From 125f5b013bc12717864d6e6f56518b96c60910a8 Mon Sep 17 00:00:00 2001 From: John Pitman Date: Wed, 16 Sep 2020 16:08:52 -0400 Subject: [PATCH] fix: raise error if app dest namespace not managed by argocd Signed-off-by: John Pitman --- util/argo/argo.go | 20 ++++++++++++ util/argo/argo_test.go | 73 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/util/argo/argo.go b/util/argo/argo.go index a72a5f3f5bf11..1359ffd07c8bd 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -235,6 +235,7 @@ func enrichSpec(spec *argoappv1.ApplicationSpec, appDetails *apiclient.RepoAppDe // ValidateDestination checks: // if we used destination name we infer the server url // if we used both name and server then we return an invalid spec error +// if we specified a namespace that is not managed by argo, then we return an invalid spec error func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestination, db db.ArgoDB) error { if dest.Name != "" { if dest.Server == "" { @@ -252,6 +253,25 @@ func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestina } } } + + cluster, err := db.GetCluster(ctx, dest.Server) + if err != nil { + return fmt.Errorf("unable to find cluster for destination server: %s: %v", dest.Server, err) + } + if len(cluster.Namespaces) > 0 { + found := false + for _, v := range cluster.Namespaces { + if v == dest.Namespace { + // don't return nil here, otherwise if other checks are added after, this code would need to be changed + found = true + break + } + } + if !found { + return fmt.Errorf("application destination namespace is not managed by ArgoCD: %s", dest.Namespace) + } + } + return nil } diff --git a/util/argo/argo_test.go b/util/argo/argo_test.go index 8bf0e0a65b328..52884a345ff7b 100644 --- a/util/argo/argo_test.go +++ b/util/argo/argo_test.go @@ -557,7 +557,13 @@ func TestValidateDestination(t *testing.T) { Namespace: "default", } - appCond := ValidateDestination(context.Background(), &dest, nil) + db := &dbmocks.ArgoDB{} + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{ + Name: "minikube", + Server: "https://127.0.0.1:6443", + }, nil) + + appCond := ValidateDestination(context.Background(), &dest, db) assert.Nil(t, appCond) assert.False(t, dest.IsServerInferred()) }) @@ -577,6 +583,11 @@ func TestValidateDestination(t *testing.T) { }, }, nil) + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{ + Name: "minikube", + Server: "https://127.0.0.1:6443", + }, nil) + appCond := ValidateDestination(context.Background(), &dest, db) assert.Nil(t, appCond) assert.Equal(t, "https://127.0.0.1:6443", dest.Server) @@ -652,4 +663,64 @@ func TestValidateDestination(t *testing.T) { assert.False(t, dest.IsServerInferred()) }) + t.Run("Validate cluster manages all namespaces", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Server: "https://127.0.0.1:6443", + Namespace: "default", + } + + db := &dbmocks.ArgoDB{} + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{ + Name: "minikube", + Server: "https://127.0.0.1:6443", + Namespaces: nil, + }, nil) + + appCond := ValidateDestination(context.Background(), &dest, db) + assert.Nil(t, appCond) + + db = &dbmocks.ArgoDB{} + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{ + Name: "minikube", + Server: "https://127.0.0.1:6443", + Namespaces: []string{}, + }, nil) + + appCond = ValidateDestination(context.Background(), &dest, db) + assert.Nil(t, appCond) + }) + + t.Run("Validate destination namespace in cluster managed namespaces", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Server: "https://127.0.0.1:6443", + Namespace: "develop", + } + + db := &dbmocks.ArgoDB{} + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{ + Name: "minikube", + Server: "https://127.0.0.1:6443", + Namespaces: []string{"default", "develop"}, + }, nil) + + appCond := ValidateDestination(context.Background(), &dest, db) + assert.Nil(t, appCond) + }) + + t.Run("Validate destination namespace not in cluster managed namespaces", func(t *testing.T) { + dest := argoappv1.ApplicationDestination{ + Server: "https://127.0.0.1:6443", + Namespace: "develop", + } + + db := &dbmocks.ArgoDB{} + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&argoappv1.Cluster{ + Name: "minikube", + Server: "https://127.0.0.1:6443", + Namespaces: []string{"default"}, + }, nil) + + err := ValidateDestination(context.Background(), &dest, db) + assert.Equal(t, "application destination namespace is not managed by ArgoCD: develop", err.Error()) + }) }