-
Notifications
You must be signed in to change notification settings - Fork 288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Spike] Fix controller generating cilium manifests with registry mirror #7139
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
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 | ||
insecure bool | ||
} | ||
|
||
// 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 | ||
} | ||
|
||
// WithInsecure configures the factory to configure helm to use to allow connections to TLS registry without certs or with self-signed certs | ||
func (f *HelmFactory) WithInsecure() *HelmFactory { | ||
f.insecure = true | ||
|
||
return f | ||
} | ||
|
||
func NewHelmFactory(builder ExecutableBuilder) *HelmFactory { | ||
return &HelmFactory{ | ||
builder: builder, | ||
} | ||
} | ||
|
||
func (f *HelmFactory) GetInstance(opts ...executables.HelmOpt) *executables.Helm { | ||
f.mu.Lock() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious, do we really need a lock here? |
||
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)) | ||
} | ||
|
||
if f.insecure { | ||
opts = append(opts, executables.WithInsecure()) | ||
} | ||
|
||
f.helm = f.builder.BuildHelmExecutable(opts...) | ||
return f.helm | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,8 @@ | |
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 @@ | |
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 @@ | |
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This if check is duplicated in registryLogin function |
||
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 (t *Templater) registryLogin(ctx context.Context, helm Helm, spec *cluster.Spec) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like this "t" is not used, it can be a function instead of a method of Templater |
||
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 @@ | |
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 { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, factory is not really a preferred abstract in golang. As we have adopted it, we should try not making it more complicated.
This method introduces something feels like "nested factory", which makes the abstract harder to understand. I believe we can achieve the target without this "helmFactory"