From 2dcfd701ffce31ceaea528577fce3a6513dc0457 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Tue, 14 Oct 2025 15:27:31 +0200 Subject: [PATCH 1/9] chore(#36): upgrade build submodule --- .../crossplane.services.openmcp.cloud_crossplanes.yaml | 2 +- .../crossplane.services.openmcp.cloud_providerconfigs.yaml | 2 +- hack/common | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/crds/manifests/crossplane.services.openmcp.cloud_crossplanes.yaml b/api/crds/manifests/crossplane.services.openmcp.cloud_crossplanes.yaml index 7ea9eac..5661a8c 100644 --- a/api/crds/manifests/crossplane.services.openmcp.cloud_crossplanes.yaml +++ b/api/crds/manifests/crossplane.services.openmcp.cloud_crossplanes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.19.0 labels: openmcp.cloud/cluster: onboarding name: crossplanes.crossplane.services.openmcp.cloud diff --git a/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml b/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml index 88f7d0c..ac8e619 100644 --- a/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml +++ b/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.18.0 + controller-gen.kubebuilder.io/version: v0.19.0 labels: openmcp.cloud/cluster: platform name: providerconfigs.crossplane.services.openmcp.cloud diff --git a/hack/common b/hack/common index 3dc4c78..5ffe5c0 160000 --- a/hack/common +++ b/hack/common @@ -1 +1 @@ -Subproject commit 3dc4c7899d658b099bf4c7b9575d34560b68a5bb +Subproject commit 5ffe5c0dd747e62fd80cb2dc7ba93fd724084c9c From 01042ad11da417e51dc7035fa78460616201a0ea Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Tue, 14 Oct 2025 15:28:27 +0200 Subject: [PATCH 2/9] feat(api): support OCI repo reference in `ProviderConfig` --- ...splane.services.openmcp.cloud_providerconfigs.yaml | 11 ++++------- api/v1alpha1/providerconfig_types.go | 8 ++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml b/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml index ac8e619..1298d97 100644 --- a/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml +++ b/api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml @@ -78,16 +78,13 @@ spec: items: type: string type: array - name: - description: Name of the Helm chart. - type: string - repository: - description: Repository is the URL to a Helm repository. + url: + description: URL is a reference to an OCI artifact repository + hosted on a remote container registry. type: string required: - availableVersions - - name - - repository + - url type: object imageMapping: additionalProperties: diff --git a/api/v1alpha1/providerconfig_types.go b/api/v1alpha1/providerconfig_types.go index 166a6c0..ed5c6f8 100644 --- a/api/v1alpha1/providerconfig_types.go +++ b/api/v1alpha1/providerconfig_types.go @@ -38,13 +38,9 @@ type AvailableCrossplaneProvider struct { // ChartSpec identifies a Helm chart. type ChartSpec struct { - // Repository is the URL to a Helm repository. + // URL is a reference to an OCI artifact repository hosted on a remote container registry. // +kubebuilder:validation:Required - Repository string `json:"repository"` - - // Name of the Helm chart. - // +kubebuilder:validation:Required - Name string `json:"name"` + URL string `json:"url"` // AvailableVersions of the Helm chart. // +kubebuilder:validation:Required From 72a09976c1749f198d22b137d4d044362cd245b6 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Wed, 15 Oct 2025 15:55:11 +0200 Subject: [PATCH 3/9] chore: upgrade control-plane-operator to 0.1.17 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 60e97cd..63ae94e 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/fluxcd/pkg/apis/meta v1.13.0 github.com/fluxcd/source-controller/api v1.6.2 github.com/go-logr/logr v1.4.3 - github.com/openmcp-project/control-plane-operator v0.1.16 + github.com/openmcp-project/control-plane-operator v0.1.17 github.com/openmcp-project/controller-utils v0.22.0 github.com/openmcp-project/openmcp-operator/api v0.15.1 github.com/openmcp-project/openmcp-operator/lib v0.15.1 diff --git a/go.sum b/go.sum index e3306b4..fa96eb8 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,8 @@ github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE= github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/openmcp-project/control-plane-operator v0.1.16 h1:/KRQBc6F9QKjoDRUlWZHATYJvmURNkPUqkV18BfJKPo= -github.com/openmcp-project/control-plane-operator v0.1.16/go.mod h1:/4/Z7DeBYmhMXusXF/Uk0KjM4vjtRHTAZ7wFhzwOOX4= +github.com/openmcp-project/control-plane-operator v0.1.17 h1:9PIFhzw86hSTsVpKodvHoRap9oonXUbcXlZbzjvEyXE= +github.com/openmcp-project/control-plane-operator v0.1.17/go.mod h1:CjwEOqQWPPhyGXyJCaGu/cRjandTp48DK5qTG6JIfq4= github.com/openmcp-project/controller-utils v0.22.0 h1:kdWGds+LOyOaOuKqWZGsJUv17e78HCr5y3bJOMSkdqE= github.com/openmcp-project/controller-utils v0.22.0/go.mod h1:aIF4lk7agc+yCNRN5Oqg4BLlzRKsGixqwsGmxPoO5ak= github.com/openmcp-project/openmcp-operator/api v0.15.1 h1:xjVQG9zt+QGuSyhGCE0HV0ZCVS9KTX71JALoCUM4BRU= From 150b2650a2f2f3f0c2754d079bb4a780ea905860 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Wed, 15 Oct 2025 15:55:43 +0200 Subject: [PATCH 4/9] refactor: component version --- internal/controller/crossplane_controller.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/controller/crossplane_controller.go b/internal/controller/crossplane_controller.go index 9b9893c..416c8e4 100644 --- a/internal/controller/crossplane_controller.go +++ b/internal/controller/crossplane_controller.go @@ -427,9 +427,8 @@ func (r *CrossplaneReconciler) GetResolverFunc(providerConfig *v1alpha1.Provider for _, availableVersion := range providerConfig.Spec.Chart.AvailableVersions { if availableVersion == version { return v1beta1.ComponentVersion{ - HelmRepo: providerConfig.Spec.Chart.Repository, - HelmChart: providerConfig.Spec.Chart.Name, - Version: version, + OCIURL: providerConfig.Spec.Chart.URL, + Version: version, }, nil } } From afe5246c1d8602c3fbff333f6d16351736322509 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Wed, 15 Oct 2025 16:40:54 +0200 Subject: [PATCH 5/9] feat: support OCIRepository resource --- internal/controller/crossplane_controller.go | 4 ++-- pkg/component/crossplane_component.go | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/controller/crossplane_controller.go b/internal/controller/crossplane_controller.go index afe2cbb..9e4381f 100644 --- a/internal/controller/crossplane_controller.go +++ b/internal/controller/crossplane_controller.go @@ -463,8 +463,8 @@ func (r *CrossplaneReconciler) GetResolverFunc(providerConfig *v1alpha1.Provider for _, availableVersion := range providerConfig.Spec.Chart.AvailableVersions { if availableVersion == version { return v1beta1.ComponentVersion{ - OCIURL: providerConfig.Spec.Chart.URL, - Version: version, + OCIURL: providerConfig.Spec.Chart.URL, + Version: version, }, nil } } diff --git a/pkg/component/crossplane_component.go b/pkg/component/crossplane_component.go index 66cd89a..03df5b8 100644 --- a/pkg/component/crossplane_component.go +++ b/pkg/component/crossplane_component.go @@ -64,18 +64,18 @@ func (c *Crossplane) BuildSourceRepository(ctx context.Context) (fluxcd.SourceAd rfn := rcontext.VersionResolver(ctx) c.applyDefaultChartSpec(rfn) - repo := &sourcev1.HelmRepository{ + repo := &sourcev1.OCIRepository{ ObjectMeta: metav1.ObjectMeta{ Name: strings.ToLower(ComponentNameCrossplane), Namespace: rcontext.TenantNamespace(ctx), }, - Spec: sourcev1.HelmRepositorySpec{ - URL: c.ChartSpec.Repository, + Spec: sourcev1.OCIRepositorySpec{ + URL: c.ChartSpec.URL, Timeout: &metav1.Duration{Duration: 1 * time.Minute}, }, } - adapter := &fluxcd.HelmRepositoryAdapter{Source: repo} + adapter := &fluxcd.OCIRepositoryAdapter{Source: repo} adapter.ApplyDefaults() return adapter, nil } @@ -99,7 +99,7 @@ func (c *Crossplane) BuildManifesto(ctx context.Context) (fluxcd.Manifesto, erro Chart: c.ChartSpec.Name, Version: c.ChartSpec.Version, SourceRef: helmv2.CrossNamespaceObjectReference{ - Kind: "HelmRepository", + Kind: "OCIRepository", Name: strings.ToLower(ComponentNameCrossplane), }, }, From f36ce8a8e257e8d291ff94403174eac3d094c2b4 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Wed, 15 Oct 2025 16:44:22 +0200 Subject: [PATCH 6/9] test: update check for OCIRepository --- pkg/component/crossplane_component_test.go | 2 +- pkg/component/utils_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/component/crossplane_component_test.go b/pkg/component/crossplane_component_test.go index 7e1fcc7..ea29899 100644 --- a/pkg/component/crossplane_component_test.go +++ b/pkg/component/crossplane_component_test.go @@ -57,7 +57,7 @@ func Test_Crossplane(t *testing.T) { hasNamespace(CrossplaneNamespace), ), isFluxComponent( - returnsHelmRepo(), + returnsOCIRepository(), returnsHelmRelease( hasKubeconfigRef(), hasHelmValue(2, "replicas"), // custom value diff --git a/pkg/component/utils_test.go b/pkg/component/utils_test.go index 967a64d..0d30310 100644 --- a/pkg/component/utils_test.go +++ b/pkg/component/utils_test.go @@ -132,13 +132,13 @@ func isFluxComponent(additionalValidations ...fluxValidationFunc) validationFunc } } -func returnsHelmRepo() fluxValidationFunc { +func returnsOCIRepository() fluxValidationFunc { return func(t *testing.T, ctx context.Context, c fluxcd.FluxComponent) { s, err := c.BuildSourceRepository(ctx) assert.NoError(t, err) - h, ok := s.(*fluxcd.HelmRepositoryAdapter) - if !assert.True(t, ok, "not a HelmRepositoryAdapter") { + h, ok := s.(*fluxcd.OCIRepositoryAdapter) + if !assert.True(t, ok, "not a OCIRepositoryAdapter") { return } assert.NotNil(t, h.Source) From 3bd2a8ea64449f17b51d7a8d1da96847f3305ea4 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Mon, 20 Oct 2025 11:29:26 +0200 Subject: [PATCH 7/9] feat(helmrelease): update to `chartRef` --- pkg/component/crossplane_component.go | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/pkg/component/crossplane_component.go b/pkg/component/crossplane_component.go index 03df5b8..9561097 100644 --- a/pkg/component/crossplane_component.go +++ b/pkg/component/crossplane_component.go @@ -70,7 +70,10 @@ func (c *Crossplane) BuildSourceRepository(ctx context.Context) (fluxcd.SourceAd Namespace: rcontext.TenantNamespace(ctx), }, Spec: sourcev1.OCIRepositorySpec{ - URL: c.ChartSpec.URL, + URL: c.ChartSpec.URL, + Reference: &sourcev1.OCIRepositoryRef{ + Tag: c.ChartSpec.Version, + }, Timeout: &metav1.Duration{Duration: 1 * time.Minute}, }, } @@ -94,15 +97,9 @@ func (c *Crossplane) BuildManifesto(ctx context.Context) (fluxcd.Manifesto, erro Namespace: rcontext.TenantNamespace(ctx), }, Spec: helmv2.HelmReleaseSpec{ - Chart: &helmv2.HelmChartTemplate{ - Spec: helmv2.HelmChartTemplateSpec{ - Chart: c.ChartSpec.Name, - Version: c.ChartSpec.Version, - SourceRef: helmv2.CrossNamespaceObjectReference{ - Kind: "OCIRepository", - Name: strings.ToLower(ComponentNameCrossplane), - }, - }, + ChartRef: &helmv2.CrossNamespaceSourceReference{ + Kind: "OCIRepository", + Name: strings.ToLower(ComponentNameCrossplane), }, ReleaseName: CrossplaneRelease, TargetNamespace: CrossplaneNamespace, @@ -142,9 +139,8 @@ func (c *Crossplane) applyDefaultChartSpec(rfn v1beta1.VersionResolverFn) { if c.ChartSpec == nil { c.ChartSpec = &v1beta1.ChartSpec{ - Repository: comp.HelmRepo, - Name: comp.HelmChart, - Version: comp.Version, + URL: comp.OCIURL, + Version: comp.Version, } } } From 82ff104340bfefbc6e54f5a642d073935bb50842 Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Mon, 20 Oct 2025 13:57:10 +0200 Subject: [PATCH 8/9] feat: skip workload cluster creation --- internal/controller/crossplane_controller.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/controller/crossplane_controller.go b/internal/controller/crossplane_controller.go index 9e4381f..092dce0 100644 --- a/internal/controller/crossplane_controller.go +++ b/internal/controller/crossplane_controller.go @@ -414,7 +414,8 @@ func (r *CrossplaneReconciler) SetupWithManager(mgr ctrl.Manager) error { WithMCPScheme(scheme.MCP). WithRetryInterval(10 * time.Second). WithMCPPermissions(getMCPPermissions()). - WithMCPRoleRefs(getMCPRoleRefs()) + WithMCPRoleRefs(getMCPRoleRefs()). + SkipWorkloadCluster() // Initialize smart requeue store with sensible defaults: // - Min interval: 5 seconds (quick retry for transient issues) From da107726399de26d8d5382f306a8bc0c926826aa Mon Sep 17 00:00:00 2001 From: Maximilian Techritz Date: Mon, 20 Oct 2025 14:03:12 +0200 Subject: [PATCH 9/9] feat: support OCIRepository secret ref + enable custom Deployment image location --- pkg/component/crossplane_component.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/component/crossplane_component.go b/pkg/component/crossplane_component.go index 9561097..4314110 100644 --- a/pkg/component/crossplane_component.go +++ b/pkg/component/crossplane_component.go @@ -7,6 +7,7 @@ import ( "time" helmv2 "github.com/fluxcd/helm-controller/api/v2" + "github.com/fluxcd/pkg/apis/meta" sourcev1 "github.com/fluxcd/source-controller/api/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -75,6 +76,9 @@ func (c *Crossplane) BuildSourceRepository(ctx context.Context) (fluxcd.SourceAd Tag: c.ChartSpec.Version, }, Timeout: &metav1.Duration{Duration: 1 * time.Minute}, + SecretRef: &meta.LocalObjectReference{ + Name: c.ImagePullSecretNames[0], // always use the first secret for OCI auth + }, }, } @@ -161,6 +165,11 @@ func (c *Crossplane) applyDefaultValues() error { // Add imagePullSecrets if provided in ProviderConfig spec values["imagePullSecrets"] = c.ImagePullSecretNames + // Pull Deployment image from specified chart URL provided in ProviderConfig spec + values["image"] = map[string]any{ + "repository": c.ChartSpec.URL, + } + // Write updated values encoded, err := json.Marshal(values) c.Values = &apiextensionsv1.JSON{Raw: encoded}