From e7b65abc00a02ab037fd832912168bd9b3be4691 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Wed, 22 Nov 2023 00:04:49 +0100 Subject: [PATCH 1/2] verbosity level Signed-off-by: Eguzki Astiz Lezaun --- api/v1alpha1/limitador_types.go | 8 ++ api/v1alpha1/zz_generated.deepcopy.go | 5 + ...itador-operator.clusterserviceversion.yaml | 2 +- .../limitador.kuadrant.io_limitadors.yaml | 5 + .../limitador.kuadrant.io_limitadors.yaml | 5 + controllers/limitador_controller_test.go | 126 ++++++++++++++++++ pkg/limitador/deployment_options.go | 6 + pkg/limitador/deployment_options_test.go | 23 ++++ 8 files changed, 179 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/limitador_types.go b/api/v1alpha1/limitador_types.go index 2dd158ab..b064bdfb 100644 --- a/api/v1alpha1/limitador_types.go +++ b/api/v1alpha1/limitador_types.go @@ -50,6 +50,10 @@ var ( } ) +// +kubebuilder:validation:Minimum=1 +// +kubebuilder:validation:Maximum=4 +type VerbosityLevel int + // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. @@ -87,6 +91,10 @@ type LimitadorSpec struct { // +optional ResourceRequirements *corev1.ResourceRequirements `json:"resourceRequirements,omitempty"` + + // Sets the level of verbosity + // +optional + Verbosity *VerbosityLevel `json:"verbosity,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index a23ce89b..40dcaeae 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -183,6 +183,11 @@ func (in *LimitadorSpec) DeepCopyInto(out *LimitadorSpec) { *out = new(v1.ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.Verbosity != nil { + in, out := &in.Verbosity, &out.Verbosity + *out = new(VerbosityLevel) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LimitadorSpec. diff --git a/bundle/manifests/limitador-operator.clusterserviceversion.yaml b/bundle/manifests/limitador-operator.clusterserviceversion.yaml index 779a7150..9deb70cf 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-21T15:45:03Z" + createdAt: "2023-11-21T22:28:31Z" 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 56f88a13..83a09625 100644 --- a/bundle/manifests/limitador.kuadrant.io_limitadors.yaml +++ b/bundle/manifests/limitador.kuadrant.io_limitadors.yaml @@ -1079,6 +1079,11 @@ spec: - basic - exhaustive type: string + verbosity: + description: Sets the level of verbosity + maximum: 4 + minimum: 1 + type: integer 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 edd3b573..a884140e 100644 --- a/config/crd/bases/limitador.kuadrant.io_limitadors.yaml +++ b/config/crd/bases/limitador.kuadrant.io_limitadors.yaml @@ -1080,6 +1080,11 @@ spec: - basic - exhaustive type: string + verbosity: + description: Sets the level of verbosity + maximum: 4 + minimum: 1 + type: integer version: type: string type: object diff --git a/controllers/limitador_controller_test.go b/controllers/limitador_controller_test.go index 6de4ed56..0d7de1eb 100644 --- a/controllers/limitador_controller_test.go +++ b/controllers/limitador_controller_test.go @@ -345,6 +345,132 @@ var _ = Describe("Limitador controller", func() { }) }) + Context("Creating a new Limitador object with verbosity", func() { + var limitadorObj *limitadorv1alpha1.Limitador + + BeforeEach(func() { + limitadorObj = basicLimitador(testNamespace) + limitadorObj.Spec.Verbosity = &[]limitadorv1alpha1.VerbosityLevel{3}[0] + + Expect(k8sClient.Create(context.TODO(), limitadorObj)).Should(Succeed()) + Eventually(testLimitadorIsReady(limitadorObj), time.Minute, 5*time.Second).Should(BeTrue()) + }) + + It("Should create a new deployment with verbosity level command line arg", func() { + deployment := &appsv1.Deployment{} + Eventually(func() bool { + err := k8sClient.Get(context.TODO(), + types.NamespacedName{ + Namespace: testNamespace, + Name: limitador.DeploymentName(limitadorObj), + }, deployment) + return err == nil + }, timeout, interval).Should(BeTrue()) + + Expect(deployment.Spec.Template.Spec.Containers[0].Command).To( + HaveExactElements( + "limitador-server", + "-vvv", + "--http-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceHTTPPort)), + "--rls-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceGRPCPort)), + "/home/limitador/etc/limitador-config.yaml", + "memory", + ), + ) + }) + }) + + Context("Creating a new Limitador object with too high verbosity level", func() { + var limitadorObj *limitadorv1alpha1.Limitador + + It("Should be rejected by k8s", func() { + limitadorObj = basicLimitador(testNamespace) + limitadorObj.Spec.Verbosity = &[]limitadorv1alpha1.VerbosityLevel{6}[0] + + Expect(k8sClient.Create(context.TODO(), limitadorObj)).NotTo(Succeed()) + }) + }) + + Context("Reconciling command line args for verbosity", func() { + var limitadorObj *limitadorv1alpha1.Limitador + + BeforeEach(func() { + limitadorObj = basicLimitador(testNamespace) + + Expect(k8sClient.Create(context.TODO(), limitadorObj)).Should(Succeed()) + Eventually(testLimitadorIsReady(limitadorObj), time.Minute, 5*time.Second).Should(BeTrue()) + }) + + It("Should modify the limitador deployment command line args", func() { + deployment := &appsv1.Deployment{} + Eventually(func() bool { + err := k8sClient.Get(context.TODO(), + types.NamespacedName{ + Namespace: testNamespace, + Name: limitador.DeploymentName(limitadorObj), + }, deployment) + return err == nil + }, timeout, interval).Should(BeTrue()) + + // verbosity level command line arg should be missing + Expect(deployment.Spec.Template.Spec.Containers[0].Command).To( + HaveExactElements( + "limitador-server", + "--http-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceHTTPPort)), + "--rls-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceGRPCPort)), + "/home/limitador/etc/limitador-config.yaml", + "memory", + ), + ) + + // Let's add verbosity level + updatedLimitador := limitadorv1alpha1.Limitador{} + Eventually(func() bool { + err := k8sClient.Get(context.TODO(), + types.NamespacedName{ + Namespace: testNamespace, + Name: limitadorObj.Name, + }, &updatedLimitador) + + if err != nil { + return false + } + + updatedLimitador.Spec.Verbosity = &[]limitadorv1alpha1.VerbosityLevel{3}[0] + return k8sClient.Update(context.TODO(), &updatedLimitador) == nil + }, timeout, interval).Should(BeTrue()) + + Eventually(func() bool { + newDeployment := &appsv1.Deployment{} + err := k8sClient.Get(context.TODO(), + types.NamespacedName{ + Namespace: testNamespace, + Name: limitador.DeploymentName(limitadorObj), + }, newDeployment) + + if err != nil { + return false + } + + return reflect.DeepEqual(newDeployment.Spec.Template.Spec.Containers[0].Command, + []string{ + "limitador-server", + "-vvv", + "--http-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceHTTPPort)), + "--rls-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceGRPCPort)), + "/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 284a0dc8..17add9f4 100644 --- a/pkg/limitador/deployment_options.go +++ b/pkg/limitador/deployment_options.go @@ -1,8 +1,10 @@ package limitador import ( + "fmt" "path/filepath" "strconv" + "strings" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -43,6 +45,10 @@ func DeploymentCommand(limObj *limitadorv1alpha1.Limitador, storageOptions Deplo command = append(command, "--limit-name-in-labels") } + if limObj.Spec.Verbosity != nil { + command = append(command, fmt.Sprintf("-%s", strings.Repeat("v", int(*limObj.Spec.Verbosity)))) + } + // let's set explicitly the HTTP port, // as it is being set in the readiness and liveness probe and in the service command = append(command, "--http-port", strconv.Itoa(int(limObj.HTTPPort()))) diff --git a/pkg/limitador/deployment_options_test.go b/pkg/limitador/deployment_options_test.go index 98583aa7..12649c6a 100644 --- a/pkg/limitador/deployment_options_test.go +++ b/pkg/limitador/deployment_options_test.go @@ -5,6 +5,7 @@ import ( "testing" "gotest.tools/assert" + is "gotest.tools/assert/cmp" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -84,6 +85,28 @@ func TestDeploymentCommand(t *testing.T) { "a", "b", "c", }) }) + + t.Run("when verbosity is set in the spec command line args includes -v*", func(subT *testing.T) { + tests := []struct { + Name string + VerbosityLevel limitadorv1alpha1.VerbosityLevel + ExpectedArg string + }{ + {"log level 1", 1, "-v"}, + {"log level 2", 2, "-vv"}, + {"log level 3", 3, "-vvv"}, + {"log level 4", 4, "-vvvv"}, + } + for _, tt := range tests { + subT.Run(tt.Name, func(subTest *testing.T) { + limObj := basicLimitador() + limObj.Spec.Verbosity = &tt.VerbosityLevel + command := DeploymentCommand(limObj, DeploymentStorageOptions{}) + assert.Assert(subTest, is.Contains(command, tt.ExpectedArg)) + }) + } + }) + } func TestDeploymentVolumeMounts(t *testing.T) { From 16c7b030730c51d40f4a0ee850b6658508fcd34d Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Wed, 22 Nov 2023 00:23:40 +0100 Subject: [PATCH 2/2] fix lint issues --- pkg/limitador/deployment_options_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/limitador/deployment_options_test.go b/pkg/limitador/deployment_options_test.go index 12649c6a..7b278bf2 100644 --- a/pkg/limitador/deployment_options_test.go +++ b/pkg/limitador/deployment_options_test.go @@ -100,13 +100,12 @@ func TestDeploymentCommand(t *testing.T) { for _, tt := range tests { subT.Run(tt.Name, func(subTest *testing.T) { limObj := basicLimitador() - limObj.Spec.Verbosity = &tt.VerbosityLevel + limObj.Spec.Verbosity = &[]limitadorv1alpha1.VerbosityLevel{tt.VerbosityLevel}[0] command := DeploymentCommand(limObj, DeploymentStorageOptions{}) assert.Assert(subTest, is.Contains(command, tt.ExpectedArg)) }) } }) - } func TestDeploymentVolumeMounts(t *testing.T) {