diff --git a/Makefile b/Makefile index 2167d3d03..d780cfe21 100644 --- a/Makefile +++ b/Makefile @@ -76,7 +76,7 @@ update: copy-crd update-csv test-unit: ensure-kubebuilder-tools -update-csv: ensure-operator-sdk ensure-operator-helm +update-csv: ensure-operator-sdk ensure-helm bash -x hack/update-csv.sh # update the replaces to released version in csv @@ -126,7 +126,7 @@ else $(info Using existing operator-sdk from "$(OPERATOR_SDK)") endif -ensure-operator-helm: +ensure-helm: ifeq "" "$(wildcard $(HELM))" $(info Installing helm into '$(HELM)') mkdir -p '$(helm_gen_dir)' diff --git a/deploy/cluster-manager/chart/cluster-manager/templates/_helpers.tpl b/deploy/cluster-manager/chart/cluster-manager/templates/_helpers.tpl index 9c9b7c3e2..726e15011 100644 --- a/deploy/cluster-manager/chart/cluster-manager/templates/_helpers.tpl +++ b/deploy/cluster-manager/chart/cluster-manager/templates/_helpers.tpl @@ -3,6 +3,8 @@ {{- with .Values.images }} {{- if and .imageCredentials.userName .imageCredentials.password }} {{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .registry (printf "%s:%s" .imageCredentials.userName .imageCredentials.password | b64enc) | b64enc }} +{{- else if .imageCredentials.dockerConfigJson }} +{{- printf "%s" .imageCredentials.dockerConfigJson | b64enc }} {{- else }} {{- printf "{}" | b64enc }} {{- end }} @@ -15,7 +17,7 @@ {{- printf "ocmhub" }} {{- end }} {{- define "tokenSecret" }} -{{- printf "%s" (randAlphaNum 6) }} +{{- printf "%s" (randAlphaNum 16) }} {{- end }} {{/* Define the image tag. */}} diff --git a/deploy/cluster-manager/chart/cluster-manager/templates/cluster_manager.yaml b/deploy/cluster-manager/chart/cluster-manager/templates/cluster_manager.yaml index 8a4e204f8..c49c14315 100644 --- a/deploy/cluster-manager/chart/cluster-manager/templates/cluster_manager.yaml +++ b/deploy/cluster-manager/chart/cluster-manager/templates/cluster_manager.yaml @@ -1,3 +1,4 @@ +{{- if .Values.clusterManager.create }} apiVersion: operator.open-cluster-management.io/v1 kind: ClusterManager metadata: @@ -31,3 +32,4 @@ spec: addOnManagerConfiguration: {{- toYaml . | nindent 4 }} {{- end }} +{{- end }} diff --git a/deploy/cluster-manager/chart/cluster-manager/values.yaml b/deploy/cluster-manager/chart/cluster-manager/values.yaml index 3944f7d59..08176189a 100644 --- a/deploy/cluster-manager/chart/cluster-manager/values.yaml +++ b/deploy/cluster-manager/chart/cluster-manager/values.yaml @@ -10,13 +10,14 @@ images: tag: "" imagePullPolicy: IfNotPresent # The image pull secret name is open-cluster-management-image-pull-credentials. - # Please set the userName and password if you use a private image registry. + # Please set the userName/password or the dockerConfigJson if you use a private image registry. # The image pull secret is fixed into the serviceAccount, you can also set # `createImageCredentials` to `false` and create the pull secret manually. imageCredentials: createImageCredentials: false userName: "" password: "" + dockerConfigJson: "" # podSecurityContext for clusterManager operator deployment. podSecurityContext: @@ -77,6 +78,8 @@ createBootstrapSA: false # configurations for clusterManager CR. clusterManager: + # if false, will not create clusterManager instance, default is true. + create: true mode: Default resourceRequirement: type: Default diff --git a/deploy/cluster-manager/chart/config.go b/deploy/cluster-manager/chart/config.go index 9250eb046..e96942988 100644 --- a/deploy/cluster-manager/chart/config.go +++ b/deploy/cluster-manager/chart/config.go @@ -2,10 +2,6 @@ package chart import ( "embed" - - corev1 "k8s.io/api/core/v1" - - operatorv1 "open-cluster-management.io/api/operator/v1" ) //go:embed cluster-manager @@ -15,70 +11,3 @@ import ( var ChartFiles embed.FS const ChartName = "cluster-manager" - -type ChartConfig struct { - // CreateNamespace is used in the render function to append the release ns in the objects. - CreateNamespace bool `json:"createNamespace,omitempty"` - // ReplicaCount is the replicas for the clusterManager operator deployment. - ReplicaCount int `json:"replicaCount,omitempty"` - // Images is the configurations for all images used in operator deployment and clusterManager CR. - Images ImagesConfig `json:"images,omitempty"` - // PodSecurityContext is the pod SecurityContext in the operator deployment - PodSecurityContext corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` - // SecurityContext is the container SecurityContext in operator deployment - SecurityContext corev1.SecurityContext `json:"securityContext,omitempty"` - // Resources is the resource requirements of the operator deployment - Resources corev1.ResourceRequirements `json:"resources,omitempty"` - // NodeSelector is the nodeSelector of the operator deployment - NodeSelector corev1.NodeSelector `json:"nodeSelector,omitempty"` - // Tolerations is the tolerations of the operator deployment - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` - // Affinity is the affinity of the operator deployment - Affinity corev1.Affinity `json:"affinity,omitempty"` - // CreateBootstrapToken is to enable/disable the bootstrap token secret for auto approve. - CreateBootstrapToken bool `json:"createBootstrapToken,omitempty"` - // CreateBootstrapSA is to create a serviceAccount to generate token. - CreateBootstrapSA bool `json:"createBootstrapSA,omitempty"` - // ClusterManager is the configuration of clusterManager CR - ClusterManager ClusterManagerConfig `json:"clusterManager,omitempty"` -} - -type ImagesConfig struct { - // Registry is registry name must NOT contain a trailing slash. - Registry string `json:"registry,omitempty"` - // Tag is the operator image tag. - Tag string `json:"tag,omitempty"` - // ImagePullPolicy is the image pull policy of operator image. Default is IfNotPresent. - ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - // The image pull secret name is open-cluster-management-image-pull-credentials. - // Please set the userName and password if you use a private image registry. - ImageCredentials ImageCredentials `json:"imageCredentials,omitempty"` -} - -type ImageCredentials struct { - CreateImageCredentials bool `json:"createImageCredentials,omitempty"` - UserName string `json:"userName,omitempty"` - Password string `json:"password,omitempty"` -} - -type ClusterManagerConfig struct { - // InstallMode represents the mode of deploy cluster-manager - Mode operatorv1.InstallMode `json:"mode,omitempty"` - - // RegistrationConfiguration contains the configuration of registration - // +optional - RegistrationConfiguration operatorv1.RegistrationHubConfiguration `json:"registrationConfiguration,omitempty"` - - // WorkConfiguration contains the configuration of work - // +optional - WorkConfiguration operatorv1.WorkConfiguration `json:"workConfiguration,omitempty"` - - // AddOnManagerConfiguration contains the configuration of addon manager - // +optional - AddOnManagerConfiguration operatorv1.AddOnManagerConfiguration `json:"addOnManagerConfiguration,omitempty"` - - // ResourceRequirement specify QoS classes of deployments managed by clustermanager. - // It applies to all the containers in the deployments. - // +optional - ResourceRequirement operatorv1.ResourceRequirement `json:"resourceRequirement,omitempty"` -} diff --git a/deploy/klusterlet/chart/config.go b/deploy/klusterlet/chart/config.go index 5b9eccbca..6f97a8d7d 100644 --- a/deploy/klusterlet/chart/config.go +++ b/deploy/klusterlet/chart/config.go @@ -2,10 +2,6 @@ package chart import ( "embed" - - corev1 "k8s.io/api/core/v1" - - operatorv1 "open-cluster-management.io/api/operator/v1" ) //go:embed klusterlet @@ -15,88 +11,3 @@ import ( var ChartFiles embed.FS const ChartName = "klusterlet" - -type ChartConfig struct { - // CreateNamespace is used in the render function to append the release ns in the objects. - CreateNamespace bool `json:"createNamespace,omitempty"` - // ReplicaCount is the replicas for the klusterlet operator deployment. - ReplicaCount int `json:"replicaCount,omitempty"` - // Images is the configurations for all images used in operator deployment and klusterlet CR. - Images ImagesConfig `json:"images,omitempty"` - // PodSecurityContext is the pod SecurityContext in the operator deployment - PodSecurityContext corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` - // SecurityContext is the container SecurityContext in operator deployment - SecurityContext corev1.SecurityContext `json:"securityContext,omitempty"` - // Resources is the resource requirements of the operator deployment - Resources corev1.ResourceRequirements `json:"resources,omitempty"` - // NodeSelector is the nodeSelector of the operator deployment - NodeSelector corev1.NodeSelector `json:"nodeSelector,omitempty"` - // Tolerations is the tolerations of the operator deployment - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` - // Affinity is the affinity of the operator deployment - Affinity corev1.Affinity `json:"affinity,omitempty"` - // Klusterlet is the configuration of klusterlet CR - Klusterlet KlusterletConfig `json:"klusterlet,omitempty"` - // PriorityClassName is the name of the PriorityClass that will be used by the deployed klusterlet agent and operator. - PriorityClassName string `json:"priorityClassName,omitempty"` - - // EnableSyncLabels is to enable the feature which can sync the labels from klusterlet to all agent resources. - EnableSyncLabels bool `json:"enableSyncLabels,omitempty"` - - // BootstrapHubKubeConfig should be the kubeConfig file of the hub cluster via setting --set-file= optional - BootstrapHubKubeConfig string `json:"bootstrapHubKubeConfig,omitempty"` - - // ExternalManagedKubeConfig should be the kubeConfig file of the managed cluster via setting --set-file= - // only need to set in the hosted mode. optional - ExternalManagedKubeConfig string `json:"externalManagedKubeConfig,omitempty"` - - // NoOperator is to only deploy the klusterlet CR if set true. - NoOperator bool `json:"noOperator,omitempty"` -} - -type ImagesConfig struct { - // Registry is registry name must NOT contain a trailing slash. - Registry string `json:"registry,omitempty"` - // Tag is the operator image tag. - Tag string `json:"tag,omitempty"` - // ImagePullPolicy is the image pull policy of operator image. Default is IfNotPresent. - ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - // The image pull secret name is open-cluster-management-image-pull-credentials. - // Please set the userName and password if you use a private image registry. - ImageCredentials ImageCredentials `json:"imageCredentials,omitempty"` -} - -type ImageCredentials struct { - CreateImageCredentials bool `json:"createImageCredentials,omitempty"` - UserName string `json:"userName,omitempty"` - Password string `json:"password,omitempty"` -} - -type KlusterletConfig struct { - // InstallMode represents the mode of deploy klusterlet - Mode operatorv1.InstallMode `json:"mode,omitempty"` - Name string `json:"name,omitempty"` - ClusterName string `json:"clusterName,omitempty"` - Namespace string `json:"namespace,omitempty"` - // ExternalServerURLs represents a list of apiserver urls and ca bundles that is accessible externally - // If it is set empty, managed cluster has no externally accessible url that hub cluster can visit. - // +optional - ExternalServerURLs []operatorv1.ServerURL `json:"externalServerURLs,omitempty"` - - // NodePlacement enables explicit control over the scheduling of the deployed pods. - // +optional - NodePlacement operatorv1.NodePlacement `json:"nodePlacement,omitempty"` - - // RegistrationConfiguration contains the configuration of registration - // +optional - RegistrationConfiguration operatorv1.RegistrationConfiguration `json:"registrationConfiguration,omitempty"` - - // WorkConfiguration contains the configuration of work - // +optional - WorkConfiguration operatorv1.WorkAgentConfiguration `json:"workConfiguration,omitempty"` - - // ResourceRequirement specify QoS classes of deployments managed by clustermanager. - // It applies to all the containers in the deployments. - // +optional - ResourceRequirement operatorv1.ResourceRequirement `json:"resourceRequirement,omitempty"` -} diff --git a/deploy/klusterlet/chart/klusterlet/templates/_helpers.tpl b/deploy/klusterlet/chart/klusterlet/templates/_helpers.tpl index 925e292e3..d402a8e46 100644 --- a/deploy/klusterlet/chart/klusterlet/templates/_helpers.tpl +++ b/deploy/klusterlet/chart/klusterlet/templates/_helpers.tpl @@ -6,6 +6,8 @@ Create secret to access docker registry {{- with .Values.images }} {{- if and .imageCredentials.userName .imageCredentials.password }} {{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .registry (printf "%s:%s" .imageCredentials.userName .imageCredentials.password | b64enc) | b64enc }} +{{- else if .imageCredentials.dockerConfigJson }} +{{- printf "%s" .imageCredentials.dockerConfigJson | b64enc }} {{- else }} {{- printf "{}" | b64enc }} {{- end }} diff --git a/deploy/klusterlet/chart/klusterlet/templates/klusterlet.yaml b/deploy/klusterlet/chart/klusterlet/templates/klusterlet.yaml index 9b134e334..3367be46b 100644 --- a/deploy/klusterlet/chart/klusterlet/templates/klusterlet.yaml +++ b/deploy/klusterlet/chart/klusterlet/templates/klusterlet.yaml @@ -1,3 +1,4 @@ +{{- if .Values.klusterlet.create }} apiVersion: operator.open-cluster-management.io/v1 kind: Klusterlet metadata: @@ -41,3 +42,4 @@ spec: {{- if .Values.priorityClassName }} priorityClassName: "{{ .Values.priorityClassName }}" {{- end }} +{{- end }} diff --git a/deploy/klusterlet/chart/klusterlet/values.yaml b/deploy/klusterlet/chart/klusterlet/values.yaml index c2731eccb..eb3f368fd 100644 --- a/deploy/klusterlet/chart/klusterlet/values.yaml +++ b/deploy/klusterlet/chart/klusterlet/values.yaml @@ -9,13 +9,14 @@ images: tag: "" imagePullPolicy: IfNotPresent # The image pull secret name is open-cluster-management-image-pull-credentials. - # Please set the userName and password if you use a private image registry. + # Please set the userName/password or the dockerConfigJson if you use a private image registry. # The image pull secret is fixed into the serviceAccount, you can also set # `createImageCredentials` to `false` and create the pull secret manually. imageCredentials: createImageCredentials: false userName: "" password: "" + dockerConfigJson: "" podSecurityContext: runAsNonRoot: true @@ -80,6 +81,8 @@ noOperator: false priorityClassName: "" klusterlet: + # if false, will not create klusterlet CR. default it true. + create: true # mode can be Default, Hosted, Singleton or SingletonHosted. mode: Singleton name: "klusterlet" diff --git a/pkg/operator/helpers/chart/config.go b/pkg/operator/helpers/chart/config.go new file mode 100644 index 000000000..96faf1233 --- /dev/null +++ b/pkg/operator/helpers/chart/config.go @@ -0,0 +1,146 @@ +package chart + +import ( + corev1 "k8s.io/api/core/v1" + + operatorv1 "open-cluster-management.io/api/operator/v1" +) + +type ClusterManagerChartConfig struct { + // CreateNamespace is used in the render function to append the release ns in the objects. + CreateNamespace bool `json:"createNamespace,omitempty"` + // ReplicaCount is the replicas for the clusterManager operator deployment. + ReplicaCount int `json:"replicaCount,omitempty"` + // Images is the configurations for all images used in operator deployment and clusterManager CR. + Images ImagesConfig `json:"images,omitempty"` + // PodSecurityContext is the pod SecurityContext in the operator deployment + PodSecurityContext corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // SecurityContext is the container SecurityContext in operator deployment + SecurityContext corev1.SecurityContext `json:"securityContext,omitempty"` + // Resources is the resource requirements of the operator deployment + Resources corev1.ResourceRequirements `json:"resources,omitempty"` + // NodeSelector is the nodeSelector of the operator deployment + NodeSelector corev1.NodeSelector `json:"nodeSelector,omitempty"` + // Tolerations is the tolerations of the operator deployment + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // Affinity is the affinity of the operator deployment + Affinity corev1.Affinity `json:"affinity,omitempty"` + // CreateBootstrapToken is to enable/disable the bootstrap token secret for auto approve. + CreateBootstrapToken bool `json:"createBootstrapToken,omitempty"` + // CreateBootstrapSA is to create a serviceAccount to generate token. + CreateBootstrapSA bool `json:"createBootstrapSA,omitempty"` + // ClusterManager is the configuration of clusterManager CR + ClusterManager ClusterManagerConfig `json:"clusterManager,omitempty"` +} + +type KlusterletChartConfig struct { + // CreateNamespace is used in the render function to append the release ns in the objects. + CreateNamespace bool `json:"createNamespace,omitempty"` + // ReplicaCount is the replicas for the klusterlet operator deployment. + ReplicaCount int `json:"replicaCount,omitempty"` + // Images is the configurations for all images used in operator deployment and klusterlet CR. + Images ImagesConfig `json:"images,omitempty"` + // PodSecurityContext is the pod SecurityContext in the operator deployment + PodSecurityContext corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // SecurityContext is the container SecurityContext in operator deployment + SecurityContext corev1.SecurityContext `json:"securityContext,omitempty"` + // Resources is the resource requirements of the operator deployment + Resources corev1.ResourceRequirements `json:"resources,omitempty"` + // NodeSelector is the nodeSelector of the operator deployment + NodeSelector corev1.NodeSelector `json:"nodeSelector,omitempty"` + // Tolerations is the tolerations of the operator deployment + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // Affinity is the affinity of the operator deployment + Affinity corev1.Affinity `json:"affinity,omitempty"` + // Klusterlet is the configuration of klusterlet CR + Klusterlet KlusterletConfig `json:"klusterlet,omitempty"` + // PriorityClassName is the name of the PriorityClass that will be used by the deployed klusterlet agent and operator. + PriorityClassName string `json:"priorityClassName,omitempty"` + + // EnableSyncLabels is to enable the feature which can sync the labels from klusterlet to all agent resources. + EnableSyncLabels bool `json:"enableSyncLabels,omitempty"` + + // BootstrapHubKubeConfig should be the kubeConfig file of the hub cluster via setting --set-file= optional + BootstrapHubKubeConfig string `json:"bootstrapHubKubeConfig,omitempty"` + + // ExternalManagedKubeConfig should be the kubeConfig file of the managed cluster via setting --set-file= + // only need to set in the hosted mode. optional + ExternalManagedKubeConfig string `json:"externalManagedKubeConfig,omitempty"` + + // NoOperator is to only deploy the klusterlet CR if set true. + NoOperator bool `json:"noOperator,omitempty"` +} + +type ImagesConfig struct { + // Registry is registry name must NOT contain a trailing slash. + Registry string `json:"registry,omitempty"` + // Tag is the operator image tag. + Tag string `json:"tag,omitempty"` + // ImagePullPolicy is the image pull policy of operator image. Default is IfNotPresent. + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + // The image pull secret name is open-cluster-management-image-pull-credentials. + // Please set the userName and password if you use a private image registry. + ImageCredentials ImageCredentials `json:"imageCredentials,omitempty"` +} + +type ImageCredentials struct { + CreateImageCredentials bool `json:"createImageCredentials,omitempty"` + UserName string `json:"userName,omitempty"` + Password string `json:"password,omitempty"` + DockerConfigJson string `json:"dockerConfigJson,omitempty"` +} + +type ClusterManagerConfig struct { + // Create determines if create the clusterManager CR, default is true. + Create bool `json:"create,omitempty"` + // InstallMode represents the mode of deploy cluster-manager + Mode operatorv1.InstallMode `json:"mode,omitempty"` + + // RegistrationConfiguration contains the configuration of registration + // +optional + RegistrationConfiguration operatorv1.RegistrationHubConfiguration `json:"registrationConfiguration,omitempty"` + + // WorkConfiguration contains the configuration of work + // +optional + WorkConfiguration operatorv1.WorkConfiguration `json:"workConfiguration,omitempty"` + + // AddOnManagerConfiguration contains the configuration of addon manager + // +optional + AddOnManagerConfiguration operatorv1.AddOnManagerConfiguration `json:"addOnManagerConfiguration,omitempty"` + + // ResourceRequirement specify QoS classes of deployments managed by clustermanager. + // It applies to all the containers in the deployments. + // +optional + ResourceRequirement operatorv1.ResourceRequirement `json:"resourceRequirement,omitempty"` +} + +type KlusterletConfig struct { + // Create determines if create the klusterlet CR, default is true. + Create bool `json:"create,omitempty"` + // InstallMode represents the mode of deploy klusterlet + Mode operatorv1.InstallMode `json:"mode,omitempty"` + Name string `json:"name,omitempty"` + ClusterName string `json:"clusterName,omitempty"` + Namespace string `json:"namespace,omitempty"` + // ExternalServerURLs represents a list of apiserver urls and ca bundles that is accessible externally + // If it is set empty, managed cluster has no externally accessible url that hub cluster can visit. + // +optional + ExternalServerURLs []operatorv1.ServerURL `json:"externalServerURLs,omitempty"` + + // NodePlacement enables explicit control over the scheduling of the deployed pods. + // +optional + NodePlacement operatorv1.NodePlacement `json:"nodePlacement,omitempty"` + + // RegistrationConfiguration contains the configuration of registration + // +optional + RegistrationConfiguration operatorv1.RegistrationConfiguration `json:"registrationConfiguration,omitempty"` + + // WorkConfiguration contains the configuration of work + // +optional + WorkConfiguration operatorv1.WorkAgentConfiguration `json:"workConfiguration,omitempty"` + + // ResourceRequirement specify QoS classes of deployments managed by clustermanager. + // It applies to all the containers in the deployments. + // +optional + ResourceRequirement operatorv1.ResourceRequirement `json:"resourceRequirement,omitempty"` +} diff --git a/pkg/operator/helpers/chart/render.go b/pkg/operator/helpers/chart/render.go index 8c0049d20..ddd698f62 100644 --- a/pkg/operator/helpers/chart/render.go +++ b/pkg/operator/helpers/chart/render.go @@ -22,20 +22,26 @@ import ( klusterletchart "open-cluster-management.io/ocm/deploy/klusterlet/chart" ) -func NewDefaultClusterManagerChartConfig() *clustermanagerchart.ChartConfig { - return &clustermanagerchart.ChartConfig{ +func NewDefaultClusterManagerChartConfig() *ClusterManagerChartConfig { + return &ClusterManagerChartConfig{ ReplicaCount: 3, CreateBootstrapToken: false, + ClusterManager: ClusterManagerConfig{ + Create: true, + }, } } -func NewDefaultKlusterletChartConfig() *klusterletchart.ChartConfig { - return &klusterletchart.ChartConfig{ +func NewDefaultKlusterletChartConfig() *KlusterletChartConfig { + return &KlusterletChartConfig{ ReplicaCount: 3, + Klusterlet: KlusterletConfig{ + Create: true, + }, } } -func RenderClusterManagerChart(config *clustermanagerchart.ChartConfig, namespace string) ([][]byte, error) { +func RenderClusterManagerChart(config *ClusterManagerChartConfig, namespace string) ([][]byte, error) { if namespace == "" { return nil, fmt.Errorf("cluster manager chart namespace is required") } @@ -43,7 +49,7 @@ func RenderClusterManagerChart(config *clustermanagerchart.ChartConfig, namespac clustermanagerchart.ChartName, clustermanagerchart.ChartFiles) } -func RenderKlusterletChart(config *klusterletchart.ChartConfig, namespace string) ([][]byte, error) { +func RenderKlusterletChart(config *KlusterletChartConfig, namespace string) ([][]byte, error) { if namespace == "" { return nil, fmt.Errorf("klusterlet chart namespace is required") } @@ -51,7 +57,7 @@ func RenderKlusterletChart(config *klusterletchart.ChartConfig, namespace string klusterletchart.ChartName, klusterletchart.ChartFiles) } -func renderChart[T *clustermanagerchart.ChartConfig | *klusterletchart.ChartConfig](config T, +func renderChart[T *ClusterManagerChartConfig | *KlusterletChartConfig](config T, namespace string, createNamespace bool, chartName string, fs embed.FS) ([][]byte, error) { // chartName is the prefix of chart path here operatorChart, err := LoadChart(fs, chartName) diff --git a/pkg/operator/helpers/chart/render_test.go b/pkg/operator/helpers/chart/render_test.go index ac838a690..56cb71fc6 100644 --- a/pkg/operator/helpers/chart/render_test.go +++ b/pkg/operator/helpers/chart/render_test.go @@ -1,6 +1,7 @@ package chart import ( + "encoding/base64" "fmt" "os" "testing" @@ -14,9 +15,6 @@ import ( "k8s.io/client-go/kubernetes/scheme" operatorv1 "open-cluster-management.io/api/operator/v1" - - clustermanagerchart "open-cluster-management.io/ocm/deploy/cluster-manager/chart" - klusterletchart "open-cluster-management.io/ocm/deploy/klusterlet/chart" ) const ( @@ -42,13 +40,13 @@ func TestClusterManagerConfig(t *testing.T) { cases := []struct { name string namespace string - chartConfig func() *clustermanagerchart.ChartConfig + chartConfig func() *ClusterManagerChartConfig expectedObjCnt int }{ { name: "default config", namespace: "open-cluster-management", - chartConfig: func() *clustermanagerchart.ChartConfig { + chartConfig: func() *ClusterManagerChartConfig { config := NewDefaultClusterManagerChartConfig() return config }, @@ -57,7 +55,7 @@ func TestClusterManagerConfig(t *testing.T) { { name: "enable bootstrap token", namespace: "multicluster-engine", - chartConfig: func() *clustermanagerchart.ChartConfig { + chartConfig: func() *ClusterManagerChartConfig { config := NewDefaultClusterManagerChartConfig() config.CreateBootstrapToken = true return config @@ -67,7 +65,7 @@ func TestClusterManagerConfig(t *testing.T) { { name: "enable bootstrap sa", namespace: "multicluster-engine", - chartConfig: func() *clustermanagerchart.ChartConfig { + chartConfig: func() *ClusterManagerChartConfig { config := NewDefaultClusterManagerChartConfig() config.CreateBootstrapSA = true return config @@ -77,13 +75,13 @@ func TestClusterManagerConfig(t *testing.T) { { name: "change images config", namespace: "ocm", - chartConfig: func() *clustermanagerchart.ChartConfig { + chartConfig: func() *ClusterManagerChartConfig { config := NewDefaultClusterManagerChartConfig() - config.Images = clustermanagerchart.ImagesConfig{ + config.Images = ImagesConfig{ Registry: "myrepo", Tag: "v9.9.9", ImagePullPolicy: corev1.PullAlways, - ImageCredentials: clustermanagerchart.ImageCredentials{ + ImageCredentials: ImageCredentials{ CreateImageCredentials: true, UserName: "test", Password: "test", @@ -93,10 +91,28 @@ func TestClusterManagerConfig(t *testing.T) { }, expectedObjCnt: 7, }, + { + name: "change images config dockerConfigJson", + namespace: "ocm", + chartConfig: func() *ClusterManagerChartConfig { + config := NewDefaultClusterManagerChartConfig() + config.Images = ImagesConfig{ + Registry: "myrepo", + Tag: "v9.9.9", + ImagePullPolicy: corev1.PullAlways, + ImageCredentials: ImageCredentials{ + CreateImageCredentials: true, + DockerConfigJson: `{"auths":{"quay.io":{"auth":"YWJjCg=="}}}`, + }, + } + return config + }, + expectedObjCnt: 7, + }, { name: "create namespace", namespace: "multicluster-engine", - chartConfig: func() *clustermanagerchart.ChartConfig { + chartConfig: func() *ClusterManagerChartConfig { config := NewDefaultClusterManagerChartConfig() config.CreateBootstrapToken = true config.CreateNamespace = true @@ -163,6 +179,22 @@ func TestClusterManagerConfig(t *testing.T) { object.Spec.AddOnManagerImagePullSpec != fmt.Sprintf("%s/addon-manager:%s", registry, version) { t.Errorf("failed to render images") } + case *corev1.Secret: + switch object.Name { + case "open-cluster-management-image-pull-credentials": + data := object.Data[corev1.DockerConfigJsonKey] + if len(data) == 0 { + t.Errorf("failed to get image pull secret") + } + if base64.StdEncoding.EncodeToString(data) == "" { + t.Errorf("failed to render image pull secret") + } + case "bootstrap-token-ocmhub": + data := object.StringData["token-secret"] + if len(data) != 16 { + t.Errorf("failed to get token secret") + } + } } } }) @@ -173,13 +205,13 @@ func TestKlusterletConfig(t *testing.T) { cases := []struct { name string namespace string - chartConfig func() *klusterletchart.ChartConfig + chartConfig func() *KlusterletChartConfig expectedObjCnt int }{ { name: "default config", namespace: "open-cluster-management", - chartConfig: func() *klusterletchart.ChartConfig { + chartConfig: func() *KlusterletChartConfig { config := NewDefaultKlusterletChartConfig() config.Klusterlet.ClusterName = "testCluster" config.Klusterlet.Mode = operatorv1.InstallModeSingleton @@ -190,7 +222,7 @@ func TestKlusterletConfig(t *testing.T) { { name: "use bootstrapHubKubeConfig", namespace: "open-cluster-management", - chartConfig: func() *klusterletchart.ChartConfig { + chartConfig: func() *KlusterletChartConfig { config := NewDefaultKlusterletChartConfig() config.Klusterlet.ClusterName = "testCluster" config.Klusterlet.Mode = operatorv1.InstallModeSingleton @@ -203,13 +235,13 @@ func TestKlusterletConfig(t *testing.T) { { name: "change images config", namespace: "ocm", - chartConfig: func() *klusterletchart.ChartConfig { + chartConfig: func() *KlusterletChartConfig { config := NewDefaultKlusterletChartConfig() - config.Images = klusterletchart.ImagesConfig{ + config.Images = ImagesConfig{ Registry: "myrepo", Tag: "v9.9.9", ImagePullPolicy: corev1.PullAlways, - ImageCredentials: klusterletchart.ImageCredentials{ + ImageCredentials: ImageCredentials{ CreateImageCredentials: true, UserName: "test", Password: "test", @@ -224,7 +256,7 @@ func TestKlusterletConfig(t *testing.T) { { name: "hosted mode", namespace: "ocm", - chartConfig: func() *klusterletchart.ChartConfig { + chartConfig: func() *KlusterletChartConfig { config := NewDefaultKlusterletChartConfig() config.NoOperator = true config.Klusterlet.Name = "klusterlet2" @@ -237,7 +269,7 @@ func TestKlusterletConfig(t *testing.T) { { name: "noOperator", namespace: "ocm", - chartConfig: func() *klusterletchart.ChartConfig { + chartConfig: func() *KlusterletChartConfig { config := NewDefaultKlusterletChartConfig() config.NoOperator = true config.Klusterlet.Name = "klusterlet2" @@ -250,7 +282,7 @@ func TestKlusterletConfig(t *testing.T) { { name: "create namespace", namespace: "open-cluster-management", - chartConfig: func() *klusterletchart.ChartConfig { + chartConfig: func() *KlusterletChartConfig { config := NewDefaultKlusterletChartConfig() config.Klusterlet.ClusterName = "testCluster" config.Klusterlet.Mode = operatorv1.InstallModeSingleton @@ -359,6 +391,22 @@ func TestKlusterletConfig(t *testing.T) { fmt.Sprintf("open-cluster-management-%s", object.Spec.ClusterName), object.Spec.Namespace) } } + case *corev1.Secret: + switch object.Name { + case "open-cluster-management-image-pull-credentials": + data := object.Data[corev1.DockerConfigJsonKey] + if len(data) == 0 { + t.Errorf("failed to get image pull secret") + } + if base64.StdEncoding.EncodeToString(data) == "" { + t.Errorf("failed to render image pull secret") + } + case "bootstrap-hub-kubeconfig", "external-managed-kubeconfig": + data := object.Data["kubeconfig"] + if base64.StdEncoding.EncodeToString(data) == "" { + t.Errorf("failed to render kubeconfig") + } + } } } }) diff --git a/test/e2e-test.mk b/test/e2e-test.mk index b56306fdd..2aa460c00 100644 --- a/test/e2e-test.mk +++ b/test/e2e-test.mk @@ -18,7 +18,10 @@ endif hub-kubeconfig: $(KUBECTL) config view --minify --flatten > $(HUB_KUBECONFIG) -deploy-hub: deploy-hub-operator apply-hub-cr hub-kubeconfig cluster-ip +deploy-hub: deploy-hub-helm hub-kubeconfig cluster-ip + +deploy-hub-helm: ensure-helm + $(HELM) install cluster-manager deploy/cluster-manager/chart/cluster-manager --namespace=open-cluster-management --create-namespace --set images.registry=$(IMAGE_REGISTRY),image.tag=$(IMAGE_TAG) deploy-hub-operator: ensure-kustomize cp deploy/cluster-manager/config/kustomization.yaml deploy/cluster-manager/config/kustomization.yaml.tmp @@ -29,7 +32,7 @@ deploy-hub-operator: ensure-kustomize apply-hub-cr: $(SED_CMD) -e "s,quay.io/open-cluster-management/registration:latest,$(REGISTRATION_IMAGE)," -e "s,quay.io/open-cluster-management/work:latest,$(WORK_IMAGE)," -e "s,quay.io/open-cluster-management/placement:latest,$(PLACEMENT_IMAGE)," -e "s,quay.io/open-cluster-management/addon-manager:latest,$(ADDON_MANAGER_IMAGE)," deploy/cluster-manager/config/samples/operator_open-cluster-management_clustermanagers.cr.yaml | $(KUBECTL) apply -f - -test-e2e: deploy-hub deploy-spoke-operator bootstrap-secret run-e2e +test-e2e: deploy-hub deploy-spoke-operator-helm run-e2e run-e2e: go test -c ./test/e2e @@ -52,6 +55,9 @@ bootstrap-secret: $(KUBECTL) get ns open-cluster-management-agent; if [ $$? -ne 0 ] ; then $(KUBECTL) create ns open-cluster-management-agent; fi $(KUSTOMIZE) build deploy/klusterlet/config/samples/bootstrap | $(KUBECTL) apply -f - +deploy-spoke-operator-helm: ensure-helm + $(HELM) install klusterlet deploy/klusterlet/chart/klusterlet --namespace=open-cluster-management --set klusterlet.create=false,images.registry=$(IMAGE_REGISTRY),image.tag=$(IMAGE_TAG) --set-file bootstrapHubKubeConfig=$(HUB_KUBECONFIG) + deploy-spoke-operator: ensure-kustomize cp deploy/klusterlet/config/kustomization.yaml deploy/klusterlet/config/kustomization.yaml.tmp cd deploy/klusterlet/config && ../../../$(KUSTOMIZE) edit set image quay.io/open-cluster-management/registration-operator:latest=$(OPERATOR_IMAGE_NAME)