@@ -19,6 +19,7 @@ package cmd
19
19
import (
20
20
"context"
21
21
"fmt"
22
+ "net/url"
22
23
"os"
23
24
"strings"
24
25
@@ -44,7 +45,7 @@ type loadOptions struct {
44
45
runtimeExtensionProviders []string
45
46
addonProviders []string
46
47
targetNamespace string
47
- ociURL string
48
+ artifactURL string
48
49
kubeconfig string
49
50
existing bool
50
51
}
@@ -67,6 +68,9 @@ var loadCmd = &cobra.Command{
67
68
Alternatively, for multi-provider OCI artifact, a fully specified name can be used for both metadata and components:
68
69
69
70
oras push ttl.sh/infrastructure-provider:tag infrastructure-docker-v1.10.0-beta.0-metadata.yaml infrastructure-docker-v1.10.0-beta.0-components.yaml
71
+
72
+ If you want to use a GitHub or GitLab release as artifact source, you must provide a full URL, including scheme, host, path, version and file name, e.g.: https://github.com/kubernetes-sigs/cluster-api/releases/v1.10.5/core-components.yaml
73
+ In this case, the version is set in the URL, and cannot be specified with the provider argument.
70
74
` ),
71
75
Example : Examples (`
72
76
# Load CAPI operator manifests from OCI source
@@ -78,12 +82,21 @@ var loadCmd = &cobra.Command{
78
82
# Prepare provider ConfigMap from OCI, from the given infrastructure provider.
79
83
capioperator preload --infrastructure=aws -u ttl.sh/infrastructure-provider
80
84
85
+ # Prepare provider ConfigMap from GitHub release, from the given infrastructure provider.
86
+ capioperator preload --infrastructure=aws -u https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/v2.9.1/infrastructure-components.yaml
87
+
81
88
# Prepare provider ConfigMap from OCI with a specific version of the given infrastructure provider in the default namespace.
82
89
capioperator preload --infrastructure=aws::v2.3.0 -u ttl.sh/infrastructure-provider
83
90
91
+ # Prepare provider ConfigMap from GitHub release with a specific version of the given infrastructure provider in the default namespace.
92
+ capioperator preload --infrastructure=aws -u https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/v2.3.0/infrastructure-components.yaml
93
+
84
94
# Prepare provider ConfigMap from OCI with a specific namespace and the latest version of the given infrastructure provider.
85
95
capioperator preload --infrastructure=aws:custom-namespace -u ttl.sh/infrastructure-provider
86
96
97
+ # Prepare provider ConfigMap from GitHub release, with a specific namespace.
98
+ capioperator preload --infrastructure=aws:custom-namespace -u https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/v2.9.1/infrastructure-components.yaml
99
+
87
100
# Prepare provider ConfigMap from OCI with a specific version and namespace of the given infrastructure provider.
88
101
capioperator preload --infrastructure=aws:custom-namespace:v2.3.0 -u ttl.sh/infrastructure-provider
89
102
@@ -119,24 +132,24 @@ func init() {
119
132
"Add-on providers and versions (e.g. helm:v0.1.0) to add to the management cluster." )
120
133
loadCmd .Flags ().StringVarP (& loadOpts .targetNamespace , "target-namespace" , "n" , "capi-operator-system" ,
121
134
"The target namespace where the operator should be deployed. If unspecified, the 'capi-operator-system' namespace is used." )
122
- loadCmd .Flags ().StringVarP (& loadOpts .ociURL , "artifact-url" , "u" , "" ,
123
- "The URL of the OCI artifact to collect component manifests from." )
135
+ loadCmd .Flags ().StringVarP (& loadOpts .artifactURL , "artifact-url" , "u" , "" ,
136
+ "The URL to OCI artifact or GitHub/GitLab release, to collect component manifests from." )
124
137
125
138
RootCmd .AddCommand (loadCmd )
126
139
}
127
140
128
141
func runPreLoad () error {
129
142
ctx := context .Background ()
130
143
131
- if loadOpts .ociURL == "" {
144
+ if loadOpts .artifactURL == "" {
132
145
return fmt .Errorf ("missing configMap artifacts url" )
133
146
}
134
147
135
148
configMaps := []* corev1.ConfigMap {}
136
149
137
150
// Load Core Provider.
138
151
if loadOpts .coreProvider != "" {
139
- configMap , err := templateConfigMap (ctx , clusterctlv1 .CoreProviderType , loadOpts .ociURL , loadOpts .coreProvider , loadOpts .targetNamespace )
152
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .CoreProviderType , loadOpts .artifactURL , loadOpts .coreProvider , loadOpts .targetNamespace )
140
153
141
154
if err != nil {
142
155
return fmt .Errorf ("cannot prepare manifests config map for core provider: %w" , err )
@@ -147,7 +160,7 @@ func runPreLoad() error {
147
160
148
161
// Load Bootstrap Providers.
149
162
for _ , bootstrapProvider := range loadOpts .bootstrapProviders {
150
- configMap , err := templateConfigMap (ctx , clusterctlv1 .BootstrapProviderType , loadOpts .ociURL , bootstrapProvider , loadOpts .targetNamespace )
163
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .BootstrapProviderType , loadOpts .artifactURL , bootstrapProvider , loadOpts .targetNamespace )
151
164
if err != nil {
152
165
return fmt .Errorf ("cannot prepare manifests config map for bootstrap provider: %w" , err )
153
166
}
@@ -157,7 +170,7 @@ func runPreLoad() error {
157
170
158
171
// Load Infrastructure Providers.
159
172
for _ , infrastructureProvider := range loadOpts .infrastructureProviders {
160
- configMap , err := templateConfigMap (ctx , clusterctlv1 .InfrastructureProviderType , loadOpts .ociURL , infrastructureProvider , loadOpts .targetNamespace )
173
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .InfrastructureProviderType , loadOpts .artifactURL , infrastructureProvider , loadOpts .targetNamespace )
161
174
if err != nil {
162
175
return fmt .Errorf ("cannot prepare manifests config map for infrastructure provider: %w" , err )
163
176
}
@@ -167,7 +180,7 @@ func runPreLoad() error {
167
180
168
181
// Load Control Plane Providers.
169
182
for _ , controlPlaneProvider := range loadOpts .controlPlaneProviders {
170
- configMap , err := templateConfigMap (ctx , clusterctlv1 .ControlPlaneProviderType , loadOpts .ociURL , controlPlaneProvider , loadOpts .targetNamespace )
183
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .ControlPlaneProviderType , loadOpts .artifactURL , controlPlaneProvider , loadOpts .targetNamespace )
171
184
if err != nil {
172
185
return fmt .Errorf ("cannot prepare manifests config map for controlplane provider: %w" , err )
173
186
}
@@ -177,7 +190,7 @@ func runPreLoad() error {
177
190
178
191
// Load Add-on Providers.
179
192
for _ , addonProvider := range loadOpts .addonProviders {
180
- configMap , err := templateConfigMap (ctx , clusterctlv1 .AddonProviderType , loadOpts .ociURL , addonProvider , loadOpts .targetNamespace )
193
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .AddonProviderType , loadOpts .artifactURL , addonProvider , loadOpts .targetNamespace )
181
194
if err != nil {
182
195
return fmt .Errorf ("cannot prepare manifests config map for addon provider: %w" , err )
183
196
}
@@ -187,7 +200,7 @@ func runPreLoad() error {
187
200
188
201
// Load IPAM Providers.
189
202
for _ , ipamProvider := range loadOpts .ipamProviders {
190
- configMap , err := templateConfigMap (ctx , clusterctlv1 .IPAMProviderType , loadOpts .ociURL , ipamProvider , loadOpts .targetNamespace )
203
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .IPAMProviderType , loadOpts .artifactURL , ipamProvider , loadOpts .targetNamespace )
191
204
if err != nil {
192
205
return fmt .Errorf ("cannot prepare manifests config map for IPAM provider: %w" , err )
193
206
}
@@ -197,7 +210,7 @@ func runPreLoad() error {
197
210
198
211
// Load Runtime Extension Providers.
199
212
for _ , runtimeExtension := range loadOpts .runtimeExtensionProviders {
200
- configMap , err := templateConfigMap (ctx , clusterctlv1 .RuntimeExtensionProviderType , loadOpts .ociURL , runtimeExtension , loadOpts .targetNamespace )
213
+ configMap , err := templateConfigMap (ctx , clusterctlv1 .RuntimeExtensionProviderType , loadOpts .artifactURL , runtimeExtension , loadOpts .targetNamespace )
201
214
if err != nil {
202
215
return fmt .Errorf ("cannot prepare manifests config map for runtime extension provider: %w" , err )
203
216
}
@@ -289,16 +302,37 @@ func fetchProviders(ctx context.Context, cl client.Client, providerList genericP
289
302
return configMaps , nil
290
303
}
291
304
292
- func templateConfigMap (ctx context.Context , providerType clusterctlv1.ProviderType , url , providerInput , defaultNamespace string ) (* corev1.ConfigMap , error ) {
305
+ func templateConfigMap (ctx context.Context , providerType clusterctlv1.ProviderType , providerURL , providerInput , defaultNamespace string ) (* corev1.ConfigMap , error ) {
293
306
provider , err := templateGenericProvider (providerType , providerInput , defaultNamespace , "" , "" )
294
307
if err != nil {
295
308
return nil , err
296
309
}
297
310
298
311
spec := provider .GetSpec ()
312
+
313
+ parsedURL , err := url .Parse (providerURL )
314
+ if err != nil {
315
+ return nil , fmt .Errorf ("invalid artifact URL: %w" , err )
316
+ }
317
+
318
+ if util .IsGitHubDomain (parsedURL ) || util .IsGitLabDomain (parsedURL ) {
319
+ // artifact URL referes to a GitHub/GitLab release.
320
+ if spec .Version != "" {
321
+ return nil , fmt .Errorf ("version cannot be set when artifact URL is GitHub or GitLab: it is specified in the URL" )
322
+ }
323
+
324
+ spec .FetchConfig = & operatorv1.FetchConfiguration {
325
+ URL : providerURL ,
326
+ }
327
+ provider .SetSpec (spec )
328
+
329
+ return providerConfigMap (ctx , provider )
330
+ }
331
+
332
+ // artifact URL refers to an OCI registry.
299
333
spec .FetchConfig = & operatorv1.FetchConfiguration {
300
334
OCIConfiguration : operatorv1.OCIConfiguration {
301
- OCI : url ,
335
+ OCI : providerURL ,
302
336
},
303
337
}
304
338
provider .SetSpec (spec )
@@ -338,9 +372,11 @@ func providerConfigMap(ctx context.Context, provider operatorv1.GenericProvider)
338
372
return nil , fmt .Errorf ("unable to init memory reader: %w" , err )
339
373
}
340
374
375
+ spec := provider .GetSpec ()
376
+
341
377
// If provided store fetch config url in memory reader.
342
- if provider . GetSpec (). FetchConfig != nil && provider . GetSpec () .FetchConfig .URL != "" {
343
- _ , err := mr .AddProvider (provider .ProviderName (), util .ClusterctlProviderType (provider ), provider . GetSpec () .FetchConfig .URL )
378
+ if spec . FetchConfig != nil && spec .FetchConfig .URL != "" {
379
+ _ , err := mr .AddProvider (provider .ProviderName (), util .ClusterctlProviderType (provider ), spec .FetchConfig .URL )
344
380
if err != nil {
345
381
return nil , fmt .Errorf ("cannot add custom url provider: %w" , err )
346
382
}
@@ -363,6 +399,11 @@ func providerConfigMap(ctx context.Context, provider operatorv1.GenericProvider)
363
399
return nil , fmt .Errorf ("cannot create repository: %w" , err )
364
400
}
365
401
402
+ if spec .Version == "" {
403
+ spec .Version = repo .DefaultVersion ()
404
+ provider .SetSpec (spec )
405
+ }
406
+
366
407
return providercontroller .RepositoryConfigMap (ctx , provider , repo )
367
408
}
368
409
0 commit comments