Skip to content

Commit

Permalink
Resolve files with duplicate content, add tests
Browse files Browse the repository at this point in the history
Signed-off-by: Danil-Grigorev <[email protected]>
  • Loading branch information
Danil-Grigorev committed Jan 27, 2025
1 parent e543e4e commit 2959930
Show file tree
Hide file tree
Showing 32 changed files with 940 additions and 99 deletions.
2 changes: 1 addition & 1 deletion api/v1alpha1/zz_generated.conversion.go

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

18 changes: 12 additions & 6 deletions api/v1alpha2/provider_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,18 @@ 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
// desired version of the release from GitHub.
// +optional
URL string `json:"url,omitempty"`

// 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"`

// Selector to be used for fetching provider’s components and metadata from
// ConfigMaps stored inside the cluster. Each ConfigMap is expected to contain
// components and metadata for a specific version only.
Expand All @@ -233,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.

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

// 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>
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
71 changes: 42 additions & 29 deletions cmd/plugin/cmd/preload.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import (

"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
kerrors "k8s.io/apimachinery/pkg/util/errors"
"oras.land/oras-go/v2/registry/remote/auth"
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2"
Expand Down Expand Up @@ -207,30 +205,18 @@ func runPreLoad() error {
configMaps = append(configMaps, configMap)
}

errors := []error{}

if !loadOpts.existing {
for _, cm := range configMaps {
out, err := yaml.Marshal(cm)
if err != nil {
return fmt.Errorf("cannot serialize provider config map: %w", err)
}

fmt.Printf("---\n%s", string(out))
if loadOpts.existing {
client, err := CreateKubeClient(loadOpts.kubeconfig, "")
if err != nil {
return fmt.Errorf("cannot create a client: %w", err)
}

return nil
}

client, err := CreateKubeClient(loadOpts.kubeconfig, "")
if err != nil {
return fmt.Errorf("cannot create a client: %w", err)
}
existing, err := preloadExisting(ctx, client)
if err != nil {
return err
}

for _, list := range operatorv1.ProviderLists {
maps, err := fetchProviders(ctx, client, list.(genericProviderList))
configMaps = append(configMaps, maps...)
errors = append(errors, err)
configMaps = append(configMaps, existing...)
}

for _, cm := range configMaps {
Expand All @@ -242,15 +228,41 @@ func runPreLoad() error {
fmt.Printf("---\n%s", string(out))
}

return kerrors.NewAggregate(errors)
return nil
}

// preloadExisting uses existing cluster kubeconfig to list providers and create configmaps with components for each provider.
func preloadExisting(ctx context.Context, cl client.Client) ([]*corev1.ConfigMap, error) {
errors := []error{}
configMaps := []*corev1.ConfigMap{}

for _, list := range operatorv1.ProviderLists {
list, ok := list.(genericProviderList)
if !ok {
log.V(5).Info("Expected to get GenericProviderList")
continue
}

list, ok = list.DeepCopyObject().(genericProviderList)
if !ok {
log.V(5).Info("Expected to get GenericProviderList")
continue
}

maps, err := fetchProviders(ctx, cl, list)
configMaps = append(configMaps, maps...)
errors = append(errors, err)
}

return configMaps, kerrors.NewAggregate(errors)
}

func fetchProviders(ctx context.Context, cl client.Client, providerList genericProviderList) ([]*corev1.ConfigMap, error) {
configMaps := []*corev1.ConfigMap{}

if err := cl.List(ctx, providerList, client.InNamespace("")); meta.IsNoMatchError(err) || apierrors.IsNotFound(err) {
return configMaps, nil
} else if err != nil {
if err := retryWithExponentialBackoff(ctx, newReadBackoff(), func(ctx context.Context) error {
return cl.List(ctx, providerList, client.InNamespace(""))
}); err != nil {
log.Error(err, fmt.Sprintf("Unable to list providers, %#v", err))

return configMaps, err
Expand Down Expand Up @@ -285,9 +297,10 @@ func templateConfigMap(ctx context.Context, providerType clusterctlv1.ProviderTy

spec := provider.GetSpec()
spec.FetchConfig = &operatorv1.FetchConfiguration{
OCI: url,
OCIConfiguration: operatorv1.OCIConfiguration{
OCI: url,
},
}

provider.SetSpec(spec)

if spec.Version != "" {
Expand Down
Loading

0 comments on commit 2959930

Please sign in to comment.