...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/manifest/repo_test.go

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

     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 manifest_test
    16  
    17  import (
    18  	"context"
    19  	"path"
    20  	"reflect"
    21  	"strings"
    22  	"testing"
    23  
    24  	corev1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/apis/core/v1beta1"
    25  	"github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/k8s"
    26  	"github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/manifest"
    27  	testpaths "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/test/util/paths"
    28  
    29  	"github.com/google/go-cmp/cmp"
    30  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/loaders"
    32  )
    33  
    34  var clusterModeWIManifest = `# Copyright 2022 Google LLC
    35  #
    36  # Licensed under the Apache License, Version 2.0 (the "License");
    37  # you may not use this file except in compliance with the License.
    38  # You may obtain a copy of the License at
    39  #
    40  #      http://www.apache.org/licenses/LICENSE-2.0
    41  #
    42  # Unless required by applicable law or agreed to in writing, software
    43  # distributed under the License is distributed on an "AS IS" BASIS,
    44  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    45  # See the License for the specific language governing permissions and
    46  # limitations under the License.
    47  
    48  apiVersion: apiextensions.k8s.io/v1
    49  kind: CustomResourceDefinition
    50  metadata:
    51    name: foos.test.cnrm.cloud.google.com
    52    labels:
    53      cnrm.cloud.google.com/system: "true"
    54      cnrm.cloud.google.com/managed-by-kcc: "true"
    55  spec:
    56    scope: Namespaced
    57    group: test.cnrm.cloud.google.com
    58    names:
    59      kind: foo
    60      plural: foos
    61    versions:
    62    - name: v1alpha1
    63      schema:
    64        openAPIV3Schema:
    65          type: object
    66      served: true
    67      storage: true
    68  ---
    69  apiVersion: apiextensions.k8s.io/v1
    70  kind: CustomResourceDefinition
    71  metadata:
    72    name: bars.test.cnrm.cloud.google.com
    73    labels:
    74      cnrm.cloud.google.com/system: "true"
    75      cnrm.cloud.google.com/managed-by-kcc: "true"
    76  spec:
    77    scope: Namespaced
    78    group: test.cnrm.cloud.google.com
    79    names:
    80      kind: bar
    81      plural: bars
    82    versions:
    83    - name: v1alpha1
    84      schema:
    85        openAPIV3Schema:
    86          type: object
    87      served: true
    88      storage: true
    89  ---
    90  # Copyright 2022 Google LLC
    91  #
    92  # Licensed under the Apache License, Version 2.0 (the "License");
    93  # you may not use this file except in compliance with the License.
    94  # You may obtain a copy of the License at
    95  #
    96  #      http://www.apache.org/licenses/LICENSE-2.0
    97  #
    98  # Unless required by applicable law or agreed to in writing, software
    99  # distributed under the License is distributed on an "AS IS" BASIS,
   100  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   101  # See the License for the specific language governing permissions and
   102  # limitations under the License.
   103  
   104  apiVersion: v1
   105  kind: Namespace
   106  metadata:
   107    name: cnrm-system
   108  ---
   109  apiVersion: v1
   110  kind: ServiceAccount
   111  metadata:
   112    annotations:
   113      iam.gke.io/gcp-service-account: cnrm-system@${PROJECT_ID?}.iam.gserviceaccount.com
   114    name: cnrm-controller-manager
   115    namespace: cnrm-system
   116  ---
   117  apiVersion: v1
   118  kind: Service
   119  metadata:
   120    name: cnrm-manager
   121    namespace: cnrm-system
   122  spec:
   123    ports:
   124    - name: controller-manager
   125      port: 443
   126    - name: metrics
   127      port: 8888
   128    selector:
   129      cnrm.cloud.google.com/component: cnrm-controller-manager
   130      cnrm.cloud.google.com/system: "true"
   131  ---
   132  apiVersion: apps/v1
   133  kind: StatefulSet
   134  metadata:
   135    labels:
   136      cnrm.cloud.google.com/component: cnrm-controller-manager
   137      cnrm.cloud.google.com/system: "true"
   138    name: cnrm-controller-manager
   139    namespace: cnrm-system
   140  spec:
   141    selector:
   142      matchLabels:
   143        cnrm.cloud.google.com/component: cnrm-controller-manager
   144        cnrm.cloud.google.com/system: "true"
   145    serviceName: cnrm-manager
   146    template:
   147      metadata:
   148        labels:
   149          cnrm.cloud.google.com/component: cnrm-controller-manager
   150          cnrm.cloud.google.com/system: "true"
   151  `
   152  
   153  var clusterModeGcpManifest = `# Copyright 2022 Google LLC
   154  #
   155  # Licensed under the Apache License, Version 2.0 (the "License");
   156  # you may not use this file except in compliance with the License.
   157  # You may obtain a copy of the License at
   158  #
   159  #      http://www.apache.org/licenses/LICENSE-2.0
   160  #
   161  # Unless required by applicable law or agreed to in writing, software
   162  # distributed under the License is distributed on an "AS IS" BASIS,
   163  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   164  # See the License for the specific language governing permissions and
   165  # limitations under the License.
   166  
   167  apiVersion: apiextensions.k8s.io/v1
   168  kind: CustomResourceDefinition
   169  metadata:
   170    name: foos.test.cnrm.cloud.google.com
   171    labels:
   172      cnrm.cloud.google.com/system: "true"
   173      cnrm.cloud.google.com/managed-by-kcc: "true"
   174  spec:
   175    scope: Namespaced
   176    group: test.cnrm.cloud.google.com
   177    names:
   178      kind: foo
   179      plural: foos
   180    versions:
   181    - name: v1alpha1
   182      schema:
   183        openAPIV3Schema:
   184          type: object
   185      served: true
   186      storage: true
   187  ---
   188  apiVersion: apiextensions.k8s.io/v1
   189  kind: CustomResourceDefinition
   190  metadata:
   191    name: bars.test.cnrm.cloud.google.com
   192    labels:
   193      cnrm.cloud.google.com/system: "true"
   194      cnrm.cloud.google.com/managed-by-kcc: "true"
   195  spec:
   196    scope: Namespaced
   197    group: test.cnrm.cloud.google.com
   198    names:
   199      kind: bar
   200      plural: bars
   201    versions:
   202    - name: v1alpha1
   203      schema:
   204        openAPIV3Schema:
   205          type: object
   206      served: true
   207      storage: true
   208  ---
   209  # Copyright 2022 Google LLC
   210  #
   211  # Licensed under the Apache License, Version 2.0 (the "License");
   212  # you may not use this file except in compliance with the License.
   213  # You may obtain a copy of the License at
   214  #
   215  #      http://www.apache.org/licenses/LICENSE-2.0
   216  #
   217  # Unless required by applicable law or agreed to in writing, software
   218  # distributed under the License is distributed on an "AS IS" BASIS,
   219  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   220  # See the License for the specific language governing permissions and
   221  # limitations under the License.
   222  
   223  apiVersion: v1
   224  kind: Namespace
   225  metadata:
   226    name: cnrm-system
   227  ---
   228  apiVersion: v1
   229  kind: ServiceAccount
   230  metadata:
   231    name: cnrm-controller-manager
   232    namespace: cnrm-system
   233  ---
   234  apiVersion: v1
   235  kind: Service
   236  metadata:
   237    name: cnrm-manager
   238    namespace: cnrm-system
   239  spec:
   240    ports:
   241    - name: controller-manager
   242      port: 443
   243    - name: metrics
   244      port: 8888
   245    selector:
   246      cnrm.cloud.google.com/component: cnrm-controller-manager
   247      cnrm.cloud.google.com/system: "true"
   248  ---
   249  apiVersion: apps/v1
   250  kind: StatefulSet
   251  metadata:
   252    labels:
   253      cnrm.cloud.google.com/component: cnrm-controller-manager
   254      cnrm.cloud.google.com/system: "true"
   255    name: cnrm-controller-manager
   256    namespace: cnrm-system
   257  spec:
   258    selector:
   259      matchLabels:
   260        cnrm.cloud.google.com/component: cnrm-controller-manager
   261        cnrm.cloud.google.com/system: "true"
   262    serviceName: cnrm-manager
   263    template:
   264      metadata:
   265        labels:
   266          cnrm.cloud.google.com/component: cnrm-controller-manager
   267          cnrm.cloud.google.com/system: "true"
   268      spec:
   269        volumes:
   270        - name: gcp-service-account
   271          secret:
   272            secretName: gcp-key
   273  `
   274  
   275  var namespacedManifest = `# Copyright 2022 Google LLC
   276  #
   277  # Licensed under the Apache License, Version 2.0 (the "License");
   278  # you may not use this file except in compliance with the License.
   279  # You may obtain a copy of the License at
   280  #
   281  #      http://www.apache.org/licenses/LICENSE-2.0
   282  #
   283  # Unless required by applicable law or agreed to in writing, software
   284  # distributed under the License is distributed on an "AS IS" BASIS,
   285  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   286  # See the License for the specific language governing permissions and
   287  # limitations under the License.
   288  
   289  apiVersion: apiextensions.k8s.io/v1
   290  kind: CustomResourceDefinition
   291  metadata:
   292    name: foos.test.cnrm.cloud.google.com
   293    labels:
   294      cnrm.cloud.google.com/system: "true"
   295      cnrm.cloud.google.com/managed-by-kcc: "true"
   296  spec:
   297    scope: Namespaced
   298    group: test.cnrm.cloud.google.com
   299    names:
   300      kind: foo
   301      plural: foos
   302    versions:
   303    - name: v1alpha1
   304      schema:
   305        openAPIV3Schema:
   306          type: object
   307      served: true
   308      storage: true
   309  ---
   310  apiVersion: apiextensions.k8s.io/v1
   311  kind: CustomResourceDefinition
   312  metadata:
   313    name: bars.test.cnrm.cloud.google.com
   314    labels:
   315      cnrm.cloud.google.com/system: "true"
   316      cnrm.cloud.google.com/managed-by-kcc: "true"
   317  spec:
   318    scope: Namespaced
   319    group: test.cnrm.cloud.google.com
   320    names:
   321      kind: bar
   322      plural: bars
   323    versions:
   324    - name: v1alpha1
   325      schema:
   326        openAPIV3Schema:
   327          type: object
   328      served: true
   329      storage: true
   330  ---
   331  # Copyright 2022 Google LLC
   332  #
   333  # Licensed under the Apache License, Version 2.0 (the "License");
   334  # you may not use this file except in compliance with the License.
   335  # You may obtain a copy of the License at
   336  #
   337  #      http://www.apache.org/licenses/LICENSE-2.0
   338  #
   339  # Unless required by applicable law or agreed to in writing, software
   340  # distributed under the License is distributed on an "AS IS" BASIS,
   341  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   342  # See the License for the specific language governing permissions and
   343  # limitations under the License.
   344  
   345  apiVersion: v1
   346  kind: Namespace
   347  metadata:
   348    name: cnrm-system
   349  `
   350  
   351  var namespacedComponentsOnly = `# Copyright 2022 Google LLC
   352  #
   353  # Licensed under the Apache License, Version 2.0 (the "License");
   354  # you may not use this file except in compliance with the License.
   355  # You may obtain a copy of the License at
   356  #
   357  #      http://www.apache.org/licenses/LICENSE-2.0
   358  #
   359  # Unless required by applicable law or agreed to in writing, software
   360  # distributed under the License is distributed on an "AS IS" BASIS,
   361  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   362  # See the License for the specific language governing permissions and
   363  # limitations under the License.
   364  
   365  apiVersion: v1
   366  kind: ServiceAccount
   367  metadata:
   368    annotations:
   369      iam.gke.io/gcp-service-account: cnrm-system-${NAMESPACE?}@${PROJECT_ID?}.iam.gserviceaccount.com
   370    labels:
   371      cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
   372      cnrm.cloud.google.com/system: "true"
   373    name: cnrm-controller-manager-${NAMESPACE?}
   374    namespace: cnrm-system
   375  ---
   376  apiVersion: v1
   377  kind: Service
   378  metadata:
   379    name: cnrm-manager-${NAMESPACE?}
   380    namespace: cnrm-system
   381  spec:
   382    ports:
   383    - name: controller-manager
   384      port: 443
   385    - name: metrics
   386      port: 8888
   387    selector:
   388      cnrm.cloud.google.com/component: cnrm-controller-manager
   389      cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
   390      cnrm.cloud.google.com/system: "true"
   391  ---
   392  apiVersion: apps/v1
   393  kind: StatefulSet
   394  metadata:
   395    labels:
   396      cnrm.cloud.google.com/component: cnrm-controller-manager
   397      cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
   398      cnrm.cloud.google.com/system: "true"
   399    name: cnrm-controller-manager-${NAMESPACE?}
   400    namespace: cnrm-system
   401  spec:
   402    selector:
   403      matchLabels:
   404        cnrm.cloud.google.com/component: cnrm-controller-manager
   405        cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
   406        cnrm.cloud.google.com/system: "true"
   407    serviceName: cnrm-manager-${NAMESPACE?}
   408    template:
   409      metadata:
   410        labels:
   411          cnrm.cloud.google.com/component: cnrm-controller-manager
   412          cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
   413          cnrm.cloud.google.com/system: "true"
   414  `
   415  
   416  func TestNewLocalRepository_LoadManifest(t *testing.T) {
   417  	t.Parallel()
   418  	basedir, repo := newTestNewLocalRepository(t)
   419  	tests := []struct {
   420  		name   string
   421  		cc     *corev1beta1.ConfigConnector
   422  		result map[string]string
   423  	}{
   424  		{
   425  			name: "cluster mode, workload identity",
   426  			cc: &corev1beta1.ConfigConnector{
   427  				ObjectMeta: metav1.ObjectMeta{
   428  					Name: k8s.ConfigConnectorAllowedName,
   429  				},
   430  				Spec: corev1beta1.ConfigConnectorSpec{
   431  					GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
   432  					Mode:                 "cluster",
   433  				},
   434  			},
   435  			result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "cluster", "workload-identity"}, "/"): clusterModeWIManifest},
   436  		},
   437  		{
   438  			name: "cluster mode, gcp identity",
   439  			cc: &corev1beta1.ConfigConnector{
   440  				ObjectMeta: metav1.ObjectMeta{
   441  					Name: k8s.ConfigConnectorAllowedName,
   442  				},
   443  				Spec: corev1beta1.ConfigConnectorSpec{
   444  					CredentialSecretName: "my-key",
   445  					Mode:                 "cluster",
   446  				},
   447  			},
   448  			result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "cluster", "gcp-identity"}, "/"): clusterModeGcpManifest},
   449  		},
   450  		{
   451  			name: "namespaced mode",
   452  			cc: &corev1beta1.ConfigConnector{
   453  				ObjectMeta: metav1.ObjectMeta{
   454  					Name: k8s.ConfigConnectorAllowedName,
   455  				},
   456  				Spec: corev1beta1.ConfigConnectorSpec{
   457  					GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
   458  					Mode:                 "namespaced",
   459  				},
   460  			},
   461  			result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "namespaced"}, "/"): namespacedManifest},
   462  		},
   463  		{
   464  			name: "namespaced mode by default",
   465  			cc: &corev1beta1.ConfigConnector{
   466  				ObjectMeta: metav1.ObjectMeta{
   467  					Name: k8s.ConfigConnectorAllowedName,
   468  				},
   469  				Spec: corev1beta1.ConfigConnectorSpec{
   470  					GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
   471  				},
   472  			},
   473  			result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "namespaced"}, "/"): namespacedManifest},
   474  		},
   475  	}
   476  
   477  	for _, test := range tests {
   478  		tc := test
   479  		t.Run(tc.name, func(t *testing.T) {
   480  			manifestStrs, err := repo.LoadManifest(context.TODO(), "configconnector", "0.0.0-test", tc.cc)
   481  			if err != nil {
   482  				t.Fatalf("unexpected error while loadding the manifest: %v", err)
   483  			}
   484  			if !reflect.DeepEqual(manifestStrs, tc.result) {
   485  				t.Fatalf("unexpected diff: %v", cmp.Diff(manifestStrs, tc.result))
   486  			}
   487  		})
   488  	}
   489  }
   490  
   491  func TestNewLocalRepository_LoadNamespacedComponents(t *testing.T) {
   492  	t.Parallel()
   493  	baseDir, repo := newTestNewLocalRepository(t)
   494  	manifestPath := path.Join(baseDir, "packages/configconnector/0.0.0-test/namespaced/per-namespace-components.yaml")
   495  	tests := []struct {
   496  		name   string
   497  		result map[string]string
   498  	}{
   499  		{
   500  			name:   "load namespaced component",
   501  			result: map[string]string{manifestPath: namespacedComponentsOnly},
   502  		},
   503  	}
   504  	for _, test := range tests {
   505  		tc := test
   506  		t.Run(tc.name, func(t *testing.T) {
   507  			t.Parallel()
   508  			manifests, err := repo.LoadNamespacedComponents(context.TODO(), "configconnector", "0.0.0-test")
   509  			if err != nil {
   510  				t.Fatalf("unexpected error while loadding the manifest for namespaced components: %v", err)
   511  			}
   512  			if !reflect.DeepEqual(manifests, tc.result) {
   513  				t.Fatalf("unexpected diff: %v", cmp.Diff(manifests, tc.result))
   514  			}
   515  		})
   516  	}
   517  }
   518  
   519  func TestNewLocalRepository_LoadChannel(t *testing.T) {
   520  	t.Parallel()
   521  	_, repo := newTestNewLocalRepository(t)
   522  	res, err := repo.LoadChannel(context.TODO(), "stable")
   523  	if err != nil {
   524  		t.Fatalf("unexpected error: %v", err)
   525  	}
   526  	expected := &loaders.Channel{
   527  		Manifests: []loaders.Version{
   528  			{
   529  				Version: "0.0.0-test",
   530  			},
   531  		},
   532  	}
   533  	if !reflect.DeepEqual(res, expected) {
   534  		t.Fatalf("unexpected diff: %v", cmp.Diff(res, expected))
   535  	}
   536  }
   537  
   538  func newTestNewLocalRepository(t *testing.T) (string, manifest.Repository) {
   539  	root := testpaths.GetOperatorSrcRootOrLogFatal()
   540  	basedir := root + "/" + "pkg/manifest/testchannel"
   541  	return basedir, manifest.NewLocalRepository(basedir)
   542  }
   543  

View as plain text