Skip to content

Commit

Permalink
πŸ’ Cherry pick packages with registry mirror fixes (#8029)
Browse files Browse the repository at this point in the history
* Adding a helm login to packages reconcile flow for workload clusters (#7971)

* Adding permissions for controller packages helm upgrade (#8012)

* Adding namespaces read permissions to eksa controller (#8017)
  • Loading branch information
pokearu authored Apr 22, 2024
1 parent daf8016 commit 355de0a
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 6 deletions.
3 changes: 3 additions & 0 deletions config/manifest/eksa-components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7109,6 +7109,8 @@ rules:
verbs:
- create
- delete
- get
- list
- apiGroups:
- ""
resources:
Expand All @@ -7134,6 +7136,7 @@ rules:
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
Expand Down
3 changes: 3 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ rules:
verbs:
- create
- delete
- get
- list
- apiGroups:
- ""
resources:
Expand All @@ -54,6 +56,7 @@ rules:
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
Expand Down
4 changes: 2 additions & 2 deletions controllers/cluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager, log logr.Logger)
}

// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch;update
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;delete;update
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;delete;update;patch
// +kubebuilder:rbac:groups="",namespace=eksa-system,resources=secrets,verbs=patch;update
// +kubebuilder:rbac:groups="",resources=namespaces,verbs=create;delete
// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;create;delete
// +kubebuilder:rbac:groups="",resources=nodes,verbs=list
// +kubebuilder:rbac:groups=addons.cluster.x-k8s.io,resources=clusterresourcesets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=anywhere.eks.amazonaws.com,resources=clusters;gitopsconfigs;snowmachineconfigs;snowdatacenterconfigs;snowippools;vspheredatacenterconfigs;vspheremachineconfigs;dockerdatacenterconfigs;tinkerbellmachineconfigs;tinkerbelltemplateconfigs;tinkerbelldatacenterconfigs;cloudstackdatacenterconfigs;cloudstackmachineconfigs;nutanixdatacenterconfigs;nutanixmachineconfigs;awsiamconfigs;oidcconfigs;awsiamconfigs;fluxconfigs,verbs=get;list;watch;update;patch
Expand Down
2 changes: 1 addition & 1 deletion controllers/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ func (f *Factory) withAWSIamConfigReconciler() *Factory {
}

func (f *Factory) withPackageControllerClient() *Factory {
f.dependencyFactory.WithHelm().WithKubectl()
f.dependencyFactory.WithHelm(helm.WithInsecure()).WithKubectl()

f.buildSteps = append(f.buildSteps, func(ctx context.Context) error {
if f.packageControllerClient != nil {
Expand Down
14 changes: 14 additions & 0 deletions pkg/curatedpackages/mocks/installer.go

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

20 changes: 17 additions & 3 deletions pkg/curatedpackages/packagecontrollerclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type ChartUninstaller interface {
type ChartManager interface {
ChartInstaller
ChartUninstaller
RegistryLogin(ctx context.Context, registry, username, password string) error
}

// NewPackageControllerClientFullLifecycle creates a PackageControllerClient
Expand Down Expand Up @@ -307,9 +308,11 @@ func (pc *PackageControllerClient) generateHelmOverrideValues() ([]byte, error)
endpoint, username, password, caCertContent, insecureSkipVerify := "", "", "", "", "false"
if pc.registryMirror != nil {
endpoint = pc.registryMirror.BaseRegistry
username, password, err = config.ReadCredentials()
if err != nil {
return []byte{}, err
if pc.registryMirror.Auth {
username, password, err = config.ReadCredentials()
if err != nil {
return []byte{}, err
}
}
caCertContent = pc.registryMirror.CACertContent
if pc.registryMirror.InsecureSkipVerify {
Expand Down Expand Up @@ -492,6 +495,17 @@ func (pc *PackageControllerClient) Reconcile(ctx context.Context, logger logr.Lo

registry := registrymirror.FromCluster(cluster)

if registry != nil && registry.Auth {
rUsername, rPassword, err := config.ReadCredentialsFromSecret(ctx, client)
if err != nil {
return err
}

if err := pc.chartManager.RegistryLogin(ctx, registry.BaseRegistry, rUsername, rPassword); err != nil {
return err
}
}

// No Kubeconfig is passed. This is intentional. The helm executable will
// get that configuration from its environment.
if err := pc.EnableFullLifecycle(ctx, logger, cluster.Name, "", image, registry,
Expand Down
139 changes: 139 additions & 0 deletions pkg/curatedpackages/packagecontrollerclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,145 @@ func TestReconcile(s *testing.T) {
t.Errorf("expected packages client error, got %s", err)
}
})

s.Run("golden path with registry mirror", func(t *testing.T) {
ctx := context.Background()
log := testr.New(t)
cluster := newReconcileTestCluster()
ctrl := gomock.NewController(t)
k := mocks.NewMockKubectlRunner(ctrl)
cm := mocks.NewMockChartManager(ctrl)
bundles := createBundle(cluster)
bundles.Spec.VersionsBundles[0].KubeVersion = string(cluster.Spec.KubernetesVersion)
bundles.ObjectMeta.Name = cluster.Spec.BundlesRef.Name
bundles.ObjectMeta.Namespace = cluster.Spec.BundlesRef.Namespace
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: constants.EksaSystemNamespace,
Name: cluster.Name + "-kubeconfig",
},
}
registrySecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: constants.EksaSystemNamespace,
Name: "registry-credentials",
},
}
eksaRelease := createEKSARelease(cluster, bundles)
cluster.Spec.BundlesRef = nil
cluster.Spec.RegistryMirrorConfiguration = &anywherev1.RegistryMirrorConfiguration{
Endpoint: "1.2.3.4",
Port: "443",
Authenticate: true,
OCINamespaces: []anywherev1.OCINamespace{
{
Namespace: "ecr-public",
Registry: "public.ecr.aws",
},
},
}
t.Setenv("REGISTRY_USERNAME", "username")
t.Setenv("REGISTRY_PASSWORD", "password")

objs := []runtime.Object{cluster, bundles, secret, eksaRelease, registrySecret}
fakeClient := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build()
cm.EXPECT().RegistryLogin(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
cm.EXPECT().InstallChart(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)

pcc := curatedpackages.NewPackageControllerClientFullLifecycle(log, cm, k, nil)
err := pcc.Reconcile(ctx, log, fakeClient, cluster)
if err != nil {
t.Errorf("expected nil error, got %s", err)
}
})

s.Run("registry mirror helm login fails", func(t *testing.T) {
ctx := context.Background()
log := testr.New(t)
cluster := newReconcileTestCluster()
ctrl := gomock.NewController(t)
k := mocks.NewMockKubectlRunner(ctrl)
cm := mocks.NewMockChartManager(ctrl)
bundles := createBundle(cluster)
bundles.Spec.VersionsBundles[0].KubeVersion = string(cluster.Spec.KubernetesVersion)
bundles.ObjectMeta.Name = cluster.Spec.BundlesRef.Name
bundles.ObjectMeta.Namespace = cluster.Spec.BundlesRef.Namespace
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: constants.EksaSystemNamespace,
Name: cluster.Name + "-kubeconfig",
},
}
registrySecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: constants.EksaSystemNamespace,
Name: "registry-credentials",
},
}
eksaRelease := createEKSARelease(cluster, bundles)
cluster.Spec.BundlesRef = nil
cluster.Spec.RegistryMirrorConfiguration = &anywherev1.RegistryMirrorConfiguration{
Endpoint: "1.2.3.4",
Port: "443",
Authenticate: true,
OCINamespaces: []anywherev1.OCINamespace{
{
Namespace: "ecr-public",
Registry: "public.ecr.aws",
},
},
}
t.Setenv("REGISTRY_USERNAME", "username")
t.Setenv("REGISTRY_PASSWORD", "password")

objs := []runtime.Object{cluster, bundles, secret, eksaRelease, registrySecret}
fakeClient := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build()
cm.EXPECT().RegistryLogin(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("login error"))
pcc := curatedpackages.NewPackageControllerClientFullLifecycle(log, cm, k, nil)
err := pcc.Reconcile(ctx, log, fakeClient, cluster)
if err == nil {
t.Errorf("expected error, got %s", err)
}
})

s.Run("registry mirror secret not found error", func(t *testing.T) {
ctx := context.Background()
log := testr.New(t)
cluster := newReconcileTestCluster()
ctrl := gomock.NewController(t)
k := mocks.NewMockKubectlRunner(ctrl)
cm := mocks.NewMockChartManager(ctrl)
bundles := createBundle(cluster)
bundles.Spec.VersionsBundles[0].KubeVersion = string(cluster.Spec.KubernetesVersion)
bundles.ObjectMeta.Name = cluster.Spec.BundlesRef.Name
bundles.ObjectMeta.Namespace = cluster.Spec.BundlesRef.Namespace
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: constants.EksaSystemNamespace,
Name: cluster.Name + "-kubeconfig",
},
}
eksaRelease := createEKSARelease(cluster, bundles)
cluster.Spec.BundlesRef = nil
cluster.Spec.RegistryMirrorConfiguration = &anywherev1.RegistryMirrorConfiguration{
Endpoint: "1.2.3.4",
Port: "443",
Authenticate: true,
OCINamespaces: []anywherev1.OCINamespace{
{
Namespace: "ecr-public",
Registry: "public.ecr.aws",
},
},
}
objs := []runtime.Object{cluster, bundles, secret, eksaRelease}
fakeClient := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build()
pcc := curatedpackages.NewPackageControllerClientFullLifecycle(log, cm, k, nil)
err := pcc.Reconcile(ctx, log, fakeClient, cluster)
if err == nil || !strings.Contains(err.Error(), "not found") {
t.Errorf("expected error, got %s", err)
}
})
}

func newReconcileTestCluster() *anywherev1.Cluster {
Expand Down

0 comments on commit 355de0a

Please sign in to comment.