Skip to content

Commit 4953ad0

Browse files
committed
disk storage
1 parent beaa93e commit 4953ad0

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed

api/v1alpha1/limitador_types.go

+43-1
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,14 @@ type LimitadorList struct {
146146
type RateLimitHeadersType string
147147

148148
// StorageType defines the valid options for storage
149-
// +kubebuilder:validation:Enum=memory;redis;redis_cached
149+
// +kubebuilder:validation:Enum=memory;redis;redis_cached;disk
150150
type StorageType string
151151

152152
const (
153153
StorageTypeInMemory StorageType = "memory"
154154
StorageTypeRedis StorageType = "redis"
155155
StorageTypeRedisCached StorageType = "redis_cached"
156+
StorageTypeDisk StorageType = "disk"
156157
)
157158

158159
// Storage contains the options for Limitador counters database or in-memory data storage
@@ -162,6 +163,9 @@ type Storage struct {
162163

163164
// +optional
164165
RedisCached *RedisCached `json:"redis-cached,omitempty"`
166+
167+
// +optional
168+
Disk *DiskSpec `json:"disk,omitempty"`
165169
}
166170

167171
func (s *Storage) Validate() bool {
@@ -238,6 +242,44 @@ type RedisCached struct {
238242
Options *RedisCachedOptions `json:"options,omitempty"`
239243
}
240244

245+
// PersistentVolumeClaimResources defines the resources configuration
246+
// of the backup data destination PersistentVolumeClaim
247+
type PersistentVolumeClaimResources struct {
248+
// Storage Resource requests to be used on the PersistentVolumeClaim.
249+
// To learn more about resource requests see:
250+
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
251+
Requests resource.Quantity `json:"requests"` // Should this be a string or a resoure.Quantity? it seems it is serialized as a string
252+
}
253+
254+
type PVCGenericSpec struct {
255+
// +optional
256+
StorageClassName *string `json:"storageClassName,omitempty"`
257+
// Resources represents the minimum resources the volume should have.
258+
// Ignored when VolumeName field is set
259+
// +optional
260+
Resources *PersistentVolumeClaimResources `json:"resources,omitempty"`
261+
// VolumeName is the binding reference to the PersistentVolume backing this claim.
262+
// +optional
263+
VolumeName *string `json:"volumeName,omitempty"`
264+
}
265+
266+
// DiskOptimizeType defines the valid options for "optimize" option of the disk persistence type
267+
// +kubebuilder:validation:Enum=throughput;disk
268+
type DiskOptimizeType string
269+
270+
const (
271+
DiskOptimizeTypeThroughput DiskOptimizeType = "throughput"
272+
DiskOptimizeTypeDisk DiskOptimizeType = "disk"
273+
)
274+
275+
type DiskSpec struct {
276+
// +optional
277+
PVC *PVCGenericSpec `json:"persistentVolumeClaim,omitempty"`
278+
279+
// +optional
280+
Optimize *DiskOptimizeType `json:"optimize,omitempty"`
281+
}
282+
241283
type Listener struct {
242284
// +optional
243285
HTTP *TransportProtocol `json:"http,omitempty"`

controllers/limitador_controller.go

+26
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ func (r *LimitadorReconciler) reconcileSpec(ctx context.Context, limitadorObj *l
110110
return ctrl.Result{}, err
111111
}
112112

113+
if err := r.reconcilePVC(ctx, limitadorObj); err != nil {
114+
return ctrl.Result{}, err
115+
}
116+
113117
if err := r.reconcileDeployment(ctx, limitadorObj); err != nil {
114118
return ctrl.Result{}, err
115119
}
@@ -232,6 +236,28 @@ func (r *LimitadorReconciler) reconcileService(ctx context.Context, limitadorObj
232236
return nil
233237
}
234238

239+
func (r *LimitadorReconciler) reconcilePVC(ctx context.Context, limitadorObj *limitadorv1alpha1.Limitador) error {
240+
logger, err := logr.FromContext(ctx)
241+
if err != nil {
242+
return err
243+
}
244+
245+
pvc := limitador.PVC(limitadorObj)
246+
// controller reference
247+
if err := r.SetOwnerReference(limitadorObj, pvc); err != nil {
248+
return err
249+
}
250+
251+
// Not reconciling updates PVCs for now.
252+
err = r.ReconcilePersistentVolumeClaim(ctx, pvc, reconcilers.CreateOnlyMutator)
253+
logger.V(1).Info("reconcile pvc", "error", err)
254+
if err != nil {
255+
return err
256+
}
257+
258+
return nil
259+
}
260+
235261
func (r *LimitadorReconciler) reconcileLimitsConfigMap(ctx context.Context, limitadorObj *limitadorv1alpha1.Limitador) error {
236262
logger, err := logr.FromContext(ctx)
237263
if err != nil {

pkg/limitador/k8s_objects.go

+50
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import (
66
appsv1 "k8s.io/api/apps/v1"
77
v1 "k8s.io/api/core/v1"
88
policyv1 "k8s.io/api/policy/v1"
9+
"k8s.io/apimachinery/pkg/api/resource"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
"k8s.io/apimachinery/pkg/util/intstr"
1112
"sigs.k8s.io/yaml"
1213

1314
limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1"
15+
"github.com/kuadrant/limitador-operator/pkg/helpers"
1416
)
1517

1618
const (
@@ -181,6 +183,10 @@ func ServiceName(limitadorObj *limitadorv1alpha1.Limitador) string {
181183
return fmt.Sprintf("limitador-%s", limitadorObj.Name)
182184
}
183185

186+
func PVCName(limitadorObj *limitadorv1alpha1.Limitador) string {
187+
return fmt.Sprintf("limitador-%s", limitadorObj.Name)
188+
}
189+
184190
func PodDisruptionBudget(limitadorObj *limitadorv1alpha1.Limitador) *policyv1.PodDisruptionBudget {
185191
return &policyv1.PodDisruptionBudget{
186192
ObjectMeta: metav1.ObjectMeta{
@@ -216,6 +222,50 @@ func Labels(limitador *limitadorv1alpha1.Limitador) map[string]string {
216222
}
217223
}
218224

225+
func PVC(limitador *limitadorv1alpha1.Limitador) *v1.PersistentVolumeClaim {
226+
pvc := &v1.PersistentVolumeClaim{
227+
TypeMeta: metav1.TypeMeta{
228+
Kind: "PersistentVolumeClaim",
229+
APIVersion: "v1",
230+
},
231+
ObjectMeta: metav1.ObjectMeta{
232+
Name: PVCName(limitador),
233+
Labels: Labels(limitador),
234+
},
235+
Spec: v1.PersistentVolumeClaimSpec{
236+
AccessModes: []v1.PersistentVolumeAccessMode{
237+
v1.PersistentVolumeAccessMode("ReadWriteOnce"),
238+
},
239+
},
240+
}
241+
242+
if limitador.Spec.Storage == nil || limitador.Spec.Storage.Disk == nil {
243+
helpers.TagObjectToDelete(pvc)
244+
return pvc
245+
}
246+
247+
if limitador.Spec.Storage.Disk.PVC != nil {
248+
pvc.Spec.StorageClassName = limitador.Spec.Storage.Disk.PVC.StorageClassName
249+
if limitador.Spec.Storage.Disk.PVC.VolumeName != nil {
250+
pvc.Spec.VolumeName = *limitador.Spec.Storage.Disk.PVC.VolumeName
251+
}
252+
253+
// Default value for resources
254+
resources := resource.MustParse("1Gi")
255+
if limitador.Spec.Storage.Disk.PVC.Resources != nil {
256+
resources = limitador.Spec.Storage.Disk.PVC.Resources.Requests
257+
}
258+
259+
pvc.Spec.Resources = v1.ResourceRequirements{
260+
Requests: v1.ResourceList{
261+
v1.ResourceStorage: resources,
262+
},
263+
}
264+
}
265+
266+
return pvc
267+
}
268+
219269
func deploymentContainerCommand(storage *limitadorv1alpha1.Storage, storageConfigSecret *v1.Secret, rateLimitHeaders *limitadorv1alpha1.RateLimitHeadersType) []string {
220270
command := []string{"limitador-server"}
221271

pkg/reconcilers/base_reconciler.go

+4
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ func (b *BaseReconciler) ReconcilePodDisruptionBudget(ctx context.Context, desir
155155
return b.ReconcileResource(ctx, &policyv1.PodDisruptionBudget{}, desired, mutatefn)
156156
}
157157

158+
func (b *BaseReconciler) ReconcilePersistentVolumeClaim(ctx context.Context, desired *corev1.PersistentVolumeClaim, mutatefn MutateFn) error {
159+
return b.ReconcileResource(ctx, &corev1.PersistentVolumeClaim{}, desired, mutatefn)
160+
}
161+
158162
func (b *BaseReconciler) GetResource(ctx context.Context, objKey types.NamespacedName, obj client.Object) error {
159163
logger, err := logr.FromContext(ctx)
160164
if err != nil {

0 commit comments

Comments
 (0)