1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package webhook
16
17 import (
18 "testing"
19
20 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
21 testutil "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test"
22 testdclschemaloader "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/dclschemaloader"
23 testservicemetadataloader "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/servicemetadataloader"
24
25 "github.com/nasa9084/go-openapi"
26 corev1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
29 )
30
31 func TestDefaultManagementConflictAnnotationForDCLBasedResources(t *testing.T) {
32 tests := []struct {
33 name string
34 obj *unstructured.Unstructured
35 newObj *unstructured.Unstructured
36 ns *corev1.Namespace
37 schema *openapi.Schema
38 denied bool
39 }{
40 {
41 name: "default annotation to 'none' if not set on either namespace or resource",
42 obj: &unstructured.Unstructured{
43 Object: map[string]interface{}{
44 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
45 "kind": "Test1Bar",
46 },
47 },
48 newObj: &unstructured.Unstructured{
49 Object: map[string]interface{}{
50 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
51 "kind": "Test1Bar",
52 "metadata": map[string]interface{}{
53 "annotations": map[string]interface{}{
54 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "none",
55 },
56 },
57 },
58 },
59 ns: &corev1.Namespace{
60 ObjectMeta: metav1.ObjectMeta{
61 Name: "test-ns",
62 },
63 },
64 schema: &openapi.Schema{
65 Type: "object",
66 Properties: map[string]*openapi.Schema{
67 "labels": &openapi.Schema{
68 Type: "string",
69 },
70 },
71 Extension: map[string]interface{}{
72 "x-dcl-labels": "labels",
73 },
74 },
75 },
76 {
77 name: "default annotation from namespace",
78 obj: &unstructured.Unstructured{
79 Object: map[string]interface{}{
80 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
81 "kind": "Test1Bar",
82 },
83 },
84 newObj: &unstructured.Unstructured{
85 Object: map[string]interface{}{
86 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
87 "kind": "Test1Bar",
88 "metadata": map[string]interface{}{
89 "annotations": map[string]interface{}{
90 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "none",
91 },
92 },
93 },
94 },
95 ns: &corev1.Namespace{
96 ObjectMeta: metav1.ObjectMeta{
97 Name: "test-ns",
98 Annotations: map[string]string{
99 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "none",
100 },
101 },
102 },
103 schema: &openapi.Schema{
104 Type: "object",
105 Properties: map[string]*openapi.Schema{
106 "labels": &openapi.Schema{
107 Type: "string",
108 },
109 },
110 Extension: map[string]interface{}{
111 "x-dcl-labels": "labels",
112 },
113 },
114 },
115 {
116 name: "no defaulting needed since resource specifies annotation",
117 obj: &unstructured.Unstructured{
118 Object: map[string]interface{}{
119 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
120 "kind": "Test1Bar",
121 "metadata": map[string]interface{}{
122 "annotations": map[string]interface{}{
123 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "resource",
124 },
125 },
126 },
127 },
128 newObj: &unstructured.Unstructured{
129 Object: map[string]interface{}{
130 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
131 "kind": "Test1Bar",
132 "metadata": map[string]interface{}{
133 "annotations": map[string]interface{}{
134 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "resource",
135 },
136 },
137 },
138 },
139 ns: &corev1.Namespace{
140 ObjectMeta: metav1.ObjectMeta{
141 Name: "test-ns",
142 Annotations: map[string]string{
143 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "none",
144 },
145 },
146 },
147 schema: &openapi.Schema{
148 Type: "object",
149 Properties: map[string]*openapi.Schema{
150 "labels": &openapi.Schema{
151 Type: "string",
152 },
153 },
154 Extension: map[string]interface{}{
155 "x-dcl-labels": "labels",
156 },
157 },
158 },
159 {
160 name: "default annotation to 'none' if resource doesn't support management conflict prevention",
161 obj: &unstructured.Unstructured{
162 Object: map[string]interface{}{
163 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
164 "kind": "Test1Bar",
165 },
166 },
167 newObj: &unstructured.Unstructured{
168 Object: map[string]interface{}{
169 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
170 "kind": "Test1Bar",
171 "metadata": map[string]interface{}{
172 "annotations": map[string]interface{}{
173 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "none",
174 },
175 },
176 },
177 },
178 ns: &corev1.Namespace{
179 ObjectMeta: metav1.ObjectMeta{
180 Name: "test-ns",
181 },
182 },
183 schema: &openapi.Schema{
184 Type: "object",
185 },
186 },
187 {
188 name: "default annotation to 'none' if resource doesn't support management conflict prevention even if namespace has annotation",
189 obj: &unstructured.Unstructured{
190 Object: map[string]interface{}{
191 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
192 "kind": "Test1Bar",
193 },
194 },
195 newObj: &unstructured.Unstructured{
196 Object: map[string]interface{}{
197 "apiVersion": "test1.cnrm.cloud.google.com/v1alpha1",
198 "kind": "Test1Bar",
199 "metadata": map[string]interface{}{
200 "annotations": map[string]interface{}{
201 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "none",
202 },
203 },
204 },
205 },
206 ns: &corev1.Namespace{
207 ObjectMeta: metav1.ObjectMeta{
208 Name: "test-ns",
209 Annotations: map[string]string{
210 k8s.ManagementConflictPreventionPolicyFullyQualifiedAnnotation: "resource",
211 },
212 },
213 },
214 schema: &openapi.Schema{
215 Type: "object",
216 },
217 },
218 }
219 smLoader := testservicemetadataloader.NewForUnitTest()
220 for _, tc := range tests {
221 tc := tc
222 t.Run(tc.name, func(t *testing.T) {
223 t.Parallel()
224 dclSchemaMap := make(map[string]*openapi.Schema)
225 dclSchemaMap["test1_beta_bar"] = tc.schema
226 dclSchemaLoader := testdclschemaloader.New(dclSchemaMap)
227 response := defaultManagementConflictAnnotationForDCLBasedResources(tc.obj, tc.ns, dclSchemaLoader, smLoader)
228 expectedResponse := constructPatchResponse(tc.obj, tc.newObj)
229 if !testutil.Equals(t, response, expectedResponse) {
230 t.Fatalf("expect to get response %v, but got %v", expectedResponse, response)
231 }
232 })
233 }
234 }
235
View as plain text