Skip to content

Commit

Permalink
Merge pull request #349 from Danil-Grigorev/provide-clusterctl-yaml
Browse files Browse the repository at this point in the history
✨Allow to utilize providers from clusterctl.yaml file in /config/clusterctl.yaml
  • Loading branch information
k8s-ci-robot committed Jan 9, 2024
2 parents d2a9bf8 + f9b4568 commit 92f1968
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
1 change: 1 addition & 0 deletions internal/controller/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ const (
githubDomain = "github.com"
gitlabHostPrefix = "gitlab."
gitlabPackagesAPIPrefix = "/api/v4/projects/"
configPath = "/config/clusterctl.yaml"
)
36 changes: 30 additions & 6 deletions internal/controller/phases.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"io"
"net/url"
"os"
"strings"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -114,18 +115,35 @@ func (p *phaseReconciler) preflightChecks(ctx context.Context) (reconcile.Result

// initializePhaseReconciler initializes phase reconciler.
func (p *phaseReconciler) initializePhaseReconciler(ctx context.Context) (reconcile.Result, error) {
// Load provider's secret and config url.
reader, err := p.secretReader(ctx)
if err != nil {
return reconcile.Result{}, wrapPhaseError(err, "failed to load the secret reader")
path := configPath
if _, err := os.Stat(configPath); os.IsNotExist(err) {
path = ""
} else if err != nil {
return reconcile.Result{}, err
}

// Initialize a client for interacting with the clusterctl configuration.
p.configClient, err = configclient.New(ctx, "", configclient.InjectReader(reader))
initConfig, err := configclient.New(ctx, path)
if err != nil {
return reconcile.Result{}, err
}

providers, err := initConfig.Providers().List()
if err != nil {
return reconcile.Result{}, err
}

reader, err := p.secretReader(ctx, providers...)
if err != nil {
return reconcile.Result{}, err
}

// Load provider's secret and config url.
p.configClient, err = configclient.New(ctx, "", configclient.InjectReader(reader))
if err != nil {
return reconcile.Result{}, wrapPhaseError(err, "failed to load the secret reader")
}

// Get returns the configuration for the provider with a given name/type.
// This is done using clusterctl internal API types.
p.providerConfig, err = p.configClient.Providers().Get(p.provider.GetName(), util.ClusterctlProviderType(p.provider))
Expand Down Expand Up @@ -197,7 +215,7 @@ func (p *phaseReconciler) load(ctx context.Context) (reconcile.Result, error) {

// secretReader use clusterctl MemoryReader structure to store the configuration variables
// that are obtained from a secret and try to set fetch url config.
func (p *phaseReconciler) secretReader(ctx context.Context) (configclient.Reader, error) {
func (p *phaseReconciler) secretReader(ctx context.Context, providers ...configclient.Provider) (configclient.Reader, error) {
log := ctrl.LoggerFrom(ctx)

mr := configclient.NewMemoryReader()
Expand All @@ -222,6 +240,12 @@ func (p *phaseReconciler) secretReader(ctx context.Context) (configclient.Reader
log.Info("No configuration secret was specified")
}

for _, provider := range providers {
if _, err := mr.AddProvider(provider.Name(), provider.Type(), provider.URL()); err != nil {
return nil, err
}
}

// If provided store fetch config url in memory reader.
if p.provider.GetSpec().FetchConfig != nil {
if p.provider.GetSpec().FetchConfig.URL != "" {
Expand Down
12 changes: 10 additions & 2 deletions internal/controller/phases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func TestSecretReader(t *testing.T) {
testValue1 := "test-value1"
testKey2 := "test-key2"
testValue2 := "test-value2"
testKey3 := "test-key3"
testValue3 := "test-value3"

g.Expect(fakeclient.Create(ctx, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -81,7 +83,7 @@ func TestSecretReader(t *testing.T) {
},
})).To(Succeed())

configreader, err := p.secretReader(context.TODO())
configreader, err := p.secretReader(context.TODO(), configclient.NewProvider(testKey3, testValue3, clusterctlv1.CoreProviderType))
g.Expect(err).ToNot(HaveOccurred())

expectedValue1, err := configreader.Get(testKey1)
Expand All @@ -94,7 +96,13 @@ func TestSecretReader(t *testing.T) {

exptectedProviderData, err := configreader.Get("providers")
g.Expect(err).ToNot(HaveOccurred())
g.Expect(exptectedProviderData).To(Equal("- name: cluster-api\n type: CoreProvider\n url: https://example.com\n"))
g.Expect(exptectedProviderData).To(Equal(`- name: test-key3
type: CoreProvider
url: test-value3
- name: cluster-api
type: CoreProvider
url: https://example.com
`))
}

func TestConfigmapRepository(t *testing.T) {
Expand Down
10 changes: 9 additions & 1 deletion internal/controller/preflight_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controller
import (
"context"
"fmt"
"os"

"github.com/google/go-github/v52/github"
"golang.org/x/oauth2"
Expand Down Expand Up @@ -230,8 +231,15 @@ func coreProviderIsReady(ctx context.Context, c client.Client) (bool, error) {
// The list of known providers can be found here:
// https://github.com/kubernetes-sigs/cluster-api/blob/main/cmd/clusterctl/client/config/providers_client.go
func isPredefinedProvider(ctx context.Context, providerName string, providerType clusterctlv1.ProviderType) (bool, error) {
path := configPath
if _, err := os.Stat(configPath); os.IsNotExist(err) {
path = ""
} else if err != nil {
return false, err
}

// Initialize a client that contains predefined providers only.
configClient, err := configclient.New(ctx, "")
configClient, err := configclient.New(ctx, path)
if err != nil {
return false, err
}
Expand Down

0 comments on commit 92f1968

Please sign in to comment.