diff --git a/api/v1alpha1/limitador_types.go b/api/v1alpha1/limitador_types.go index f7312b42..c0309e46 100644 --- a/api/v1alpha1/limitador_types.go +++ b/api/v1alpha1/limitador_types.go @@ -76,6 +76,9 @@ type LimitadorSpec struct { // +optional RateLimitHeaders *RateLimitHeadersType `json:"rateLimitHeaders,omitempty"` + // +optional + Telemetry *Telemetry `json:"telemetry,omitempty"` + // +optional Limits []RateLimit `json:"limits,omitempty"` @@ -149,6 +152,10 @@ type LimitadorList struct { // +kubebuilder:validation:Enum=NONE;DRAFT_VERSION_03 type RateLimitHeadersType string +// Telemetry defines the level of metrics Limitador will expose to the user +// +kubebuilder:validation:Enum=basic;exhaustive +type Telemetry string + // Storage contains the options for Limitador counters database or in-memory data storage type Storage struct { // +optional diff --git a/bundle/manifests/limitador-operator.clusterserviceversion.yaml b/bundle/manifests/limitador-operator.clusterserviceversion.yaml index c75cbc3f..d463772e 100644 --- a/bundle/manifests/limitador-operator.clusterserviceversion.yaml +++ b/bundle/manifests/limitador-operator.clusterserviceversion.yaml @@ -37,7 +37,7 @@ metadata: capabilities: Basic Install categories: Integration & Delivery containerImage: quay.io/kuadrant/limitador-operator:latest - createdAt: "2023-11-08T14:01:55Z" + createdAt: "2023-11-08T14:12:13Z" operators.operatorframework.io/builder: operator-sdk-v1.28.1 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/Kuadrant/limitador-operator diff --git a/bundle/manifests/limitador.kuadrant.io_limitadors.yaml b/bundle/manifests/limitador.kuadrant.io_limitadors.yaml index 0697a8f4..367636ef 100644 --- a/bundle/manifests/limitador.kuadrant.io_limitadors.yaml +++ b/bundle/manifests/limitador.kuadrant.io_limitadors.yaml @@ -1178,6 +1178,13 @@ spec: type: object type: object type: object + telemetry: + description: Telemetry defines the level of metrics Limitador will + expose to the user + enum: + - basic + - exhaustive + type: string version: type: string type: object diff --git a/config/crd/bases/limitador.kuadrant.io_limitadors.yaml b/config/crd/bases/limitador.kuadrant.io_limitadors.yaml index 6c102ffb..f84c1ade 100644 --- a/config/crd/bases/limitador.kuadrant.io_limitadors.yaml +++ b/config/crd/bases/limitador.kuadrant.io_limitadors.yaml @@ -1179,6 +1179,13 @@ spec: type: object type: object type: object + telemetry: + description: Telemetry defines the level of metrics Limitador will + expose to the user + enum: + - basic + - exhaustive + type: string version: type: string type: object diff --git a/controllers/limitador_controller_test.go b/controllers/limitador_controller_test.go index 4d731ffe..7a7d3572 100644 --- a/controllers/limitador_controller_test.go +++ b/controllers/limitador_controller_test.go @@ -567,7 +567,7 @@ var _ = Describe("Limitador controller", func() { }) }) - Context("Reconciling command line args", func() { + Context("Reconciling command line args for rate limit headers", func() { var limitadorObj *limitadorv1alpha1.Limitador BeforeEach(func() { @@ -629,6 +629,68 @@ var _ = Describe("Limitador controller", func() { }) }) + Context("Reconciling command line args for telemetry", func() { + var limitadorObj *limitadorv1alpha1.Limitador + + BeforeEach(func() { + limitadorObj = newLimitador() + + Expect(k8sClient.Create(context.TODO(), limitadorObj)).Should(Succeed()) + }) + + AfterEach(func() { + err := k8sClient.Delete(context.TODO(), limitadorObj, deletePropagationPolicy) + Expect(err == nil || errors.IsNotFound(err)) + }) + + It("Should modify the limitador deployment command line args", func() { + updatedLimitador := limitadorv1alpha1.Limitador{} + Eventually(func() bool { + err := k8sClient.Get( + context.TODO(), + types.NamespacedName{ + Namespace: LimitadorNamespace, + Name: limitadorObj.Name, + }, + &updatedLimitador) + + if err != nil { + return false + } + + if updatedLimitador.Spec.Telemetry != nil { + return false + } + telemetry := limitadorv1alpha1.Telemetry("exhaustive") + updatedLimitador.Spec.Telemetry = &telemetry + return k8sClient.Update(context.TODO(), &updatedLimitador) == nil + }, timeout, interval).Should(BeTrue()) + + Eventually(func() bool { + updatedLimitadorDeployment := appsv1.Deployment{} + err := k8sClient.Get( + context.TODO(), + types.NamespacedName{ + Namespace: LimitadorNamespace, + Name: limitadorObj.Name, + }, + &updatedLimitadorDeployment) + + if err != nil { + return false + } + + return reflect.DeepEqual(updatedLimitadorDeployment.Spec.Template.Spec.Containers[0].Command, + []string{ + "limitador-server", + "--limit-name-in-labels", + "/home/limitador/etc/limitador-config.yaml", + "memory", + }) + }, timeout, interval).Should(BeTrue()) + }) + }) + Context("Modifying limitador deployment objects", func() { var limitadorObj *limitadorv1alpha1.Limitador diff --git a/pkg/limitador/deployment_options.go b/pkg/limitador/deployment_options.go index a41034f3..38956f58 100644 --- a/pkg/limitador/deployment_options.go +++ b/pkg/limitador/deployment_options.go @@ -37,6 +37,10 @@ func DeploymentCommand(limObj *limitadorv1alpha1.Limitador, storageOptions Deplo command = append(command, "--rate-limit-headers", string(*limObj.Spec.RateLimitHeaders)) } + if limObj.Spec.Telemetry != nil && *limObj.Spec.Telemetry == "exhaustive" { + command = append(command, "--limit-name-in-labels") + } + command = append(command, filepath.Join(LimitadorCMMountPath, LimitadorConfigFileName)) command = append(command, storageOptions.Command...)