diff --git a/controllers/backplaneconfig_controller_test.go b/controllers/backplaneconfig_controller_test.go index e365992bf..1ecc3f42e 100644 --- a/controllers/backplaneconfig_controller_test.go +++ b/controllers/backplaneconfig_controller_test.go @@ -77,6 +77,7 @@ var _ = Describe("BackplaneConfig controller", func() { hiveConfig *unstructured.Unstructured clusterManagementAddon *unstructured.Unstructured addonTemplate *unstructured.Unstructured + addonDeploymentConfig *unstructured.Unstructured tests testList msaTests testList secondTests testList @@ -199,6 +200,13 @@ var _ = Describe("BackplaneConfig controller", func() { Kind: "AddOnTemplate", }) + addonDeploymentConfig = &unstructured.Unstructured{} + addonDeploymentConfig.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "addon.open-cluster-management.io", + Version: "v1alpha1", + Kind: "AddOnDeploymentConfig", + }) + tests = testList{ { Name: BackplaneConfigTestName, @@ -311,6 +319,14 @@ var _ = Describe("BackplaneConfig controller", func() { } msaTests = testList{ + { + Name: "Managed-ServiceAccount Addon Deployment Config", + NamespacedName: types.NamespacedName{ + Name: "managed-serviceaccount-addon-deploy-config", + Namespace: DestinationNamespace}, + ResourceType: addonDeploymentConfig, + Expected: nil, + }, { Name: "Managed-ServiceAccount Addon Template", NamespacedName: types.NamespacedName{Name: "managed-serviceaccount"}, diff --git a/hack/bundle-automation/charts-config.yaml b/hack/bundle-automation/charts-config.yaml index a9cde275b..f60186689 100644 --- a/hack/bundle-automation/charts-config.yaml +++ b/hack/bundle-automation/charts-config.yaml @@ -15,3 +15,4 @@ escape-template-variables: - "CLUSTER_NAME" - "HUB_KUBECONFIG" + - "INSTALL_NAMESPACE" diff --git a/hack/bundle-automation/generate-charts.py b/hack/bundle-automation/generate-charts.py index 0686714ae..34c7f4e9a 100755 --- a/hack/bundle-automation/generate-charts.py +++ b/hack/bundle-automation/generate-charts.py @@ -56,6 +56,26 @@ def parse_image_ref(image_ref): return parsed_ref + +def updateAddOnDeploymentConfig(yamlContent): + yamlContent['metadata']['namespace'] = '{{ .Values.global.namespace }}' + + +def updateClusterManagementAddOn(yamlContent): + if 'spec' not in yamlContent: + return + if 'supportedConfigs' not in yamlContent['spec']: + return + supportedConfigs = yamlContent['spec']['supportedConfigs'] + for config in supportedConfigs: + if 'defaultConfig' not in config: + continue + defaultConfig = config['defaultConfig'] + if 'namespace' not in defaultConfig: + continue + defaultConfig['namespace'] = '{{ .Values.global.namespace }}' + + def updateServiceAccount(yamlContent): yamlContent['metadata'].pop('namespace') @@ -95,7 +115,13 @@ def updateResources(outputDir, repo, chart): with open(filePath, 'r') as f: yamlContent = yaml.safe_load(f) kind = yamlContent["kind"] - if kind == "ServiceAccount": + if kind == "AddOnDeploymentConfig": + logging.info(" Updating AddOnDeploymentConfig!") + updateAddOnDeploymentConfig(yamlContent) + elif kind == "ClusterManagementAddOn": + logging.info(" Updating ClusterManagementAddOn!") + updateClusterManagementAddOn(yamlContent) + elif kind == "ServiceAccount": logging.info(" Updating ServiceAccount!") updateServiceAccount(yamlContent) elif kind == "ClusterRoleBinding": diff --git a/hack/unit-test-crds/addondeploymentconfigs.yaml b/hack/unit-test-crds/addondeploymentconfigs.yaml index c351b83f3..a88763c58 100644 --- a/hack/unit-test-crds/addondeploymentconfigs.yaml +++ b/hack/unit-test-crds/addondeploymentconfigs.yaml @@ -10,85 +10,165 @@ spec: listKind: AddOnDeploymentConfigList plural: addondeploymentconfigs singular: addondeploymentconfig - scope: Namespaced preserveUnknownFields: false + scope: Namespaced versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: AddOnDeploymentConfig represents a deployment configuration for an add-on. - type: object - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec represents a desired configuration for an add-on. - type: object - properties: - customizedVariables: - description: CustomizedVariables is a list of name-value variables for the current add-on deployment. The add-on implementation can use these variables to render its add-on deployment. The default is an empty list. - type: array - items: - description: CustomizedVariable represents a customized variable for add-on deployment. - type: object - required: - - name - properties: - name: - description: Name of this variable. - type: string - maxLength: 255 - pattern: ^[a-zA-Z_][_a-zA-Z0-9]*$ - value: - description: Value of this variable. - type: string - maxLength: 1024 - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - nodePlacement: - description: NodePlacement enables explicit control over the scheduling of the add-on agents on the managed cluster. All add-on agent pods are expected to comply with this node placement. If the placement is nil, the placement is not specified, it will be omitted. If the placement is an empty object, the placement will match all nodes and tolerate nothing. - type: object + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AddOnDeploymentConfig represents a deployment configuration for + an add-on. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec represents a desired configuration for an add-on. + properties: + agentInstallNamespace: + default: open-cluster-management-agent-addon + description: AgentInstallNamespace is the namespace where the add-on + agent should be installed on the managed cluster. + maxLength: 63 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + customizedVariables: + description: CustomizedVariables is a list of name-value variables + for the current add-on deployment. The add-on implementation can + use these variables to render its add-on deployment. The default + is an empty list. + items: + description: CustomizedVariable represents a customized variable + for add-on deployment. properties: - nodeSelector: - description: NodeSelector defines which Nodes the Pods are scheduled on. If the selector is an empty list, it will match all nodes. The default is an empty list. + name: + description: Name of this variable. + maxLength: 255 + pattern: ^[a-zA-Z_][_a-zA-Z0-9]*$ + type: string + value: + description: Value of this variable. + maxLength: 1024 + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodePlacement: + description: NodePlacement enables explicit control over the scheduling + of the add-on agents on the managed cluster. All add-on agent pods + are expected to comply with this node placement. If the placement + is nil, the placement is not specified, it will be omitted. If the + placement is an empty object, the placement will match all nodes + and tolerate nothing. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector defines which Nodes the Pods are scheduled + on. If the selector is an empty list, it will match all nodes. + The default is an empty list. + type: object + tolerations: + description: Tolerations is attached by pods to tolerate any taint + that matches the triple using the matching + operator . If the tolerations is an empty list, it + will tolerate nothing. The default is an empty list. + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string type: object - additionalProperties: - type: string - tolerations: - description: Tolerations is attached by pods to tolerate any taint that matches the triple using the matching operator . If the tolerations is an empty list, it will tolerate nothing. The default is an empty list. - type: array - items: - description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . - type: object - properties: - effect: - description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. - type: integer - format: int64 - value: - description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. - type: string - served: true - storage: true + type: array + type: object + proxyConfig: + description: ProxyConfig holds proxy settings for add-on agent on + the managed cluster. Empty means no proxy settings is available. + properties: + httpProxy: + description: HTTPProxy is the URL of the proxy for HTTP requests + type: string + httpsProxy: + description: HTTPSProxy is the URL of the proxy for HTTPS requests + type: string + noProxy: + description: NoProxy is a comma-separated list of hostnames and/or + CIDRs and/or IPs for which the proxy should not be used. + type: string + type: object + registries: + description: "Registries describes how to override images used by + the addon agent on the managed cluster. the following example will + override image \"quay.io/open-cluster-management/addon-agent\" to + \"quay.io/ocm/addon-agent\" when deploying the addon agent \n registries: + - source: quay.io/open-cluster-management/addon-agent mirror: quay.io/ocm/addon-agent" + items: + description: ImageMirror describes how to mirror images from a source + properties: + mirror: + description: Mirror is the mirrored registry of the Source. + Will be ignored if Mirror is empty. + type: string + source: + description: Source is the source registry. All image registries + will be replaced by Mirror if Source is empty. + type: string + required: + - mirror + type: object + type: array + type: object + type: object + served: true + storage: true status: acceptedNames: kind: "" plural: "" conditions: [] - storedVersions: [] \ No newline at end of file + storedVersions: [] diff --git a/hack/unit-test-crds/addontemplates.yaml b/hack/unit-test-crds/addontemplates.yaml index 029779ed6..a600497e9 100644 --- a/hack/unit-test-crds/addontemplates.yaml +++ b/hack/unit-test-crds/addontemplates.yaml @@ -385,38 +385,59 @@ spec: to bind the user provided ClusterRole/Role to the "system:open-cluster-management:cluster::addon:" Group. properties: - roleRef: - description: RoleRef is an reference to the permission - resource. it could be a role or a cluster role, - the user must make sure it exist on the hub cluster. + currentCluster: + description: CurrentCluster contains the configuration + of CurrentCluster type binding. It is required when + the type is CurrentCluster. properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced + clusterRoleName: + description: ClusterRoleName is the name of the + clusterrole the addon agent is bound. A rolebinding + will be created referring to this cluster role + in each cluster namespace. The user must make + sure the clusterrole exists on the hub cluster. type: string required: - - apiGroup - - kind - - name + - clusterRoleName type: object - x-kubernetes-map-type: atomic singleNamespace: description: SingleNamespace contains the configuration of SingleNamespace type binding. It is required when the type is SingleNamespace properties: namespace: + description: Namespace is the namespace the addon + agent has permissions to bind to. A rolebinding + will be created in this namespace referring + to the RoleRef. type: string + roleRef: + description: RoleRef is an reference to the permission + resource. it could be a role or a cluster role, + the user must make sure it exist on the hub + cluster. + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - apiGroup + - kind + - name + type: object + x-kubernetes-map-type: atomic required: - namespace + - roleRef type: object type: description: 'Type of the permissions setting. It @@ -430,7 +451,6 @@ spec: - SingleNamespace type: string required: - - roleRef - type type: object type: array diff --git a/pkg/rendering/renderer_test.go b/pkg/rendering/renderer_test.go index b887d3a20..48a06ec8d 100644 --- a/pkg/rendering/renderer_test.go +++ b/pkg/rendering/renderer_test.go @@ -171,7 +171,9 @@ func TestRender(t *testing.T) { containsHTTPS = false containsNO = false } - if template.GetKind() == "AddOnDeploymentConfig" { + if template.GetKind() == "AddOnDeploymentConfig" && + // managed service account addon deployment config does not need a node placement config + template.GetName() != "managed-serviceaccount-addon-deploy-config" { addonDep := &addonv1alpha1.AddOnDeploymentConfig{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(template.Object, addonDep) if err != nil { diff --git a/pkg/templates/charts/toggle/managed-serviceaccount/templates/addondeploymentconfig.yaml b/pkg/templates/charts/toggle/managed-serviceaccount/templates/addondeploymentconfig.yaml new file mode 100644 index 000000000..19cbbcc5e --- /dev/null +++ b/pkg/templates/charts/toggle/managed-serviceaccount/templates/addondeploymentconfig.yaml @@ -0,0 +1,7 @@ +apiVersion: addon.open-cluster-management.io/v1alpha1 +kind: AddOnDeploymentConfig +metadata: + name: managed-serviceaccount-addon-deploy-config + namespace: '{{ .Values.global.namespace }}' +spec: + agentInstallNamespace: open-cluster-management-agent-addon diff --git a/pkg/templates/charts/toggle/managed-serviceaccount/templates/addontemplate.yaml b/pkg/templates/charts/toggle/managed-serviceaccount/templates/addontemplate.yaml index 4d065dc21..4f0542e64 100644 --- a/pkg/templates/charts/toggle/managed-serviceaccount/templates/addontemplate.yaml +++ b/pkg/templates/charts/toggle/managed-serviceaccount/templates/addontemplate.yaml @@ -7,6 +7,12 @@ spec: agentSpec: workload: manifests: + - apiVersion: v1 + kind: Namespace + metadata: + annotations: + addon.open-cluster-management.io/deletion-orphan: '' + name: '{{ `{{INSTALL_NAMESPACE}}` }}' - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -127,9 +133,7 @@ spec: registration: - kubeClient: hubPermissions: - - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: managed-serviceaccount-addon-agent + - currentCluster: + clusterRoleName: managed-serviceaccount-addon-agent type: CurrentCluster type: KubeClient diff --git a/pkg/templates/charts/toggle/managed-serviceaccount/templates/clustermanagementaddon.yaml b/pkg/templates/charts/toggle/managed-serviceaccount/templates/clustermanagementaddon.yaml index 366f7b99f..0c42cd218 100644 --- a/pkg/templates/charts/toggle/managed-serviceaccount/templates/clustermanagementaddon.yaml +++ b/pkg/templates/charts/toggle/managed-serviceaccount/templates/clustermanagementaddon.yaml @@ -1,23 +1,20 @@ - -# Source: managed-serviceaccount/templates/clustermanagementaddon.yaml apiVersion: addon.open-cluster-management.io/v1alpha1 kind: ClusterManagementAddOn metadata: - name: managed-serviceaccount annotations: - addon.open-cluster-management.io/lifecycle: "addon-manager" + addon.open-cluster-management.io/lifecycle: addon-manager + name: managed-serviceaccount spec: addOnMeta: - displayName: managed-serviceaccount description: managed-serviceaccount + displayName: managed-serviceaccount supportedConfigs: - - group: addon.open-cluster-management.io + - defaultConfig: + name: managed-serviceaccount-addon-deploy-config + namespace: '{{ .Values.global.namespace }}' + group: addon.open-cluster-management.io resource: addondeploymentconfigs -# TODO: uncomment when the agentInstallNamespace field is added to the ocm repo - # defaultConfig: - # namespace: default - # name: managed-serviceaccount-addon-deploy-config - - group: addon.open-cluster-management.io + - defaultConfig: + name: managed-serviceaccount-2.4 + group: addon.open-cluster-management.io resource: addontemplates - defaultConfig: - name: managed-serviceaccount-2.4 \ No newline at end of file