From 6710c9d93f1acb0362650146ee05dfeb79a40031 Mon Sep 17 00:00:00 2001 From: Damiano Donati Date: Wed, 14 Feb 2024 13:25:02 +0100 Subject: [PATCH] manifests-gen: store core capi crds in their own manifest Store Core CAPI CRDs in their own manifest to get them applied by CVO directly. We want these to be installed independently from whether the cluster-capi-operator is enabled, as other Openshift components rely on them. --- manifests-gen/customizations.go | 41 ++++++++++++++------------------- manifests-gen/providers.go | 29 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/manifests-gen/customizations.go b/manifests-gen/customizations.go index 8b3a95455..a35843954 100644 --- a/manifests-gen/customizations.go +++ b/manifests-gen/customizations.go @@ -18,11 +18,8 @@ import ( type resourceKey string const ( - crdKey resourceKey = "crds" - otherKey resourceKey = "other" - rbacKey resourceKey = "rbac" - deploymentKey resourceKey = "deployment" - serviceKey resourceKey = "service" + crdKey resourceKey = "crds" + otherKey resourceKey = "other" ) var ( @@ -46,11 +43,8 @@ var ( func processObjects(objs []unstructured.Unstructured, providerName string) map[resourceKey][]unstructured.Unstructured { resourceMap := map[resourceKey][]unstructured.Unstructured{} - finalObjs := []unstructured.Unstructured{} - rbacObjs := []unstructured.Unstructured{} + providerConfigMapObjs := []unstructured.Unstructured{} crdObjs := []unstructured.Unstructured{} - deploymentObjs := []unstructured.Unstructured{} - serviceObjs := []unstructured.Unstructured{} serviceSecretNames := findWebhookServiceSecretName(objs) @@ -60,9 +54,7 @@ func processObjects(objs []unstructured.Unstructured, providerName string) map[r case "ClusterRole", "Role", "ClusterRoleBinding", "RoleBinding", "ServiceAccount": setOpenShiftAnnotations(obj, false) setTechPreviewAnnotation(obj) - rbacObjs = append(rbacObjs, obj) - - finalObjs = append(finalObjs, obj) + providerConfigMapObjs = append(providerConfigMapObjs, obj) case "MutatingWebhookConfiguration": // Explicitly remove defaulting webhooks for the cluster-api provider. // We don't need CAPI to set any default to the cluster object because @@ -70,41 +62,42 @@ func processObjects(objs []unstructured.Unstructured, providerName string) map[r // For more information: https://issues.redhat.com/browse/OCPCLOUD-1506 removeClusterDefaultingWebhooks(&obj) replaceCertManagerAnnotations(&obj) - finalObjs = append(finalObjs, obj) + providerConfigMapObjs = append(providerConfigMapObjs, obj) case "ValidatingWebhookConfiguration": removeClusterValidatingWebhooks(&obj) replaceCertManagerAnnotations(&obj) - finalObjs = append(finalObjs, obj) + providerConfigMapObjs = append(providerConfigMapObjs, obj) case "CustomResourceDefinition": replaceCertManagerAnnotations(&obj) removeConversionWebhook(&obj) setOpenShiftAnnotations(obj, true) setTechPreviewAnnotation(obj) - crdObjs = append(crdObjs, obj) - finalObjs = append(finalObjs, obj) + // Store Core CAPI CRDs in their own manifest to get them applied by CVO directly. + // We want these to be installed independently from whether the cluster-capi-operator is enabled, + // as other Openshift components rely on them. + if providerName == coreCAPIProvider { + crdObjs = append(crdObjs, obj) + } else { + providerConfigMapObjs = append(providerConfigMapObjs, obj) + } case "Service": replaceCertMangerServiceSecret(&obj, serviceSecretNames) setOpenShiftAnnotations(obj, true) setTechPreviewAnnotation(obj) - serviceObjs = append(serviceObjs, obj) - finalObjs = append(finalObjs, obj) + providerConfigMapObjs = append(providerConfigMapObjs, obj) case "Deployment": customizeDeployments(&obj) if providerName == "operator" { setOpenShiftAnnotations(obj, false) setTechPreviewAnnotation(obj) } - deploymentObjs = append(deploymentObjs, obj) - finalObjs = append(finalObjs, obj) + providerConfigMapObjs = append(providerConfigMapObjs, obj) case "Certificate", "Issuer", "Namespace", "Secret": // skip } } - resourceMap[rbacKey] = rbacObjs resourceMap[crdKey] = crdObjs - resourceMap[deploymentKey] = deploymentObjs - resourceMap[serviceKey] = serviceObjs - resourceMap[otherKey] = finalObjs + resourceMap[otherKey] = providerConfigMapObjs return resourceMap } diff --git a/manifests-gen/providers.go b/manifests-gen/providers.go index 97abae275..b3f2587c7 100644 --- a/manifests-gen/providers.go +++ b/manifests-gen/providers.go @@ -20,6 +20,7 @@ import ( const ( powerVSProvider = "powervs" ibmCloudProvider = "ibmcloud" + coreCAPIProvider = "cluster-api" metadataFilePath = "./metadata.yaml" kustomizeComponentsPath = "./config/default" ) @@ -84,6 +85,23 @@ func (p *provider) providerTypeName() string { return strings.ReplaceAll(strings.ToLower(string(p.Type)), "provider", "") } +// writeProviderComponentsToManifest allows to write provider components directly to a manifest. +// This differs from writeProviderComponentsConfigmap as it won't store the components in a ConfigMap +// but directly on the YAML manifests as YAML representation of an unstructured objects. +func (p *provider) writeProviderComponentsToManifest(fileName string, objs []unstructured.Unstructured) error { + if len(objs) == 0 { + return nil + } + + combined, err := utilyaml.FromUnstructured(objs) + if err != nil { + return err + } + + return os.WriteFile(path.Join(*manifestsPath, fileName), ensureNewLine(combined), 0600) +} + +// writeProviderComponentsConfigmap allows to write provider components to the provider (transport) ConfigMap. func (p *provider) writeProviderComponentsConfigmap(fileName string, objs []unstructured.Unstructured) error { combined, err := utilyaml.FromUnstructured(objs) if err != nil { @@ -161,5 +179,16 @@ func importProvider(p provider) error { return fmt.Errorf("error writing provider ConfigMap: %w", err) } + // Optionally write a separate CRD manifest file, + // to apply CRDs directly via CVO rather than through the cluster-capi-operator, + // useful in cases where the platform is not supported but some CRDs are needed + // by other OCP operators other than the cluster-capi-operator. + if len(resourceMap[crdKey]) > 0 { + cmFileName := fmt.Sprintf("%s04_crd.%s-%s.yaml", manifestPrefix, strings.ToLower(p.providerTypeName()), p.Name) + if err := p.writeProviderComponentsToManifest(cmFileName, resourceMap[crdKey]); err != nil { + return fmt.Errorf("error writing provider CRDs: %w", err) + } + } + return nil }