From a21723cb736d634b4dd40f9bc2b34a7965723f1f Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Mon, 19 Aug 2024 14:47:18 +0100 Subject: [PATCH] Add admission policy to deny changing an AWS LB type on an existing service --- .../validating-admission-policy-binding.yaml | 7 +++++++ .../assets/validating-admission-policy.yaml | 20 +++++++++++++++++++ pkg/cloud/aws/aws.go | 3 +++ pkg/cloud/aws/aws_test.go | 2 +- pkg/cloud/cloud_test.go | 18 +++++++++++------ 5 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 pkg/cloud/aws/assets/validating-admission-policy-binding.yaml create mode 100644 pkg/cloud/aws/assets/validating-admission-policy.yaml diff --git a/pkg/cloud/aws/assets/validating-admission-policy-binding.yaml b/pkg/cloud/aws/assets/validating-admission-policy-binding.yaml new file mode 100644 index 000000000..02fbcbb0e --- /dev/null +++ b/pkg/cloud/aws/assets/validating-admission-policy-binding.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + name: openshift-cloud-controller-manager-cloud-provider-aws +spec: + policyName: openshift-cloud-controller-manager-cloud-provider-aws + validationActions: ["Deny"] diff --git a/pkg/cloud/aws/assets/validating-admission-policy.yaml b/pkg/cloud/aws/assets/validating-admission-policy.yaml new file mode 100644 index 000000000..0247e5d4c --- /dev/null +++ b/pkg/cloud/aws/assets/validating-admission-policy.yaml @@ -0,0 +1,20 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + name: openshift-cloud-controller-manager-cloud-provider-aws +spec: + failurePolicy: Fail + matchConstraints: + resourceRules: + - apiGroups: [""] + apiVersions: ["v1"] + operations: ["UPDATE"] + resources: ["services"] + validations: + - expression: | + (has(object.metadata.annotations) && 'service.beta.kubernetes.io/aws-load-balancer-type' in object.metadata.annotations) == + (has(oldObject.metadata.annotations) && 'service.beta.kubernetes.io/aws-load-balancer-type' in oldObject.metadata.annotations) && + (has(object.metadata.annotations) && 'service.beta.kubernetes.io/aws-load-balancer-type' in object.metadata.annotations ? + object.metadata.annotations['service.beta.kubernetes.io/aws-load-balancer-type'] == oldObject.metadata.annotations['service.beta.kubernetes.io/aws-load-balancer-type'] : true) + message: "The annotation 'service.beta.kubernetes.io/aws-load-balancer-type' may not be added, removed, or have its value changed. Changing the type of an existing load balancer is not supported." + reason: Invalid diff --git a/pkg/cloud/aws/aws.go b/pkg/cloud/aws/aws.go index 329c16114..79c32b691 100644 --- a/pkg/cloud/aws/aws.go +++ b/pkg/cloud/aws/aws.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/asaskevich/govalidator" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -20,6 +21,8 @@ var ( templates = []common.TemplateSource{ {ReferenceObject: &appsv1.Deployment{}, EmbedFsPath: "assets/deployment.yaml"}, + {ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicy{}, EmbedFsPath: "assets/validating-admission-policy.yaml"}, + {ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicyBinding{}, EmbedFsPath: "assets/validating-admission-policy-binding.yaml"}, } ) diff --git a/pkg/cloud/aws/aws_test.go b/pkg/cloud/aws/aws_test.go index 447a7c5d9..36ac82ec1 100644 --- a/pkg/cloud/aws/aws_test.go +++ b/pkg/cloud/aws/aws_test.go @@ -43,7 +43,7 @@ func TestResourcesRenderingSmoke(t *testing.T) { } resources := assets.GetRenderedResources() - assert.Len(t, resources, 1) + assert.Len(t, resources, 3) }) } } diff --git a/pkg/cloud/cloud_test.go b/pkg/cloud/cloud_test.go index ddcaf9175..29befe510 100644 --- a/pkg/cloud/cloud_test.go +++ b/pkg/cloud/cloud_test.go @@ -99,17 +99,23 @@ func TestGetResources(t *testing.T) { }{{ name: "AWS resources returned as expected", testPlatform: platformsMap[string(configv1.AWSPlatformType)], - expectedResourceCount: 2, + expectedResourceCount: 4, expectedResourcesKindName: []string{ "Deployment/aws-cloud-controller-manager", + "ValidatingAdmissionPolicy/openshift-cloud-controller-manager-cloud-provider-aws", + "ValidatingAdmissionPolicyBinding/openshift-cloud-controller-manager-cloud-provider-aws", "PodDisruptionBudget/aws-cloud-controller-manager", }, }, { - name: "AWS resources returned as expected with single node cluster", - testPlatform: platformsMap[string(configv1.AWSPlatformType)], - expectedResourceCount: 1, - singleReplica: true, - expectedResourcesKindName: []string{"Deployment/aws-cloud-controller-manager"}, + name: "AWS resources returned as expected with single node cluster", + testPlatform: platformsMap[string(configv1.AWSPlatformType)], + expectedResourceCount: 3, + singleReplica: true, + expectedResourcesKindName: []string{ + "Deployment/aws-cloud-controller-manager", + "ValidatingAdmissionPolicy/openshift-cloud-controller-manager-cloud-provider-aws", + "ValidatingAdmissionPolicyBinding/openshift-cloud-controller-manager-cloud-provider-aws", + }, }, { name: "OpenStack resources returned as expected", testPlatform: platformsMap[string(configv1.OpenStackPlatformType)],