Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions api/v1alpha1/provider_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (src *BootstrapProvider) ConvertTo(dstRaw conversion.Hub) error {

dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
dst.Spec.FetchConfig.OCI = restored.Spec.FetchConfig.OCI

return nil
}
Expand Down Expand Up @@ -108,6 +109,7 @@ func (src *ControlPlaneProvider) ConvertTo(dstRaw conversion.Hub) error {

dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
dst.Spec.FetchConfig.OCI = restored.Spec.FetchConfig.OCI

return nil
}
Expand Down Expand Up @@ -170,6 +172,7 @@ func (src *CoreProvider) ConvertTo(dstRaw conversion.Hub) error {

dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
dst.Spec.FetchConfig.OCI = restored.Spec.FetchConfig.OCI

return nil
}
Expand Down Expand Up @@ -232,6 +235,7 @@ func (src *InfrastructureProvider) ConvertTo(dstRaw conversion.Hub) error {

dst.Spec.ManifestPatches = restored.Spec.ManifestPatches
dst.Spec.AdditionalDeployments = restored.Spec.AdditionalDeployments
dst.Spec.FetchConfig.OCI = restored.Spec.FetchConfig.OCI

return nil
}
Expand Down Expand Up @@ -495,6 +499,10 @@ func Convert_v1alpha2_ContainerSpec_To_v1alpha1_ContainerSpec(in *operatorv1.Con
return nil
}

func Convert_v1alpha2_FetchConfiguration_To_v1alpha1_FetchConfiguration(in *operatorv1.FetchConfiguration, out *FetchConfiguration, s apimachineryconversion.Scope) error {
return autoConvert_v1alpha2_FetchConfiguration_To_v1alpha1_FetchConfiguration(in, out, s)
}

func toImageMeta(imageURL string) *ImageMeta {
im := ImageMeta{}

Expand Down
20 changes: 16 additions & 4 deletions api/v1alpha1/provider_conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,28 @@ func TestFuzzyConversion(t *testing.T) {
Scheme: scheme,
Hub: &operatorv1.CoreProvider{},
Spoke: &CoreProvider{},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, secretConfigFuzzFunc},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, ociFuzzFunc, secretConfigFuzzFunc},
}))

t.Run("for ControlPlaneProvider", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
Scheme: scheme,
Hub: &operatorv1.ControlPlaneProvider{},
Spoke: &ControlPlaneProvider{},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, secretConfigFuzzFunc},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, ociFuzzFunc, secretConfigFuzzFunc},
}))

t.Run("for BootstrapProvider", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
Scheme: scheme,
Hub: &operatorv1.BootstrapProvider{},
Spoke: &BootstrapProvider{},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, secretConfigFuzzFunc},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, ociFuzzFunc, secretConfigFuzzFunc},
}))

t.Run("for InfrastructureProvider", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
Scheme: scheme,
Hub: &operatorv1.InfrastructureProvider{},
Spoke: &InfrastructureProvider{},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, secretConfigFuzzFunc},
FuzzerFuncs: []fuzzer.FuzzerFuncs{imageMetaFuzzFunc, imageURLFuzzFunc, ociFuzzFunc, secretConfigFuzzFunc},
}))
}

Expand All @@ -80,6 +80,18 @@ func secretConfigFuzzer(in *operatorv1.SecretReference, c fuzz.Continue) {
}
}

func ociFuzzFunc(_ runtimeserializer.CodecFactory) []interface{} {
return []interface{}{
ociFuzzer,
}
}

func ociFuzzer(in *operatorv1.FetchConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(in)

in.OCI = ""
}

func imageURLFuzzFunc(_ runtimeserializer.CodecFactory) []interface{} {
return []interface{}{
imageURLFuzzer,
Expand Down
36 changes: 24 additions & 12 deletions api/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions api/v1alpha2/provider_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ type ContainerSpec struct {
}

// FetchConfiguration determines the way to fetch the components and metadata for the provider.
// +kubebuilder:validation:XValidation:rule="[has(self.oci), has(self.url), has(self.selector)].exists_one(x,x)", message="Must specify one and only one of {oci, url, selector}"
type FetchConfiguration struct {
// OCI configurations to be used for fetching the provider’s components and metadata from an OCI artifact.
OCIConfiguration `json:",inline"`

// URL to be used for fetching the provider’s components and metadata from a remote Github repository.
// For example, https://github.com/{owner}/{repository}/releases
// You must set `providerSpec.Version` field for operator to pick up
Expand All @@ -227,6 +231,14 @@ type FetchConfiguration struct {
Selector *metav1.LabelSelector `json:"selector,omitempty"`
}

type OCIConfiguration struct {
// OCI to be used for fetching the provider’s components and metadata from an OCI artifact.
// You must set `providerSpec.Version` field for operator to pick up desired version of the release from GitHub.
// If the providerSpec.Version is missing, latest provider version from clusterctl defaults is used.
// +optional
OCI string `json:"oci,omitempty"`
}

// ProviderStatus defines the observed state of the Provider.
type ProviderStatus struct {
// Contract will contain the core provider contract that the provider is
Expand Down
16 changes: 16 additions & 0 deletions api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 15 additions & 7 deletions cmd/plugin/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ func deployCAPIOperator(ctx context.Context, opts *initOptions) error {
return nil
}

// createGenericProvider creates a generic provider.
func createGenericProvider(ctx context.Context, client ctrlclient.Client, providerType clusterctlv1.ProviderType, providerInput, defaultNamespace, configSecretName, configSecretNamespace string) (operatorv1.GenericProvider, error) {
// templateGenericProvider prepares the provider manifest based on provided provider string.
func templateGenericProvider(providerType clusterctlv1.ProviderType, providerInput, defaultNamespace, configSecretName, configSecretNamespace string) (operatorv1.GenericProvider, error) {
// Parse the provider string
// Format is <provider-name>:<optional-namespace>:<optional-version>
// Example: aws:capa-system:v2.1.5 -> name: aws, namespace: capa-system, version: v2.1.5
Expand Down Expand Up @@ -498,8 +498,6 @@ func createGenericProvider(ctx context.Context, client ctrlclient.Client, provid
spec := provider.GetSpec()
spec.Version = version
provider.SetSpec(spec)
} else {
version = latestVersion
}

// Set config secret
Expand All @@ -517,19 +515,29 @@ func createGenericProvider(ctx context.Context, client ctrlclient.Client, provid
provider.SetSpec(spec)
}

return provider, nil
}

// createGenericProvider creates a generic provider.
func createGenericProvider(ctx context.Context, client ctrlclient.Client, providerType clusterctlv1.ProviderType, providerInput, defaultNamespace, configSecretName, configSecretNamespace string) (operatorv1.GenericProvider, error) {
provider, err := templateGenericProvider(providerType, providerInput, defaultNamespace, configSecretName, configSecretNamespace)
if err != nil {
return nil, err
}

// Ensure that desired namespace exists
if err := EnsureNamespaceExists(ctx, client, namespace); err != nil {
if err := EnsureNamespaceExists(ctx, client, provider.GetNamespace()); err != nil {
return nil, fmt.Errorf("cannot ensure that namespace exists: %w", err)
}

log.Info("Installing provider", "Type", provider.GetType(), "Name", name, "Version", version, "Namespace", namespace)
log.Info("Installing provider", "Type", provider.GetType(), "Name", provider.GetName(), "Version", provider.GetSpec().Version, "Namespace", provider.GetNamespace())

// Create the provider
if err := wait.ExponentialBackoff(backoffOpts, func() (bool, error) {
if err := client.Create(ctx, provider); err != nil {
// If the provider already exists, return immediately and do not retry.
if apierrors.IsAlreadyExists(err) {
log.Info("Provider already exists, skipping creation", "Type", provider.GetType(), "Name", name, "Version", version, "Namespace", namespace)
log.Info("Provider already exists, skipping creation", "Type", provider.GetType(), "Name", provider.GetName(), "Version", provider.GetSpec().Version, "Namespace", provider.GetNamespace())

return true, err
}
Expand Down
1 change: 0 additions & 1 deletion cmd/plugin/cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ func TestInitProviders(t *testing.T) {
opts: &initOptions{
coreProvider: "cluster-api:capi-system:v1.8.0",
infrastructureProviders: []string{
"cluster-api:capi-system:v1.8.0",
"aws:capa-operator-system",
"docker:capd-operator-system",
},
Expand Down
Loading
Loading