fix(in-cluster): do not allow the cluster to be used when disabled (#21208)

Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
This commit is contained in:
Alexandre Gaudreault 2025-01-22 15:36:05 -05:00 committed by GitHub
parent 35a174b956
commit 8f285a5dd4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 428 additions and 121 deletions

View file

@ -41,6 +41,39 @@ import (
"github.com/argoproj/argo-cd/v3/util/settings"
)
// getDefaultTestClientSet creates a Clientset with the default argo objects
// and objects specified in parameters
func getDefaultTestClientSet(obj ...runtime.Object) *kubefake.Clientset {
argoCDSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: argocommon.ArgoCDSecretName,
Namespace: "argocd",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
}
emptyArgoCDConfigMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: argocommon.ArgoCDConfigMapName,
Namespace: "argocd",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{},
}
objects := append(obj, emptyArgoCDConfigMap, argoCDSecret)
kubeclientset := kubefake.NewClientset(objects...)
return kubeclientset
}
func TestCreateOrUpdateInCluster(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
@ -1317,8 +1350,7 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) {
},
}
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
kubeclientset := getDefaultTestClientSet(secret)
metrics := appsetmetrics.NewFakeAppsetMetrics()
argodb := db.NewDB("argocd", settings.NewSettingsManager(context.TODO(), kubeclientset, "argocd"), kubeclientset)
@ -2054,8 +2086,7 @@ func TestValidateGeneratedApplications(t *testing.T) {
},
}
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
kubeclientset := getDefaultTestClientSet(secret)
argodb := db.NewDB("argocd", settings.NewSettingsManager(context.TODO(), kubeclientset, "argocd"), kubeclientset)
@ -2117,7 +2148,7 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) {
},
}
kubeclientset := kubefake.NewSimpleClientset()
kubeclientset := getDefaultTestClientSet()
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &project).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics()
@ -2404,8 +2435,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
},
}
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
kubeclientset := getDefaultTestClientSet(secret)
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics()
@ -2580,8 +2610,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
},
}
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
kubeclientset := getDefaultTestClientSet(secret)
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics()
@ -2700,7 +2729,7 @@ func TestPolicies(t *testing.T) {
Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://kubernetes.default.svc"}}},
}
kubeclientset := kubefake.NewSimpleClientset()
kubeclientset := getDefaultTestClientSet()
for _, c := range []struct {
name string

View file

@ -16,6 +16,7 @@ import (
kubefake "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/tools/cache"
"github.com/argoproj/argo-cd/v3/common"
statecache "github.com/argoproj/argo-cd/v3/controller/cache"
cachemocks "github.com/argoproj/argo-cd/v3/controller/cache/mocks"
"github.com/argoproj/argo-cd/v3/controller/metrics"
@ -57,15 +58,28 @@ func TestGetReconcileResults(t *testing.T) {
func TestGetReconcileResults_Refresh(t *testing.T) {
ctx := context.Background()
cm := corev1.ConfigMap{
argoCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "argocd-cm",
Name: common.ArgoCDConfigMapName,
Namespace: "default",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
}
argoCDSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDSecretName,
Namespace: "default",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
}
proj := &v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
@ -91,7 +105,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) {
appClientset := appfake.NewSimpleClientset(app, proj)
deployment := test.NewDeployment()
kubeClientset := kubefake.NewClientset(deployment, &cm)
kubeClientset := kubefake.NewClientset(deployment, argoCM, argoCDSecret)
clusterCache := clustermocks.ClusterCache{}
clusterCache.On("IsNamespaced", mock.Anything).Return(true, nil)
clusterCache.On("GetGVKParser", mock.Anything).Return(nil)

View file

@ -22,3 +22,16 @@ The v2 behavior can be preserved by setting the config value `server.rbac.disabl
to `false` in the Argo CD ConfigMap `argocd-cm`.
Read the [RBAC documentation](../rbac.md#fine-grained-permissions-for-updatedelete-action) for more detailed inforamtion.
## Other changes
### Using `cluster.inClusterEnabled: "false"`
When `cluster.inClusterEnabled: "false"` is explicitly configured, Applications currently configured to
sync on the in-cluster cluster will now be in an Unknown state, without the possibility to sync resources.
It will not be possible to create new Applications using the in-cluster cluster. When deleting existing
Application, it will not delete the previously managed resources.
It is recommended to perform any cleanup or migration to existing in-cluster Application before upgrading
when in-cluster is disabled. To perform cleanup post-migration, the in-cluster will need to be enabled temporarily.

View file

@ -732,6 +732,28 @@ func TestComparisonFailsIfDestinationClusterIsInvalid(t *testing.T) {
Expect(Condition(ApplicationConditionInvalidSpecError, "there are no clusters with this name"))
}
func TestComparisonFailsIfInClusterDisabled(t *testing.T) {
Given(t).
Path(guestbookPath).
DestServer(KubernetesInternalAPIServerAddr).
When().
CreateApp().
Refresh(RefreshTypeNormal).
Sync().
Then().
Expect(Success("")).
Expect(HealthIs(health.HealthStatusHealthy)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
When().
SetParamInSettingConfigMap("cluster.inClusterEnabled", "false").
Refresh(RefreshTypeNormal).
Then().
Expect(Success("")).
Expect(HealthIs(health.HealthStatusUnknown)).
Expect(SyncStatusIs(SyncStatusCodeUnknown)).
Expect(Condition(ApplicationConditionInvalidSpecError, fmt.Sprintf("cluster %q is disabled", KubernetesInternalAPIServerAddr)))
}
func TestCannotSetInvalidPath(t *testing.T) {
Given(t).
Path(guestbookPath).
@ -2189,6 +2211,19 @@ func TestCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) {
})
}
func TestCreateAppWithInClusterDisabled(t *testing.T) {
Given(t).
Path(guestbookPath).
DestServer(KubernetesInternalAPIServerAddr).
When().
SetParamInSettingConfigMap("cluster.inClusterEnabled", "false").
IgnoreErrors().
CreateApp().
Then().
// RPC error messages are quoted: time="2024-12-18T04:13:58Z" level=fatal msg="<Quoted value>"
Expect(Error("", fmt.Sprintf(`cluster \"%s\" is disabled`, KubernetesInternalAPIServerAddr)))
}
func TestListResource(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).

View file

@ -370,7 +370,7 @@ func Error(message, err string, matchers ...func(string, string) bool) Expectati
return failed, fmt.Sprintf("output does not contain '%s'", message)
}
if !match(c.actions.lastError.Error(), err) {
return failed, fmt.Sprintf("error does not contain '%s'", message)
return failed, fmt.Sprintf("error does not contain '%s'", err)
}
return succeeded, fmt.Sprintf("error '%s'", message)
}

View file

@ -142,11 +142,19 @@ func (db *db) WatchClusters(ctx context.Context,
handleModEvent func(oldCluster *appv1.Cluster, newCluster *appv1.Cluster),
handleDeleteEvent func(clusterServer string),
) error {
localCls, err := db.GetCluster(ctx, appv1.KubernetesInternalAPIServerAddr)
argoSettings, err := db.settingsMgr.GetSettings()
if err != nil {
return err
}
handleAddEvent(localCls)
localCls := db.getLocalCluster()
if argoSettings.InClusterEnabled {
localCls, err = db.GetCluster(ctx, appv1.KubernetesInternalAPIServerAddr)
if err != nil {
return fmt.Errorf("could not get local cluster: %w", err)
}
handleAddEvent(localCls)
}
db.watchSecrets(
ctx,
@ -159,9 +167,11 @@ func (db *db) WatchClusters(ctx context.Context,
return
}
if cluster.Server == appv1.KubernetesInternalAPIServerAddr {
// change local cluster event to modified or deleted, since it cannot be re-added or deleted
handleModEvent(localCls, cluster)
localCls = cluster
if argoSettings.InClusterEnabled {
// change local cluster event to modified, since it cannot be added at runtime
handleModEvent(localCls, cluster)
localCls = cluster
}
return
}
handleAddEvent(cluster)
@ -185,10 +195,11 @@ func (db *db) WatchClusters(ctx context.Context,
},
func(secret *corev1.Secret) {
if string(secret.Data["server"]) == appv1.KubernetesInternalAPIServerAddr {
// change local cluster event to modified or deleted, since it cannot be re-added or deleted
handleModEvent(localCls, db.getLocalCluster())
localCls = db.getLocalCluster()
if string(secret.Data["server"]) == appv1.KubernetesInternalAPIServerAddr && argoSettings.InClusterEnabled {
// change local cluster event to modified, since it cannot be deleted at runtime, unless disabled.
newLocalCls := db.getLocalCluster()
handleModEvent(localCls, newLocalCls)
localCls = newLocalCls
} else {
handleDeleteEvent(string(secret.Data["server"]))
}
@ -214,6 +225,14 @@ func (db *db) getClusterSecret(server string) (*corev1.Secret, error) {
// GetCluster returns a cluster from a query
func (db *db) GetCluster(_ context.Context, server string) (*appv1.Cluster, error) {
argoSettings, err := db.settingsMgr.GetSettings()
if err != nil {
return nil, err
}
if server == appv1.KubernetesInternalAPIServerAddr && !argoSettings.InClusterEnabled {
return nil, status.Errorf(codes.NotFound, "cluster %q is disabled", server)
}
informer, err := db.settingsMgr.GetSecretsInformer()
if err != nil {
return nil, err
@ -222,6 +241,7 @@ func (db *db) GetCluster(_ context.Context, server string) (*appv1.Cluster, erro
if err != nil {
return nil, err
}
if len(res) > 0 {
return SecretToCluster(res[0].(*corev1.Secret))
}
@ -254,6 +274,10 @@ func (db *db) GetProjectClusters(_ context.Context, project string) ([]*appv1.Cl
}
func (db *db) GetClusterServersByName(_ context.Context, name string) ([]string, error) {
argoSettings, err := db.settingsMgr.GetSettings()
if err != nil {
return nil, err
}
informer, err := db.settingsMgr.GetSecretsInformer()
if err != nil {
return nil, err
@ -265,7 +289,7 @@ func (db *db) GetClusterServersByName(_ context.Context, name string) ([]string,
return nil, err
}
if len(localClusterSecrets) == 0 && db.getLocalCluster().Name == name {
if len(localClusterSecrets) == 0 && db.getLocalCluster().Name == name && argoSettings.InClusterEnabled {
return []string{appv1.KubernetesInternalAPIServerAddr}, nil
}
@ -276,7 +300,11 @@ func (db *db) GetClusterServersByName(_ context.Context, name string) ([]string,
var res []string
for i := range secrets {
s := secrets[i].(*corev1.Secret)
res = append(res, strings.TrimRight(string(s.Data["server"]), "/"))
server := strings.TrimRight(string(s.Data["server"]), "/")
if !argoSettings.InClusterEnabled && server == appv1.KubernetesInternalAPIServerAddr {
continue
}
res = append(res, server)
}
return res, nil
}

View file

@ -49,7 +49,7 @@ func TestWatchClusters_CreateRemoveCluster(t *testing.T) {
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
completed := runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
assert.Nil(t, old)
assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, new.Server)
@ -72,6 +72,7 @@ func TestWatchClusters_CreateRemoveCluster(t *testing.T) {
assert.Equal(t, "https://minikube", old.Server)
},
})
assert.True(t, completed, "Failed due to timeout")
}
func TestWatchClusters_LocalClusterModifications(t *testing.T) {
@ -104,7 +105,7 @@ func TestWatchClusters_LocalClusterModifications(t *testing.T) {
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
completed := runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
assert.Nil(t, old)
assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, new.Server)
@ -127,4 +128,43 @@ func TestWatchClusters_LocalClusterModifications(t *testing.T) {
assert.Equal(t, "in-cluster", new.Name)
},
})
assert.True(t, completed, "Failed due to timeout")
}
func TestWatchClusters_LocalClusterModificationsWhenDisabled(t *testing.T) {
// !race:
// Intermittent failure when running TestWatchClusters_LocalClusterModifications with -race, likely due to race condition
// https://github.com/argoproj/argo-cd/issues/4755
argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{"cluster.inClusterEnabled": "false"},
}
argoCDSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDSecretName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
}
kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
completed := runWatchTest(t, db, []func(_ *v1alpha1.Cluster, _ *v1alpha1.Cluster){
func(_ *v1alpha1.Cluster, _ *v1alpha1.Cluster) {
assert.Fail(t, "The in-cluster should not be added when disabled")
},
})
assert.False(t, completed, "Expecting the method to never complete because no cluster is ever added")
}

View file

@ -253,7 +253,7 @@ func TestRejectCreationForInClusterWhenDisabled(t *testing.T) {
require.Error(t, err)
}
func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster)) {
func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster)) (completed bool) {
t.Helper()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@ -290,11 +290,144 @@ func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster,
select {
case <-allDone:
return true
case <-time.After(timeout):
assert.Fail(t, "Failed due to timeout")
return false
}
}
func TestGetCluster(t *testing.T) {
emptyArgoCDConfigMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{},
}
argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{"cluster.inClusterEnabled": "false"},
}
argoCDSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDSecretName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
}
secretForServerWithInClusterAddr := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mycluster1",
Namespace: fakeNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
},
Data: map[string][]byte{
"server": []byte(v1alpha1.KubernetesInternalAPIServerAddr),
"name": []byte("in-cluster-renamed"),
},
}
secretForServerWithExternalClusterAddr := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mycluster2",
Namespace: fakeNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
},
Data: map[string][]byte{
"server": []byte("http://mycluster2"),
"name": []byte("mycluster2"),
},
}
t.Run("Valid external cluster", func(t *testing.T) {
kubeclientset := fake.NewClientset(secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
cluster, err := db.GetCluster(context.TODO(), string(secretForServerWithExternalClusterAddr.Data["server"]))
require.NoError(t, err)
assert.Equal(t, string(secretForServerWithExternalClusterAddr.Data["server"]), cluster.Server)
assert.Equal(t, string(secretForServerWithExternalClusterAddr.Data["name"]), cluster.Name)
})
t.Run("invalid cluster", func(t *testing.T) {
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
_, err := db.GetCluster(context.TODO(), "https://mycluster-does-not-exist")
require.Error(t, err)
status, ok := status.FromError(err)
assert.True(t, ok)
assert.Equal(t, codes.NotFound, status.Code())
})
t.Run("in-cluster not configured", func(t *testing.T) {
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
cluster, err := db.GetCluster(context.TODO(), v1alpha1.KubernetesInternalAPIServerAddr)
require.NoError(t, err)
assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, cluster.Server)
assert.Equal(t, "in-cluster", cluster.Name)
})
t.Run("in-cluster disabled", func(t *testing.T) {
kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
_, err := db.GetCluster(context.TODO(), v1alpha1.KubernetesInternalAPIServerAddr)
require.Error(t, err)
status, ok := status.FromError(err)
assert.True(t, ok)
assert.Equal(t, codes.NotFound, status.Code())
})
t.Run("in-cluster configured", func(t *testing.T) {
kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, emptyArgoCDConfigMap, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
cluster, err := db.GetCluster(context.TODO(), v1alpha1.KubernetesInternalAPIServerAddr)
require.NoError(t, err)
assert.Equal(t, v1alpha1.KubernetesInternalAPIServerAddr, cluster.Server)
assert.Equal(t, "in-cluster-renamed", cluster.Name)
})
t.Run("in-cluster configured and disabled", func(t *testing.T) {
kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret)
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
_, err := db.GetCluster(context.TODO(), v1alpha1.KubernetesInternalAPIServerAddr)
require.Error(t, err)
status, ok := status.FromError(err)
assert.True(t, ok)
assert.Equal(t, codes.NotFound, status.Code())
})
}
func TestListClusters(t *testing.T) {
emptyArgoCDConfigMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
@ -421,6 +554,113 @@ func TestListClusters(t *testing.T) {
})
}
func TestGetClusterServersByName(t *testing.T) {
emptyArgoCDConfigMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{},
}
argoCDSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDSecretName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
}
argoCDConfigMapWithInClusterServerAddressDisabled := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: fakeNamespace,
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{"cluster.inClusterEnabled": "false"},
}
argoCDSecretInClusterConfigured := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster-secret",
Namespace: fakeNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Annotations: map[string]string{
common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
},
},
Data: map[string][]byte{
"name": []byte("in-cluster-renamed"),
"server": []byte(v1alpha1.KubernetesInternalAPIServerAddr),
"config": []byte("{}"),
},
}
t.Run("returns the server name", func(t *testing.T) {
argoCDClusterSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster-secret",
Namespace: fakeNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Annotations: map[string]string{
common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
},
},
Data: map[string][]byte{
"name": []byte("my-cluster-name"),
"server": []byte("https://my-cluster-server"),
"config": []byte("{}"),
},
}
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDClusterSecret, argoCDSecret)
db := NewDB(fakeNamespace, settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace), kubeclientset)
servers, err := db.GetClusterServersByName(context.Background(), "my-cluster-name")
require.NoError(t, err)
assert.ElementsMatch(t, []string{"https://my-cluster-server"}, servers)
})
t.Run("returns in-cluster", func(t *testing.T) {
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret)
db := NewDB(fakeNamespace, settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace), kubeclientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster")
require.NoError(t, err)
assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers)
})
t.Run("does not return in-cluster when disabled", func(t *testing.T) {
kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret)
db := NewDB(fakeNamespace, settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace), kubeclientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster")
require.NoError(t, err)
assert.Empty(t, servers)
})
t.Run("returns in-cluster when configured", func(t *testing.T) {
kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecretInClusterConfigured, argoCDSecret)
db := NewDB(fakeNamespace, settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace), kubeclientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster-renamed")
require.NoError(t, err)
assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers)
})
t.Run("does not return in-cluster when configured and disabled", func(t *testing.T) {
kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecretInClusterConfigured, argoCDSecret)
db := NewDB(fakeNamespace, settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace), kubeclientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster-renamed")
require.NoError(t, err)
assert.Empty(t, servers)
})
}
// TestClusterRaceConditionClusterSecrets reproduces a race condition
// on the cluster secrets. The test isn't asserting anything because
// before the fix it would cause a panic from concurrent map iteration and map write

View file

@ -502,42 +502,6 @@ func TestRepositorySecretsTrim(t *testing.T) {
}
}
func TestGetClusterSuccessful(t *testing.T) {
server := "my-cluster"
name := "my-name"
clientset := getClientset(nil, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
},
Data: map[string][]byte{
"server": []byte(server),
"name": []byte(name),
"config": []byte("{}"),
},
})
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
cluster, err := db.GetCluster(context.Background(), server)
require.NoError(t, err)
assert.Equal(t, server, cluster.Server)
assert.Equal(t, name, cluster.Name)
}
func TestGetNonExistingCluster(t *testing.T) {
server := "https://mycluster"
clientset := getClientset(nil)
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
_, err := db.GetCluster(context.Background(), server)
require.Error(t, err)
status, ok := status.FromError(err)
assert.True(t, ok)
assert.Equal(t, codes.NotFound, status.Code())
}
func TestCreateClusterSuccessful(t *testing.T) {
server := "https://mycluster"
clientset := getClientset(nil)
@ -752,62 +716,6 @@ func TestHelmRepositorySecretsTrim(t *testing.T) {
}
}
func TestGetClusterServersByName(t *testing.T) {
clientset := getClientset(nil, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster-secret",
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Annotations: map[string]string{
common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
},
},
Data: map[string][]byte{
"name": []byte("my-cluster-name"),
"server": []byte("https://my-cluster-server"),
"config": []byte("{}"),
},
})
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
servers, err := db.GetClusterServersByName(context.Background(), "my-cluster-name")
require.NoError(t, err)
assert.ElementsMatch(t, []string{"https://my-cluster-server"}, servers)
}
func TestGetClusterServersByName_InClusterNotConfigured(t *testing.T) {
clientset := getClientset(nil)
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster")
require.NoError(t, err)
assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers)
}
func TestGetClusterServersByName_InClusterConfigured(t *testing.T) {
clientset := getClientset(nil, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster-secret",
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Annotations: map[string]string{
common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
},
},
Data: map[string][]byte{
"name": []byte("in-cluster-renamed"),
"server": []byte(v1alpha1.KubernetesInternalAPIServerAddr),
"config": []byte("{}"),
},
})
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster-renamed")
require.NoError(t, err)
assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers)
}
func TestGetApplicationControllerReplicas(t *testing.T) {
clientset := getClientset(nil)
expectedReplicas := int32(2)