@@ -19,6 +19,7 @@ package cmd
1919import (
2020 "context"
2121 "fmt"
22+ "net/url"
2223 "os"
2324 "strings"
2425
@@ -44,7 +45,7 @@ type loadOptions struct {
4445 runtimeExtensionProviders []string
4546 addonProviders []string
4647 targetNamespace string
47- ociURL string
48+ artifactURL string
4849 kubeconfig string
4950 existing bool
5051}
@@ -67,6 +68,9 @@ var loadCmd = &cobra.Command{
6768 Alternatively, for multi-provider OCI artifact, a fully specified name can be used for both metadata and components:
6869
6970 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.
7074 ` ),
7175 Example : Examples (`
7276 # Load CAPI operator manifests from OCI source
@@ -78,12 +82,21 @@ var loadCmd = &cobra.Command{
7882 # Prepare provider ConfigMap from OCI, from the given infrastructure provider.
7983 capioperator preload --infrastructure=aws -u ttl.sh/infrastructure-provider
8084
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+
8188 # Prepare provider ConfigMap from OCI with a specific version of the given infrastructure provider in the default namespace.
8289 capioperator preload --infrastructure=aws::v2.3.0 -u ttl.sh/infrastructure-provider
8390
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+
8494 # Prepare provider ConfigMap from OCI with a specific namespace and the latest version of the given infrastructure provider.
8595 capioperator preload --infrastructure=aws:custom-namespace -u ttl.sh/infrastructure-provider
8696
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+
87100 # Prepare provider ConfigMap from OCI with a specific version and namespace of the given infrastructure provider.
88101 capioperator preload --infrastructure=aws:custom-namespace:v2.3.0 -u ttl.sh/infrastructure-provider
89102
@@ -119,24 +132,24 @@ func init() {
119132 "Add-on providers and versions (e.g. helm:v0.1.0) to add to the management cluster." )
120133 loadCmd .Flags ().StringVarP (& loadOpts .targetNamespace , "target-namespace" , "n" , "capi-operator-system" ,
121134 "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." )
124137
125138 RootCmd .AddCommand (loadCmd )
126139}
127140
128141func runPreLoad () error {
129142 ctx := context .Background ()
130143
131- if loadOpts .ociURL == "" {
144+ if loadOpts .artifactURL == "" {
132145 return fmt .Errorf ("missing configMap artifacts url" )
133146 }
134147
135148 configMaps := []* corev1.ConfigMap {}
136149
137150 // Load Core Provider.
138151 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 )
140153
141154 if err != nil {
142155 return fmt .Errorf ("cannot prepare manifests config map for core provider: %w" , err )
@@ -147,7 +160,7 @@ func runPreLoad() error {
147160
148161 // Load Bootstrap Providers.
149162 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 )
151164 if err != nil {
152165 return fmt .Errorf ("cannot prepare manifests config map for bootstrap provider: %w" , err )
153166 }
@@ -157,7 +170,7 @@ func runPreLoad() error {
157170
158171 // Load Infrastructure Providers.
159172 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 )
161174 if err != nil {
162175 return fmt .Errorf ("cannot prepare manifests config map for infrastructure provider: %w" , err )
163176 }
@@ -167,7 +180,7 @@ func runPreLoad() error {
167180
168181 // Load Control Plane Providers.
169182 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 )
171184 if err != nil {
172185 return fmt .Errorf ("cannot prepare manifests config map for controlplane provider: %w" , err )
173186 }
@@ -177,7 +190,7 @@ func runPreLoad() error {
177190
178191 // Load Add-on Providers.
179192 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 )
181194 if err != nil {
182195 return fmt .Errorf ("cannot prepare manifests config map for addon provider: %w" , err )
183196 }
@@ -187,7 +200,7 @@ func runPreLoad() error {
187200
188201 // Load IPAM Providers.
189202 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 )
191204 if err != nil {
192205 return fmt .Errorf ("cannot prepare manifests config map for IPAM provider: %w" , err )
193206 }
@@ -197,7 +210,7 @@ func runPreLoad() error {
197210
198211 // Load Runtime Extension Providers.
199212 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 )
201214 if err != nil {
202215 return fmt .Errorf ("cannot prepare manifests config map for runtime extension provider: %w" , err )
203216 }
@@ -289,16 +302,37 @@ func fetchProviders(ctx context.Context, cl client.Client, providerList genericP
289302 return configMaps , nil
290303}
291304
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 ) {
293306 provider , err := templateGenericProvider (providerType , providerInput , defaultNamespace , "" , "" )
294307 if err != nil {
295308 return nil , err
296309 }
297310
298311 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.
299333 spec .FetchConfig = & operatorv1.FetchConfiguration {
300334 OCIConfiguration : operatorv1.OCIConfiguration {
301- OCI : url ,
335+ OCI : providerURL ,
302336 },
303337 }
304338 provider .SetSpec (spec )
@@ -338,9 +372,11 @@ func providerConfigMap(ctx context.Context, provider operatorv1.GenericProvider)
338372 return nil , fmt .Errorf ("unable to init memory reader: %w" , err )
339373 }
340374
375+ spec := provider .GetSpec ()
376+
341377 // 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 )
344380 if err != nil {
345381 return nil , fmt .Errorf ("cannot add custom url provider: %w" , err )
346382 }
@@ -363,6 +399,11 @@ func providerConfigMap(ctx context.Context, provider operatorv1.GenericProvider)
363399 return nil , fmt .Errorf ("cannot create repository: %w" , err )
364400 }
365401
402+ if spec .Version == "" {
403+ spec .Version = repo .DefaultVersion ()
404+ provider .SetSpec (spec )
405+ }
406+
366407 return providercontroller .RepositoryConfigMap (ctx , provider , repo )
367408}
368409
0 commit comments