...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/pkg/webhook/management_conflict_annotation_defaulter_test.go

Documentation: github.com/GoogleCloudPlatform/k8s-config-connector/pkg/webhook

     1  // Copyright 2022 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    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