diff --git a/pkg/dependencies/factory.go b/pkg/dependencies/factory.go index 16eca5d0e96f3..a49e95330d3ec 100644 --- a/pkg/dependencies/factory.go +++ b/pkg/dependencies/factory.go @@ -107,6 +107,7 @@ type Dependencies struct { SnowValidator *snow.Validator IPValidator *validator.IPValidator UnAuthKubectlClient KubeClients + HelmFactory *HelmFactory CreateClusterDefaulter cli.CreateClusterDefaulter UpgradeClusterDefaulter cli.UpgradeClusterDefaulter } @@ -770,6 +771,23 @@ func (f *Factory) WithHelm(opts ...executables.HelmOpt) *Factory { return f } +func (f *Factory) WithHelmFactory(opts ...executables.HelmOpt) *Factory { + f.WithExecutableBuilder() + + f.buildSteps = append(f.buildSteps, func(ctx context.Context) error { + if f.dependencies.HelmFactory != nil { + return nil + } + + f.dependencies.HelmFactory = NewHelmFactory(f.executablesConfig.builder). + WithRegistryMirror(f.registryMirror). + WithProxyConfigurations(f.proxyConfiguration) + return nil + }) + + return f +} + // WithNetworking builds a Networking. func (f *Factory) WithNetworking(clusterConfig *v1alpha1.Cluster) *Factory { var networkingBuilder func() clustermanager.Networking @@ -845,13 +863,13 @@ func (f *Factory) WithCNIInstaller(spec *cluster.Spec, provider providers.Provid } func (f *Factory) WithCiliumTemplater() *Factory { - f.WithHelm(executables.WithInsecure()) + f.WithHelmFactory(executables.WithInsecure()) f.buildSteps = append(f.buildSteps, func(ctx context.Context) error { if f.dependencies.CiliumTemplater != nil { return nil } - f.dependencies.CiliumTemplater = cilium.NewTemplater(f.dependencies.Helm) + f.dependencies.CiliumTemplater = cilium.NewTemplater(f.dependencies.HelmFactory) return nil }) diff --git a/pkg/dependencies/helm.go b/pkg/dependencies/helm.go new file mode 100644 index 0000000000000..13ea40beeb44c --- /dev/null +++ b/pkg/dependencies/helm.go @@ -0,0 +1,56 @@ +package dependencies + +import ( + "sync" + + "github.com/aws/eks-anywhere/pkg/executables" + "github.com/aws/eks-anywhere/pkg/registrymirror" +) + +type ExecutableBuilder interface { + BuildHelmExecutable(...executables.HelmOpt) *executables.Helm +} + +type HelmFactory struct { + mu sync.Mutex + builder ExecutableBuilder + helm *executables.Helm + registryMirror *registrymirror.RegistryMirror + proxyConfiguration map[string]string +} + +// WithRegistryMirror configures the factory to use registry mirror wherever applicable. +func (f *HelmFactory) WithRegistryMirror(registryMirror *registrymirror.RegistryMirror) *HelmFactory { + f.registryMirror = registryMirror + + return f +} + +// WithProxyConfigurations configures the factory to use proxy configurations wherever applicable. +func (f *HelmFactory) WithProxyConfigurations(proxyConfiguration map[string]string) *HelmFactory { + f.proxyConfiguration = proxyConfiguration + + return f +} + +func NewHelmFactory(builder ExecutableBuilder) *HelmFactory { + return &HelmFactory{ + builder: builder, + } +} + +func (f *HelmFactory) GetInstance(opts ...executables.HelmOpt) *executables.Helm { + f.mu.Lock() + defer f.mu.Unlock() + + if f.registryMirror != nil { + opts = append(opts, executables.WithRegistryMirror(f.registryMirror)) + } + + if f.proxyConfiguration != nil { + opts = append(opts, executables.WithEnv(f.proxyConfiguration)) + } + + f.helm = f.builder.BuildHelmExecutable(opts...) + return f.helm +} diff --git a/pkg/networking/cilium/templater.go b/pkg/networking/cilium/templater.go index fc873784d2a6c..4819f224f1667 100644 --- a/pkg/networking/cilium/templater.go +++ b/pkg/networking/cilium/templater.go @@ -11,6 +11,8 @@ import ( anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/config" + "github.com/aws/eks-anywhere/pkg/executables" + "github.com/aws/eks-anywhere/pkg/registrymirror" "github.com/aws/eks-anywhere/pkg/retrier" "github.com/aws/eks-anywhere/pkg/semver" "github.com/aws/eks-anywhere/pkg/templater" @@ -29,13 +31,17 @@ type Helm interface { RegistryLogin(ctx context.Context, registry, username, password string) error } +type HelmFactory interface { + GetInstance(opts ...executables.HelmOpt) *executables.Helm +} + type Templater struct { - helm Helm + helmFactory HelmFactory } -func NewTemplater(helm Helm) *Templater { +func NewTemplater(helmFactory HelmFactory) *Templater { return &Templater{ - helm: helm, + helmFactory: helmFactory, } } @@ -62,7 +68,16 @@ func (t *Templater) GenerateUpgradePreflightManifest(ctx context.Context, spec * return nil, err } - manifest, err := t.helm.Template(ctx, uri, version, namespace, v, kubeVersion) + r := registrymirror.FromCluster(spec.Cluster) + helm := t.helmFactory.GetInstance(executables.WithRegistryMirror(r)) + + if spec.Cluster.Spec.RegistryMirrorConfiguration != nil { + if err := t.registryLogin(ctx, helm, spec); err != nil { + return nil, err + } + } + + manifest, err := helm.Template(ctx, uri, version, namespace, v, kubeVersion) if err != nil { return nil, fmt.Errorf("failed generating cilium upgrade preflight manifest: %v", err) } @@ -112,6 +127,20 @@ func WithPolicyAllowedNamespaces(namespaces []string) ManifestOpt { } } +func (t *Templater) registryLogin(ctx context.Context, helm Helm, spec *cluster.Spec) error { + if spec.Cluster.Spec.RegistryMirrorConfiguration.Authenticate { + username, password, err := config.ReadCredentials() + if err != nil { + return err + } + endpoint := net.JoinHostPort(spec.Cluster.Spec.RegistryMirrorConfiguration.Endpoint, spec.Cluster.Spec.RegistryMirrorConfiguration.Port) + if err := helm.RegistryLogin(ctx, endpoint, username, password); err != nil { + return err + } + } + return nil +} + func (t *Templater) GenerateManifest(ctx context.Context, spec *cluster.Spec, opts ...ManifestOpt) ([]byte, error) { versionsBundle := spec.RootVersionsBundle() kubeVersion, err := getKubeVersionString(spec, versionsBundle) @@ -131,21 +160,17 @@ func (t *Templater) GenerateManifest(ctx context.Context, spec *cluster.Spec, op uri, version := getChartURIAndVersion(versionsBundle) var manifest []byte + r := registrymirror.FromCluster(spec.Cluster) + helm := t.helmFactory.GetInstance(executables.WithRegistryMirror(r)) + if spec.Cluster.Spec.RegistryMirrorConfiguration != nil { - if spec.Cluster.Spec.RegistryMirrorConfiguration.Authenticate { - username, password, err := config.ReadCredentials() - if err != nil { - return nil, err - } - endpoint := net.JoinHostPort(spec.Cluster.Spec.RegistryMirrorConfiguration.Endpoint, spec.Cluster.Spec.RegistryMirrorConfiguration.Port) - if err := t.helm.RegistryLogin(ctx, endpoint, username, password); err != nil { - return nil, err - } + if err := t.registryLogin(ctx, helm, spec); err != nil { + return nil, err } } err = c.retrier.Retry(func() error { - manifest, err = t.helm.Template(ctx, uri, version, namespace, c.values, c.kubeVersion) + manifest, err = helm.Template(ctx, uri, version, namespace, c.values, c.kubeVersion) return err }) if err != nil {