Skip to content

Commit a4f2374

Browse files
Merge pull request #379 from miyadav/OCPBUG48481
OCPBUGS-48481: annotation validation policy
2 parents 84ac6e4 + b93ed3c commit a4f2374

9 files changed

+87
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: admissionregistration.k8s.io/v1
2+
kind: ValidatingAdmissionPolicyBinding
3+
metadata:
4+
name: azure-load-balancer-tcp-idle-timeout-validation-annotation-binding
5+
spec:
6+
policyName: azure-load-balancer-tcp-idle-timeout-annotation-validation-policy
7+
validationActions: ["Deny"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
apiVersion: admissionregistration.k8s.io/v1beta1
2+
kind: ValidatingAdmissionPolicy
3+
metadata:
4+
name: azure-load-balancer-tcp-idle-timeout-annotation-validation-policy
5+
spec:
6+
matchConstraints:
7+
resourceRules:
8+
- apiGroups: [""]
9+
apiVersions: ["v1"]
10+
operations: ["CREATE", "UPDATE"]
11+
resources: ["services"]
12+
variables:
13+
- name: hasIdleTimeout
14+
expression: has(object.metadata.annotations) && 'service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout' in object.metadata.annotations
15+
- name: idleTimeoutValue
16+
expression: object.metadata.?annotations['service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout'].orValue("")
17+
- name: hasOldIdleTimeout
18+
expression: oldObject != null && oldObject.metadata.?annotations != null && 'service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout' in oldObject.metadata.annotations
19+
- name: oldIdleTimeoutValue
20+
expression: oldObject.metadata.?annotations['service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout'].orValue("")
21+
- name: valueHasChanged
22+
expression: variables.hasIdleTimeout && (!variables.hasOldIdleTimeout || variables.oldIdleTimeoutValue != variables.idleTimeoutValue)
23+
validations:
24+
- expression: "!variables.hasIdleTimeout || !variables.valueHasChanged || variables.idleTimeoutValue.matches('^[0-9]+$')"
25+
message: "value for annotation 'service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout' must be an integer"
26+
- expression: "!variables.hasIdleTimeout || !variables.valueHasChanged || (int(variables.idleTimeoutValue) >= 4 && int(variables.idleTimeoutValue) <= 100)"
27+
message: "value for annotation 'service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout' must be no less than 4 and no more than 100"
28+

pkg/cloud/azure/azure.go

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ var (
3636
{ReferenceObject: &rbacv1.ClusterRoleBinding{}, EmbedFsPath: "assets/azure-cloud-controller-manager-clusterrolebinding.yaml"},
3737
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicy{}, EmbedFsPath: "assets/validating-admission-policy.yaml"},
3838
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicyBinding{}, EmbedFsPath: "assets/validating-admission-policy-binding.yaml"},
39+
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicyBinding{}, EmbedFsPath: "assets/validating-admission-service-annotation-policy-binding.yaml"},
40+
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicy{}, EmbedFsPath: "assets/validating-admission-service-annotation-policy.yaml"},
3941
}
4042
)
4143

pkg/cloud/azure/azure_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func TestResourcesRenderingSmoke(t *testing.T) {
8888
}
8989

9090
resources := assets.GetRenderedResources()
91-
assert.Len(t, resources, 8)
91+
assert.Len(t, resources, 10)
9292
})
9393
}
9494
}

pkg/cloud/cloud_test.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -129,27 +129,31 @@ func TestGetResources(t *testing.T) {
129129
}, {
130130
name: "GCP resources returned as expected",
131131
testPlatform: platformsMap[string(configv1.GCPPlatformType)],
132-
expectedResourceCount: 4,
132+
expectedResourceCount: 6,
133133
expectedResourcesKindName: []string{
134134
"Deployment/gcp-cloud-controller-manager",
135135
"PodDisruptionBudget/gcp-cloud-controller-manager",
136136
"ClusterRole/gcp-cloud-controller-manager",
137137
"ClusterRoleBinding/gcp-cloud-controller-manager:cloud-provider",
138+
"ValidatingAdmissionPolicyBinding/network-tier-annotation-binding",
139+
"ValidatingAdmissionPolicy/network-tier-annotation-validation-policy",
138140
},
139141
}, {
140142
name: "GCP resources returned as expected with single node cluster",
141143
testPlatform: platformsMap[string(configv1.GCPPlatformType)],
142-
expectedResourceCount: 3,
144+
expectedResourceCount: 5,
143145
singleReplica: true,
144146
expectedResourcesKindName: []string{
145147
"Deployment/gcp-cloud-controller-manager",
146148
"ClusterRole/gcp-cloud-controller-manager",
147149
"ClusterRoleBinding/gcp-cloud-controller-manager:cloud-provider",
150+
"ValidatingAdmissionPolicyBinding/network-tier-annotation-binding",
151+
"ValidatingAdmissionPolicy/network-tier-annotation-validation-policy",
148152
},
149153
}, {
150154
name: "Azure resources returned as expected",
151155
testPlatform: platformsMap[string(configv1.AzurePlatformType)],
152-
expectedResourceCount: 9,
156+
expectedResourceCount: 11,
153157
expectedResourcesKindName: []string{
154158
"Deployment/azure-cloud-controller-manager",
155159
"DaemonSet/azure-cloud-node-manager",
@@ -159,12 +163,14 @@ func TestGetResources(t *testing.T) {
159163
"ClusterRoleBinding/cloud-controller-manager:azure-cloud-controller-manager",
160164
"ValidatingAdmissionPolicy/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
161165
"ValidatingAdmissionPolicyBinding/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
166+
"ValidatingAdmissionPolicyBinding/azure-load-balancer-tcp-idle-timeout-validation-annotation-binding",
167+
"ValidatingAdmissionPolicy/azure-load-balancer-tcp-idle-timeout-annotation-validation-policy",
162168
"PodDisruptionBudget/azure-cloud-controller-manager",
163169
},
164170
}, {
165171
name: "Azure resources returned as expected with single node cluster",
166172
testPlatform: platformsMap[string(configv1.AzurePlatformType)],
167-
expectedResourceCount: 8,
173+
expectedResourceCount: 10,
168174
singleReplica: true,
169175
expectedResourcesKindName: []string{
170176
"Deployment/azure-cloud-controller-manager",
@@ -175,6 +181,8 @@ func TestGetResources(t *testing.T) {
175181
"ClusterRoleBinding/cloud-controller-manager:azure-cloud-controller-manager",
176182
"ValidatingAdmissionPolicy/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
177183
"ValidatingAdmissionPolicyBinding/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
184+
"ValidatingAdmissionPolicyBinding/azure-load-balancer-tcp-idle-timeout-validation-annotation-binding",
185+
"ValidatingAdmissionPolicy/azure-load-balancer-tcp-idle-timeout-annotation-validation-policy",
178186
},
179187
}, {
180188
name: "Azure Stack resources returned as expected",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: admissionregistration.k8s.io/v1
2+
kind: ValidatingAdmissionPolicyBinding
3+
metadata:
4+
name: network-tier-annotation-binding
5+
spec:
6+
policyName: network-tier-annotation-validation-policy
7+
validationActions: ["Deny"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
apiVersion: admissionregistration.k8s.io/v1
2+
kind: ValidatingAdmissionPolicy
3+
metadata:
4+
name: network-tier-annotation-validation-policy
5+
spec:
6+
matchConstraints:
7+
resourceRules:
8+
- apiGroups: [""]
9+
apiVersions: ["v1"]
10+
operations: ["CREATE", "UPDATE"]
11+
resources: ["services"]
12+
variables:
13+
- name: hasNetworkTier
14+
expression: has(object.metadata.annotations) && 'cloud.google.com/network-tier' in object.metadata.annotations
15+
- name: networkTierValue
16+
expression: object.metadata.?annotations['cloud.google.com/network-tier'].orValue("")
17+
- name: hasOldNetworkTier
18+
expression: oldObject != null && oldObject.metadata.?annotations != null && 'cloud.google.com/network-tier' in oldObject.metadata.annotations
19+
- name: oldNetworkTierValue
20+
expression: oldObject.metadata.?annotations['cloud.google.com/network-tier'].orValue("")
21+
- name: valueHasChanged
22+
expression: variables.hasNetworkTier && (!variables.hasOldNetworkTier || variables.oldNetworkTierValue != variables.networkTierValue)
23+
validations:
24+
- expression: |
25+
!variables.valueHasChanged || variables.networkTierValue in ['Standard', 'Premium']
26+
message: "The annotation 'cloud.google.com/network-tier', if specified, must be either 'Standard' or 'Premium'."

pkg/cloud/gcp/gcp.go

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
"github.com/asaskevich/govalidator"
8+
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
89
appsv1 "k8s.io/api/apps/v1"
910
rbacv1 "k8s.io/api/rbac/v1"
1011
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -22,6 +23,8 @@ var (
2223
{ReferenceObject: &appsv1.Deployment{}, EmbedFsPath: "assets/cloud-controller-manager.yaml"},
2324
{ReferenceObject: &rbacv1.ClusterRole{}, EmbedFsPath: "assets/gcp-cloud-controller-manager-clusterrole.yaml"},
2425
{ReferenceObject: &rbacv1.ClusterRoleBinding{}, EmbedFsPath: "assets/gcp-cloud-controller-manager-clusterrolebinding.yaml"},
26+
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicyBinding{}, EmbedFsPath: "assets/validating-admission-policy-binding.yaml"},
27+
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicy{}, EmbedFsPath: "assets/validating-admission-policy.yaml"},
2528
}
2629
)
2730

pkg/cloud/gcp/gcp_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestResourcesRenderingSmoke(t *testing.T) {
5555
}
5656

5757
resources := assets.GetRenderedResources()
58-
assert.Len(t, resources, 3)
58+
assert.Len(t, resources, 5)
5959
})
6060
}
6161
}

0 commit comments

Comments
 (0)