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 }