Skip to content

Commit 22ed569

Browse files
feat: add support OCI repositories (#46)
* chore(#36): upgrade build submodule * feat(api): support OCI repo reference in `ProviderConfig` * chore: upgrade control-plane-operator to 0.1.17 * refactor: component version * feat: support OCIRepository resource * test: update check for OCIRepository * feat(helmrelease): update to `chartRef` * feat: skip workload cluster creation * feat: support OCIRepository secret ref + enable custom Deployment image location * feat(api): enhance ProviderConfig * fix(api): json struct tags and comments * feat: add pull secret discovery * fix(sample): providerconfig example * feat: implement `PlatfromSecret` component to sync Helm chart pull secrets in the platform cluster * feat: update crossplane instance reconciler * fix(api): linting errors * fix(controller): liniting errors * feat: add split helper function * feat: add oci prefix function * feat: handle OCI and DockerRef URL * chore: refactor utils functions * fix(bug): register reconciler * fix: adjust samples * doc: add comment * docs(api): add note for ProviderConfig helm chart URL * fix: providerconfig sample * docs: add more details on how the provider works * feat: release v0.1.0 * docs: refactor README * docs: fix phrasing * feat: swtich to controller-utils/pkg/image.ParseImage func * fix: tests
1 parent c604380 commit 22ed569

26 files changed

+1086
-270
lines changed

README.md

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,50 @@ spec:
4949
## 📖 Usage
5050
5151
### Configure a `ProviderConfig`
52-
A `ProviderConfig` is an API where you can configure the installation of a Crossplane instance in your `ManagedControlPlane`.
52+
A `ProviderConfig` is an API where you can configure an allow-list of Crossplane and provider installations in your `ManagedControlPlane`.
53+
The `ProviderConfig` is stored in the Platform cluster and therefore in the responsibility realm of the platform owner.
5354

5455
```yaml
5556
apiVersion: crossplane.services.openmcp.cloud/v1alpha1
5657
kind: ProviderConfig
5758
metadata:
5859
name: default
5960
spec:
60-
chart:
61-
repository: "https://charts.crossplane.io/stable"
62-
name: crossplane
63-
availableVersions:
64-
- v1.20.0
65-
- v1.19.0
66-
availableProviders:
67-
- name: provider-kubernetes
68-
package: xpkg.upbound.io/upbound/provider-kubernetes
69-
versions:
70-
- v0.16.0
61+
versions:
62+
- version: v2.0.2
63+
chart:
64+
url: "ghcr.io/openmcp-project/openmcp/charts/crossplane:2.0.2" # example OCI regsitry URL for Crosslane helm chart
65+
secretRef: # optional
66+
name: ghcr
67+
image:
68+
url: "xpkg.crossplane.io/crossplane/crossplane:2.0.2" # currently, upstream location but can be private registry as well
69+
secretRef:
70+
name: xyz # optional
71+
- version: v1.20.0
72+
chart:
73+
url: "ghcr.io/openmcp-project/openmcp/charts/crossplane:1.20.0" # example OCI regsitry URL for Crosslane helm chart
74+
secretRef: # optional
75+
name: ghcr
76+
image:
77+
url: "xpkg.crossplane.io/crossplane/crossplane:1.20.0" # currently, upstream location but can be private registry as well
78+
secretRef: # optional
79+
name: xyz
80+
81+
providers:
82+
availableProviders:
83+
- name: provider-kubernetes
84+
package: xpkg.upbound.io/upbound/provider-kubernetes
85+
versions:
86+
- v0.16.0
87+
- v0.15.0
88+
imagePullSecretRefs:
89+
- name: secretforprivateproviders
90+
- name: xyz
7191
```
7292

93+
The `ProviderConfig` allows you to specify secret references for private helm chart or image locations.
94+
NOTE: `ProvierConfig.spec.versions[].chart.url` needs to be image URL to an OCI registry.
95+
7396
### Install a Crossplane instance
7497

7598
```yaml
@@ -79,12 +102,15 @@ metadata:
79102
name: crossplane-sample
80103
namespace: default
81104
spec:
82-
version: v1.20.0
105+
version: v1.20.0 # allowed version from ProviderConfig
83106
providers:
84107
- name: provider-kubernetes
85-
version: v0.16.0
108+
version: v0.16.0 # allowed version from ProviderConfig
86109
```
87110

111+
## 📚 Documentation
112+
More documentation for the service-provider-crossplane can be found in the [docs](./docs) folder.
113+
88114
## 🧑‍💻 Development
89115

90116
### Building the binary locally

Taskfile.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ includes:
1010
CODE_DIRS: '{{.ROOT_DIR}}/cmd/... {{.ROOT_DIR}}/internal/... {{.ROOT_DIR}}/api/v1alpha1/... {{.ROOT_DIR}}/pkg/...'
1111
COMPONENTS: 'service-provider-crossplane'
1212
REPO_URL: 'https://github.com/openmcp-project/service-provider-crossplane'
13+
GENERATE_DOCS_INDEX: "true"
1314
CHART_COMPONENTS: "[]"
1415
CRDS_COMPONENTS: 'service-provider-crossplane'
1516
CRDS_PATH: '{{.ROOT_DIR}}/api/crds/manifests'

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.0.5-dev
1+
v0.1.0

api/crds/manifests/crossplane.services.openmcp.cloud_crossplanes.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.18.0
6+
controller-gen.kubebuilder.io/version: v0.19.0
77
labels:
88
openmcp.cloud/cluster: onboarding
99
name: crossplanes.crossplane.services.openmcp.cloud

api/crds/manifests/crossplane.services.openmcp.cloud_providerconfigs.yaml

Lines changed: 109 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.18.0
6+
controller-gen.kubebuilder.io/version: v0.19.0
77
labels:
88
openmcp.cloud/cluster: platform
99
name: providerconfigs.crossplane.services.openmcp.cloud
@@ -45,77 +45,125 @@ spec:
4545
spec:
4646
description: spec defines the desired state of ProviderConfig
4747
properties:
48-
availableProviders:
49-
description: AvailableProviders holds the list of providers that can
50-
be configured with the Service Provider Crossplane.
51-
items:
52-
description: AvailableCrossplaneProvider represents configuration
53-
for Crossplane providers in a ProviderConfig of the Service Provider
54-
Crossplane.
55-
properties:
56-
name:
57-
description: Name of the provider.
58-
type: string
59-
package:
60-
description: Package is the package name of the provider.
61-
type: string
62-
versions:
63-
description: Version of the provider to install.
64-
items:
65-
type: string
66-
type: array
67-
required:
68-
- name
69-
- package
70-
- versions
71-
type: object
72-
type: array
73-
chart:
74-
description: Optional custom Helm chart configuration.
48+
providers:
49+
description: Providers holds the configuration for Crossplane providers
50+
that can be installed via the Service Provider Crossplane.
7551
properties:
76-
availableVersions:
77-
description: AvailableVersions of the Helm chart.
52+
availableProviders:
53+
description: AvailableProviders holds the list of providers that
54+
can be configured with the Service Provider Crossplane.
7855
items:
79-
type: string
56+
description: AvailableCrossplaneProvider represents configuration
57+
for Crossplane providers in a ProviderConfig of the Service
58+
Provider Crossplane.
59+
properties:
60+
name:
61+
description: Name of the provider.
62+
type: string
63+
package:
64+
description: Package is the package name of the provider.
65+
type: string
66+
versions:
67+
description: Version of the provider to install.
68+
items:
69+
type: string
70+
type: array
71+
required:
72+
- name
73+
- package
74+
- versions
75+
type: object
76+
type: array
77+
imagePullSecretRefs:
78+
description: Image pull secrets for pulling Crossplane provider
79+
images from private OCI registries.
80+
items:
81+
description: LocalObjectReference is a reference to an object
82+
in the same namespace as the resource referencing it.
83+
properties:
84+
name:
85+
default: ""
86+
description: |-
87+
Name of the referent.
88+
This field is effectively required, but due to backwards compatibility is
89+
allowed to be empty. Instances of this type with an empty value here are
90+
almost certainly wrong.
91+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
92+
type: string
93+
type: object
94+
x-kubernetes-map-type: atomic
8095
type: array
81-
name:
82-
description: Name of the Helm chart.
83-
type: string
84-
repository:
85-
description: Repository is the URL to a Helm repository.
86-
type: string
8796
required:
88-
- availableVersions
89-
- name
90-
- repository
97+
- availableProviders
9198
type: object
92-
imageMapping:
93-
additionalProperties:
94-
type: string
95-
description: ImageMapping holds the information about exchangable
96-
image locations in the Helm chart.
97-
type: object
98-
imagePullSecrets:
99-
description: Image pull secrets for Crossplane pods
99+
versions:
100100
items:
101-
description: LocalObjectReference is a reference to an object in
102-
the same namespace as the resource referencing it.
101+
description: CrossplaneVersion defines a specific version of Crossplane
102+
along with its chart and image information.
103103
properties:
104-
name:
105-
default: ""
106-
description: |-
107-
Name of the referent.
108-
This field is effectively required, but due to backwards compatibility is
109-
allowed to be empty. Instances of this type with an empty value here are
110-
almost certainly wrong.
111-
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
104+
chart:
105+
description: Chart holds the Helm chart information for this
106+
Crossplane version.
107+
properties:
108+
secretRef:
109+
description: SecretRef references a secret containing credentials
110+
to access the OCI artifact repository.
111+
properties:
112+
name:
113+
default: ""
114+
description: |-
115+
Name of the referent.
116+
This field is effectively required, but due to backwards compatibility is
117+
allowed to be empty. Instances of this type with an empty value here are
118+
almost certainly wrong.
119+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
120+
type: string
121+
type: object
122+
x-kubernetes-map-type: atomic
123+
url:
124+
description: |-
125+
URL is a reference to an OCI artifact repository hosted on a remote container registry where the Helm chart is stored.
126+
The URL must NOT start with "oci://".
127+
type: string
128+
required:
129+
- url
130+
type: object
131+
image:
132+
description: Image holds the Crossplane controller image information
133+
for this Crossplane version.
134+
properties:
135+
secretRef:
136+
description: SecretRef references a secret containing credentials
137+
to access the container image repository.
138+
properties:
139+
name:
140+
default: ""
141+
description: |-
142+
Name of the referent.
143+
This field is effectively required, but due to backwards compatibility is
144+
allowed to be empty. Instances of this type with an empty value here are
145+
almost certainly wrong.
146+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
147+
type: string
148+
type: object
149+
x-kubernetes-map-type: atomic
150+
url:
151+
description: URL is a reference to the container image location.
152+
type: string
153+
required:
154+
- url
155+
type: object
156+
version:
157+
description: Version of Crossplane.
112158
type: string
159+
required:
160+
- chart
161+
- image
162+
- version
113163
type: object
114-
x-kubernetes-map-type: atomic
115164
type: array
116165
required:
117-
- availableProviders
118-
- chart
166+
- versions
119167
type: object
120168
status:
121169
description: status defines the observed state of ProviderConfig

api/v1alpha1/providerconfig_types.go

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,38 +36,62 @@ type AvailableCrossplaneProvider struct {
3636
Package string `json:"package"`
3737
}
3838

39-
// ChartSpec identifies a Helm chart.
40-
type ChartSpec struct {
41-
// Repository is the URL to a Helm repository.
39+
// CrossplaneProviders represents the configutation of Crossplane providers and and their image pull secrets.
40+
type CrossplaneProviders struct {
41+
// AvailableProviders holds the list of providers that can be configured with the Service Provider Crossplane.
4242
// +kubebuilder:validation:Required
43-
Repository string `json:"repository"`
43+
AvailableProviders []AvailableCrossplaneProvider `json:"availableProviders"`
4444

45-
// Name of the Helm chart.
46-
// +kubebuilder:validation:Required
47-
Name string `json:"name"`
45+
// Image pull secrets for pulling Crossplane provider images from private OCI registries.
46+
// +kubebuilder:validation:Optional
47+
ImagePullSecrets []commonapi.LocalObjectReference `json:"imagePullSecretRefs,omitempty"`
48+
}
4849

49-
// AvailableVersions of the Helm chart.
50+
// ChartSpec defines the location and access of a Helm chart.
51+
type ChartSpec struct {
52+
// URL is a reference to an OCI artifact repository hosted on a remote container registry where the Helm chart is stored.
53+
// The URL must NOT start with "oci://".
5054
// +kubebuilder:validation:Required
51-
AvailableVersions []string `json:"availableVersions"`
55+
URL string `json:"url"`
56+
57+
// SecretRef references a secret containing credentials to access the OCI artifact repository.
58+
// +kubebuilder:validation:Optional
59+
SecretRef commonapi.LocalObjectReference `json:"secretRef,omitempty"`
5260
}
5361

54-
// ProviderConfigSpec defines the desired state of ProviderConfig.
55-
type ProviderConfigSpec struct {
56-
// Optional custom Helm chart configuration.
62+
// ImageSpec defines the location and access a container image.
63+
type ImageSpec struct {
64+
// URL is a reference to the container image location.
5765
// +kubebuilder:validation:Required
58-
Chart ChartSpec `json:"chart"`
66+
URL string `json:"url"`
5967

60-
// ImageMapping holds the information about exchangable image locations in the Helm chart.
68+
// SecretRef references a secret containing credentials to access the container image repository.
6169
// +kubebuilder:validation:Optional
62-
ImageMapping map[string]string `json:"imageMapping,omitempty"`
70+
SecretRef commonapi.LocalObjectReference `json:"secretRef,omitempty"`
71+
}
6372

64-
// AvailableProviders holds the list of providers that can be configured with the Service Provider Crossplane.
73+
// CrossplaneVersion defines a specific version of Crossplane along with its chart and image information.
74+
type CrossplaneVersion struct {
75+
// Version of Crossplane.
6576
// +kubebuilder:validation:Required
66-
AvailableProviders []AvailableCrossplaneProvider `json:"availableProviders"`
77+
Version string `json:"version"`
78+
79+
// Chart holds the Helm chart information for this Crossplane version.
80+
// +kubebuilder:validation:Required
81+
Chart ChartSpec `json:"chart"`
82+
83+
// Image holds the Crossplane controller image information for this Crossplane version.
84+
// +kubebuilder:validation:Required
85+
Image ImageSpec `json:"image"`
86+
}
87+
88+
// ProviderConfigSpec defines the desired state of ProviderConfig.
89+
type ProviderConfigSpec struct {
90+
CrossplaneVersions []CrossplaneVersion `json:"versions"`
6791

68-
// Image pull secrets for Crossplane pods
92+
// Providers holds the configuration for Crossplane providers that can be installed via the Service Provider Crossplane.
6993
// +kubebuilder:validation:Optional
70-
ImagePullSecrets []commonapi.LocalObjectReference `json:"imagePullSecrets,omitempty"`
94+
Providers CrossplaneProviders `json:"providers,omitempty"`
7195
}
7296

7397
// ProviderConfigStatus defines the observed state of ProviderConfig.

0 commit comments

Comments
 (0)