From d1b5c1020303aaff2e148a73513d46d7f350ea0f Mon Sep 17 00:00:00 2001 From: mgianluc Date: Thu, 21 Dec 2023 09:18:38 +0100 Subject: [PATCH] Remove OpenAPI validations --- Makefile | 2 +- config/default/manager_image_patch.yaml | 2 +- controllers/addoncompliance_controller.go | 56 ------ .../addoncompliance_controller_test.go | 36 +--- .../addoncompliance_transformations_test.go | 8 +- controllers/export_test.go | 1 - go.mod | 2 +- go.sum | 4 +- manifest/manifest.yaml | 2 +- test/fv/configmap_test.go | 176 +++++++----------- 10 files changed, 80 insertions(+), 209 deletions(-) diff --git a/Makefile b/Makefile index c8eb897..cf4a9b5 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ ARCH ?= amd64 OS ?= $(shell uname -s | tr A-Z a-z) K8S_LATEST_VER ?= $(shell curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) export CONTROLLER_IMG ?= $(REGISTRY)/$(IMAGE_NAME) -TAG ?= main +TAG ?= dev .PHONY: all all: build diff --git a/config/default/manager_image_patch.yaml b/config/default/manager_image_patch.yaml index c4ff0ce..70dc9c8 100644 --- a/config/default/manager_image_patch.yaml +++ b/config/default/manager_image_patch.yaml @@ -8,5 +8,5 @@ spec: spec: containers: # Change the value of image field below to your controller image URL - - image: projectsveltos/addon-compliance-controller-amd64:main + - image: projectsveltos/addon-compliance-controller-amd64:dev name: manager diff --git a/controllers/addoncompliance_controller.go b/controllers/addoncompliance_controller.go index 3049b4e..8bdbc75 100644 --- a/controllers/addoncompliance_controller.go +++ b/controllers/addoncompliance_controller.go @@ -26,7 +26,6 @@ import ( sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" - "github.com/getkin/kin-openapi/openapi3" "github.com/go-logr/logr" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" @@ -212,14 +211,6 @@ func (r *AddonComplianceReconciler) reconcileNormal( r.updateMaps(addonConstraintScope, logger) var validations map[string][]byte - validations, err = r.collectOpenapiValidations(ctx, addonConstraintScope, logger) - if err != nil { - failureMsg := err.Error() - addonConstraintScope.SetFailureMessage(&failureMsg) - return reconcile.Result{Requeue: true, RequeueAfter: normalRequeueAfter}, nil - } - addonConstraintScope.AddonCompliance.Status.OpenapiValidations = validations - validations, err = r.collectLuaValidations(ctx, addonConstraintScope, logger) if err != nil { failureMsg := err.Error() @@ -495,18 +486,6 @@ func (r *AddonComplianceReconciler) getMatchingClusters(ctx context.Context, func (r *AddonComplianceReconciler) getCurrentReferences(addonConstraintScope *scope.AddonComplianceScope) *libsveltosset.Set { currentReferences := &libsveltosset.Set{} - for i := range addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs { - referencedNamespace := addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs[i].Namespace - referencedName := addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs[i].Name - - apiVersion := getReferenceAPIVersion(addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs[i].Kind) - currentReferences.Insert(&corev1.ObjectReference{ - APIVersion: apiVersion, - Kind: addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs[i].Kind, - Namespace: referencedNamespace, - Name: referencedName, - }) - } for i := range addonConstraintScope.AddonCompliance.Spec.LuaValidationRefs { referencedNamespace := addonConstraintScope.AddonCompliance.Spec.LuaValidationRefs[i].Namespace referencedName := addonConstraintScope.AddonCompliance.Spec.LuaValidationRefs[i].Name @@ -523,41 +502,6 @@ func (r *AddonComplianceReconciler) getCurrentReferences(addonConstraintScope *s return currentReferences } -func (r *AddonComplianceReconciler) collectOpenapiValidations(ctx context.Context, addonConstraintScope *scope.AddonComplianceScope, - logger logr.Logger) (map[string][]byte, error) { - - logger.V(logs.LogDebug).Info("collect openapi validations") - validations := make(map[string][]byte) - for i := range addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs { - ref := &addonConstraintScope.AddonCompliance.Spec.OpenAPIValidationRefs[i] - currentValidation, err := r.collectValidations(ctx, ref.Kind, ref.Namespace, ref.Name, ref.Path, logger) - if err != nil { - return nil, err - } - for k := range currentValidation { - loader := &openapi3.Loader{Context: ctx, IsExternalRefsAllowed: true} - - // Load the OpenAPI specification from the content - doc, err := loader.LoadFromData([]byte(currentValidation[k])) - if err != nil { - logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to loadFromData: %v", err)) - return nil, err - } - - err = doc.Validate(ctx) - if err != nil { - logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to validate: %v", err)) - return nil, err - } - - validations[k] = currentValidation[k] - } - - } - - return validations, nil -} - func (r *AddonComplianceReconciler) collectLuaValidations(ctx context.Context, addonConstraintScope *scope.AddonComplianceScope, logger logr.Logger) (map[string][]byte, error) { diff --git a/controllers/addoncompliance_controller_test.go b/controllers/addoncompliance_controller_test.go index 4a492ea..182082b 100644 --- a/controllers/addoncompliance_controller_test.go +++ b/controllers/addoncompliance_controller_test.go @@ -167,25 +167,22 @@ var _ = Describe("AddonCompliance Controller", func() { } }) - It("getCurrentReferences collects all OpenAPIValidationRef referenced objects", func() { - addonConstraint.Spec.OpenAPIValidationRefs = []libsveltosv1alpha1.OpenAPIValidationRef{ + It("getCurrentReferences collects all LuaValidationRefs referenced objects", func() { + addonConstraint.Spec.LuaValidationRefs = []libsveltosv1alpha1.LuaValidationRef{ { Namespace: namespace, Name: randomString(), - Kind: string(libsveltosv1alpha1.ConfigMapReferencedResourceKind), + Kind: string(libsveltosv1alpha1.SecretReferencedResourceKind), }, { Namespace: namespace, Name: randomString(), - Kind: sourcev1.GitRepositoryKind, + Kind: string(libsveltosv1alpha1.ConfigMapReferencedResourceKind), }, - } - - addonConstraint.Spec.LuaValidationRefs = []libsveltosv1alpha1.LuaValidationRef{ { Namespace: namespace, Name: randomString(), - Kind: string(libsveltosv1alpha1.SecretReferencedResourceKind), + Kind: sourcev1.GitRepositoryKind, }, } @@ -279,7 +276,7 @@ var _ = Describe("AddonCompliance Controller", func() { APIVersion: libsveltosv1alpha1.GroupVersion.String(), } - addonConstraint.Spec.OpenAPIValidationRefs = []libsveltosv1alpha1.OpenAPIValidationRef{ + addonConstraint.Spec.LuaValidationRefs = []libsveltosv1alpha1.LuaValidationRef{ { Namespace: configMap.Namespace, Name: configMap.Name, @@ -471,27 +468,6 @@ var _ = Describe("AddonCompliance Controller", func() { Expect(len(u)).To(Equal(2)) }) - It("collectOpenapiValidations updates AddonCompliance status", func() { - configMap := createConfigMapWithPolicy(randomString(), randomString(), []string{nameSpec, deplReplicaSpec}...) - - addonConstraint.Spec.OpenAPIValidationRefs = []libsveltosv1alpha1.OpenAPIValidationRef{ - {Namespace: configMap.Namespace, Name: configMap.Name, - Kind: string(libsveltosv1alpha1.ConfigMapReferencedResourceKind)}, - } - - initObjects := []client.Object{configMap, addonConstraint} - - c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjects...).Build() - addonConstraintScope := getAddonComplianceScope(c, klogr.New(), addonConstraint) - reconciler := getAddonComplianceReconciler(c) - - result, err := controllers.CollectOpenapiValidations(reconciler, context.TODO(), - addonConstraintScope, klogr.New()) - Expect(err).To(BeNil()) - Expect(result).ToNot(BeNil()) - Expect(len(result)).To(Equal(2)) - }) - It("collectLuaValidations updates AddonCompliance status", func() { configMap := createConfigMapWithPolicy(randomString(), randomString(), []string{deploymentReplicaCheck}...) diff --git a/controllers/addoncompliance_transformations_test.go b/controllers/addoncompliance_transformations_test.go index 7e98126..1508ca3 100644 --- a/controllers/addoncompliance_transformations_test.go +++ b/controllers/addoncompliance_transformations_test.go @@ -52,7 +52,7 @@ var _ = Describe("AddonComplianceTransformation map functions", func() { Namespace: randomString(), }, Spec: libsveltosv1alpha1.AddonComplianceSpec{ - OpenAPIValidationRefs: []libsveltosv1alpha1.OpenAPIValidationRef{ + LuaValidationRefs: []libsveltosv1alpha1.LuaValidationRef{ { Namespace: configMap.Namespace, Name: configMap.Name, @@ -68,7 +68,7 @@ var _ = Describe("AddonComplianceTransformation map functions", func() { Namespace: randomString(), }, Spec: libsveltosv1alpha1.AddonComplianceSpec{ - OpenAPIValidationRefs: []libsveltosv1alpha1.OpenAPIValidationRef{ + LuaValidationRefs: []libsveltosv1alpha1.LuaValidationRef{ { Namespace: randomString(), Name: configMap.Name, @@ -131,7 +131,7 @@ var _ = Describe("AddonComplianceTransformation map functions", func() { Namespace: randomString(), }, Spec: libsveltosv1alpha1.AddonComplianceSpec{ - OpenAPIValidationRefs: []libsveltosv1alpha1.OpenAPIValidationRef{ + LuaValidationRefs: []libsveltosv1alpha1.LuaValidationRef{ { Namespace: gitRepo.Namespace, Name: gitRepo.Name, @@ -147,7 +147,7 @@ var _ = Describe("AddonComplianceTransformation map functions", func() { Namespace: randomString(), }, Spec: libsveltosv1alpha1.AddonComplianceSpec{ - OpenAPIValidationRefs: []libsveltosv1alpha1.OpenAPIValidationRef{ + LuaValidationRefs: []libsveltosv1alpha1.LuaValidationRef{ { Namespace: gitRepo.Namespace, Name: randomString(), diff --git a/controllers/export_test.go b/controllers/export_test.go index 3b252a4..cd2012d 100644 --- a/controllers/export_test.go +++ b/controllers/export_test.go @@ -31,7 +31,6 @@ var ( CleanMaps = (*AddonComplianceReconciler).cleanMaps CollectContentOfConfigMap = (*AddonComplianceReconciler).collectContentOfConfigMap CollectContentOfSecret = (*AddonComplianceReconciler).collectContentOfSecret - CollectOpenapiValidations = (*AddonComplianceReconciler).collectOpenapiValidations CollectLuaValidations = (*AddonComplianceReconciler).collectLuaValidations ) diff --git a/go.mod b/go.mod index f119186..3c88319 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/onsi/ginkgo/v2 v2.13.1 github.com/onsi/gomega v1.30.0 github.com/pkg/errors v0.9.1 - github.com/projectsveltos/libsveltos v0.20.1-0.20231129081648-ef5be475b0c0 + github.com/projectsveltos/libsveltos v0.20.1-0.20231221080505-f3a4eea4967b github.com/spf13/pflag v1.0.5 golang.org/x/text v0.14.0 k8s.io/api v0.28.4 diff --git a/go.sum b/go.sum index fb8261d..32816ad 100644 --- a/go.sum +++ b/go.sum @@ -141,8 +141,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/projectsveltos/libsveltos v0.20.1-0.20231129081648-ef5be475b0c0 h1:X2sl3kxINpYeOrQDkfDR2f772KH23iVf+17IFmghn9c= -github.com/projectsveltos/libsveltos v0.20.1-0.20231129081648-ef5be475b0c0/go.mod h1:lDfsnHGVIvb9Xs30gevyGkCEJXwo5B22HUo0Ya/+gHA= +github.com/projectsveltos/libsveltos v0.20.1-0.20231221080505-f3a4eea4967b h1:JnzdkwqFg+M0UC2GYDQjMdaBEnpCP2egymHxxwyu0hA= +github.com/projectsveltos/libsveltos v0.20.1-0.20231221080505-f3a4eea4967b/go.mod h1:lDfsnHGVIvb9Xs30gevyGkCEJXwo5B22HUo0Ya/+gHA= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= diff --git a/manifest/manifest.yaml b/manifest/manifest.yaml index e9e7371..9e3d3ba 100644 --- a/manifest/manifest.yaml +++ b/manifest/manifest.yaml @@ -269,7 +269,7 @@ spec: - --v=5 command: - /manager - image: projectsveltos/addon-compliance-controller-amd64:main + image: projectsveltos/addon-compliance-controller-amd64:dev livenessProbe: httpGet: path: /healthz diff --git a/test/fv/configmap_test.go b/test/fv/configmap_test.go index 58c5d25..08c69ee 100644 --- a/test/fv/configmap_test.go +++ b/test/fv/configmap_test.go @@ -32,111 +32,63 @@ import ( ) var ( - appLabel = `openapi: 3.0.0 -info: - title: Kubernetes Deployment Label Validation - version: 1.0.0 - -components: - schemas: - Deployment: - type: object - properties: - metadata: - type: object - properties: - labels: - type: object - additionalProperties: - type: string - required: - - metadata - DeploymentWithAppLabel: - allOf: - - $ref: '#/components/schemas/Deployment' - - properties: - metadata: - properties: - labels: - type: object - additionalProperties: - type: string - required: - - app - required: - - labels - required: - - metadata - -paths: - /apis/apps/v1/namespaces/{namespace}/deployments/{deployment}: - post: - parameters: - - in: path - name: namespace - required: true - schema: - type: string - minimum: 1 - description: The namespace of the resource - - in: path - name: deployment - required: true - schema: - type: string - minimum: 1 - description: The name of the resource - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/DeploymentWithAppLabel' - responses: - '200': - description: Valid Deployment with "app" label provided - '400': - description: Invalid Deployment, missing or incorrect "app" label + appLabel = `function evaluate() + local hs = {} + hs.valid = true + hs.message = "" + + local deployments = {} + local pattern = "^prod" + + -- Separate deployments and services from the resources + for _, resource in ipairs(resources) do + if resource.kind == "Deployment" then + table.insert(deployments, resource) + end + end + + -- Check for each deployment if there is a 'app' label + for _, deployment in ipairs(deployments) do + if deployment.metadata.labels == nil then + hs.valid = false + else if not deployment.metadata.labels['app'] then + hs.valid = false + end + end + + return hs +end` + + deploymentReplicaCheck = ` +function evaluate() + local hs = {} + hs.valid = true + hs.message = "" + + local deployments = {} + local pattern = "^prod" + + -- Separate deployments and services from the resources + for _, resource in ipairs(resources) do + if resource.kind == "Deployment" then + table.insert(deployments, resource) + end + end + + -- Check for each deployment if there is a matching service + for _, deployment in ipairs(deployments) do + local deploymentInfo = deployment.metadata.namespace .. "/" .. deployment.metadata.name + + if not string.match(deployment.metadata.name, pattern) then + hs.message = "No matching service found for deployment: " .. deploymentInfo + hs.valid = false + break + end + end + + return hs +end ` - - deplNameSpecificNamespace = `openapi: 3.0.0 -info: - title: Kubernetes Replica Validation - version: 1.0.0 - -paths: - /apis/apps/v1/namespaces/production/deployments/{deployment}: - post: - parameters: - - in: path - name: deployment - required: true - schema: - type: string - minimum: 1 - description: The name of the resource - summary: Create/Update a new deployment - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Deployment' - responses: - '200': - description: OK - -components: - schemas: - Deployment: - type: object - properties: - metadata: - type: object - properties: - name: - type: string - maxLength: 10` ) var _ = Describe("AddonCompliance with ConfigMap", Serial, func() { @@ -144,8 +96,8 @@ var _ = Describe("AddonCompliance with ConfigMap", Serial, func() { namePrefix = "cm-" ) - It("Process a ConfigMap with Openapi policies", Label("FV"), func() { - configMap := createConfigMapWithPolicy(randomString(), randomString(), []string{appLabel, deplNameSpecificNamespace}...) + It("Process a ConfigMap with Lua policies", Label("FV"), func() { + configMap := createConfigMapWithPolicy(randomString(), randomString(), []string{appLabel, deploymentReplicaCheck}...) verifyYttSourceWithConfigMap(namePrefix, configMap, 2) }) }) @@ -164,7 +116,7 @@ func verifyYttSourceWithConfigMap(namePrefix string, configMap *corev1.ConfigMap Byf("Creating a AddonCompliance referencing this ConfigMap") addonConstraint := getAddonCompliance(namePrefix, map[string]string{key: value}) - addonConstraint.Spec.OpenAPIValidationRefs = []libsveltosv1alpha1.OpenAPIValidationRef{ + addonConstraint.Spec.LuaValidationRefs = []libsveltosv1alpha1.LuaValidationRef{ { Namespace: configMap.Namespace, Name: configMap.Name, @@ -182,18 +134,18 @@ func verifyYttSourceWithConfigMap(namePrefix string, configMap *corev1.ConfigMap if err != nil { return false } - if currentAddonCompliance.Status.OpenapiValidations == nil { + if currentAddonCompliance.Status.LuaValidations == nil { return false } return true }, timeout, pollingInterval).Should(BeTrue()) - Byf("Verifying AddonCompliance %s Status.OpenapiValidations", addonConstraint.Name) + Byf("Verifying AddonCompliance %s Status.LuaValidations", addonConstraint.Name) currentAddonCompliance := &libsveltosv1alpha1.AddonCompliance{} Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: addonConstraint.Namespace, Name: addonConstraint.Name}, currentAddonCompliance)).To(Succeed()) - Expect(len(currentAddonCompliance.Status.OpenapiValidations)).To(Equal(expectedResources)) + Expect(len(currentAddonCompliance.Status.LuaValidations)).To(Equal(expectedResources)) Byf("Verifying AddonCompliance %s Status.MatchingClusterRefs", addonConstraint.Name) Expect(len(currentAddonCompliance.Status.MatchingClusterRefs)).To(Equal(1)) @@ -215,10 +167,10 @@ func verifyYttSourceWithConfigMap(namePrefix string, configMap *corev1.ConfigMap if err != nil { return false } - if currentAddonCompliance.Status.OpenapiValidations == nil { + if currentAddonCompliance.Status.LuaValidations == nil { return false } - return len(currentAddonCompliance.Status.OpenapiValidations) == 1 + return len(currentAddonCompliance.Status.LuaValidations) == 1 }, timeout, pollingInterval).Should(BeTrue()) Byf("Deleting AddonCompliance %s", addonConstraint.Name)