github.com/argoproj/argo-cd/v2@v2.10.5/test/e2e/cluster_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	. "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
    14  	"github.com/argoproj/argo-cd/v2/test/e2e/fixture"
    15  	. "github.com/argoproj/argo-cd/v2/test/e2e/fixture"
    16  	accountFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/account"
    17  	"github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
    18  	clusterFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/cluster"
    19  	. "github.com/argoproj/argo-cd/v2/util/errors"
    20  )
    21  
    22  func TestClusterList(t *testing.T) {
    23  	SkipIfAlreadyRun(t)
    24  	defer RecordTestRun(t)
    25  
    26  	last := ""
    27  	expected := fmt.Sprintf(`SERVER                          NAME        VERSION  STATUS      MESSAGE  PROJECT
    28  https://kubernetes.default.svc  in-cluster  %v     Successful           `, GetVersions().ServerVersion)
    29  
    30  	clusterFixture.
    31  		Given(t).
    32  		Project(ProjectName)
    33  
    34  	// We need an application targeting the cluster, otherwise the test will
    35  	// fail if run isolated.
    36  	app.GivenWithSameState(t).
    37  		Path(guestbookPath).
    38  		When().
    39  		CreateApp()
    40  
    41  	tries := 5
    42  	for i := 0; i <= tries; i += 1 {
    43  		clusterFixture.GivenWithSameState(t).
    44  			When().
    45  			List().
    46  			Then().
    47  			AndCLIOutput(func(output string, err error) {
    48  				last = output
    49  			})
    50  		if expected == last {
    51  			break
    52  		} else if i < tries {
    53  			// We retry with a simple backoff
    54  			time.Sleep(time.Duration(i+1) * time.Second)
    55  		}
    56  	}
    57  	assert.Equal(t, expected, last)
    58  }
    59  
    60  func TestClusterAdd(t *testing.T) {
    61  	clusterFixture.
    62  		Given(t).
    63  		Project(ProjectName).
    64  		Upsert(true).
    65  		Server(KubernetesInternalAPIServerAddr).
    66  		When().
    67  		Create().
    68  		List().
    69  		Then().
    70  		AndCLIOutput(func(output string, err error) {
    71  			assert.Equal(t, fmt.Sprintf(`SERVER                          NAME              VERSION  STATUS      MESSAGE  PROJECT
    72  https://kubernetes.default.svc  test-cluster-add  %v     Successful           %s`, GetVersions().ServerVersion, ProjectName), output)
    73  		})
    74  }
    75  
    76  func TestClusterAddPermissionDenied(t *testing.T) {
    77  	accountFixture.Given(t).
    78  		Name("test").
    79  		When().
    80  		Create().
    81  		Login().
    82  		SetPermissions([]fixture.ACL{}, "org-admin")
    83  
    84  	clusterFixture.
    85  		GivenWithSameState(t).
    86  		Project(ProjectName).
    87  		Upsert(true).
    88  		Server(KubernetesInternalAPIServerAddr).
    89  		When().
    90  		IgnoreErrors().
    91  		Create().
    92  		Then().
    93  		AndCLIOutput(func(output string, err error) {
    94  			assert.True(t, strings.Contains(err.Error(), "PermissionDenied desc = permission denied: clusters, create"))
    95  		})
    96  }
    97  
    98  func TestClusterAddAllowed(t *testing.T) {
    99  	accountFixture.Given(t).
   100  		Name("test").
   101  		When().
   102  		Create().
   103  		Login().
   104  		SetPermissions([]fixture.ACL{
   105  			{
   106  				Resource: "clusters",
   107  				Action:   "create",
   108  				Scope:    ProjectName + "/*",
   109  			},
   110  			{
   111  				Resource: "clusters",
   112  				Action:   "get",
   113  				Scope:    ProjectName + "/*",
   114  			},
   115  		}, "org-admin")
   116  
   117  	clusterFixture.
   118  		GivenWithSameState(t).
   119  		Project(ProjectName).
   120  		Upsert(true).
   121  		Server(KubernetesInternalAPIServerAddr).
   122  		When().
   123  		Create().
   124  		List().
   125  		Then().
   126  		AndCLIOutput(func(output string, err error) {
   127  			assert.Equal(t, fmt.Sprintf(`SERVER                          NAME                      VERSION  STATUS      MESSAGE  PROJECT
   128  https://kubernetes.default.svc  test-cluster-add-allowed  %v     Successful           argo-project`, GetVersions().ServerVersion), output)
   129  		})
   130  }
   131  
   132  func TestClusterListDenied(t *testing.T) {
   133  	accountFixture.Given(t).
   134  		Name("test").
   135  		When().
   136  		Create().
   137  		Login().
   138  		SetPermissions([]fixture.ACL{
   139  			{
   140  				Resource: "clusters",
   141  				Action:   "create",
   142  				Scope:    ProjectName + "/*",
   143  			},
   144  		}, "org-admin")
   145  
   146  	clusterFixture.
   147  		GivenWithSameState(t).
   148  		Project(ProjectName).
   149  		Upsert(true).
   150  		Server(KubernetesInternalAPIServerAddr).
   151  		When().
   152  		Create().
   153  		List().
   154  		Then().
   155  		AndCLIOutput(func(output string, err error) {
   156  			assert.Equal(t, output, "SERVER  NAME  VERSION  STATUS  MESSAGE  PROJECT")
   157  		})
   158  }
   159  
   160  func TestClusterSet(t *testing.T) {
   161  	EnsureCleanState(t)
   162  	defer RecordTestRun(t)
   163  	clusterFixture.
   164  		GivenWithSameState(t).
   165  		Project(ProjectName).
   166  		Name("in-cluster").
   167  		Namespaces([]string{"namespace-edit-1", "namespace-edit-2"}).
   168  		Server(KubernetesInternalAPIServerAddr).
   169  		When().
   170  		SetNamespaces().
   171  		GetByName("in-cluster").
   172  		Then().
   173  		AndCLIOutput(func(output string, err error) {
   174  			assert.True(t, strings.Contains(output, "namespace-edit-1"))
   175  			assert.True(t, strings.Contains(output, "namespace-edit-2"))
   176  		})
   177  }
   178  
   179  func TestClusterGet(t *testing.T) {
   180  	SkipIfAlreadyRun(t)
   181  	EnsureCleanState(t)
   182  	defer RecordTestRun(t)
   183  	output := FailOnErr(RunCli("cluster", "get", "https://kubernetes.default.svc")).(string)
   184  
   185  	assert.Contains(t, output, "name: in-cluster")
   186  	assert.Contains(t, output, "server: https://kubernetes.default.svc")
   187  	assert.Contains(t, output, fmt.Sprintf(`serverVersion: "%v"`, GetVersions().ServerVersion))
   188  	assert.Contains(t, output, `config:
   189    tlsClientConfig:
   190      insecure: false`)
   191  
   192  	assert.Contains(t, output, `status: Successful`)
   193  }
   194  
   195  func TestClusterNameInRestAPI(t *testing.T) {
   196  	EnsureCleanState(t)
   197  
   198  	var cluster Cluster
   199  	err := DoHttpJsonRequest("GET", "/api/v1/clusters/in-cluster?id.type=name", &cluster)
   200  	require.NoError(t, err)
   201  
   202  	assert.Equal(t, cluster.Name, "in-cluster")
   203  	assert.Contains(t, cluster.Server, "https://kubernetes.default.svc")
   204  
   205  	err = DoHttpJsonRequest("PUT",
   206  		"/api/v1/clusters/in-cluster?id.type=name&updatedFields=labels", &cluster, []byte(`{"labels":{"test": "val"}}`)...)
   207  	require.NoError(t, err)
   208  	assert.Equal(t, map[string]string{"test": "val"}, cluster.Labels)
   209  }
   210  
   211  func TestClusterURLInRestAPI(t *testing.T) {
   212  	EnsureCleanState(t)
   213  
   214  	clusterURL := url.QueryEscape(KubernetesInternalAPIServerAddr)
   215  
   216  	var cluster Cluster
   217  	err := DoHttpJsonRequest("GET", fmt.Sprintf("/api/v1/clusters/%s", clusterURL), &cluster)
   218  	require.NoError(t, err)
   219  
   220  	assert.Equal(t, cluster.Name, "in-cluster")
   221  	assert.Contains(t, cluster.Server, "https://kubernetes.default.svc")
   222  
   223  	err = DoHttpJsonRequest("PUT",
   224  		fmt.Sprintf("/api/v1/clusters/%s?&updatedFields=labels", clusterURL), &cluster, []byte(`{"labels":{"test": "val"}}`)...)
   225  	require.NoError(t, err)
   226  	assert.Equal(t, map[string]string{"test": "val"}, cluster.Labels)
   227  }
   228  
   229  func TestClusterDeleteDenied(t *testing.T) {
   230  	accountFixture.Given(t).
   231  		Name("test").
   232  		When().
   233  		Create().
   234  		Login().
   235  		SetPermissions([]fixture.ACL{
   236  			{
   237  				Resource: "clusters",
   238  				Action:   "create",
   239  				Scope:    ProjectName + "/*",
   240  			},
   241  			{
   242  				Resource: "clusters",
   243  				Action:   "get",
   244  				Scope:    ProjectName + "/*",
   245  			},
   246  		}, "org-admin")
   247  
   248  	// Attempt to remove cluster creds by name
   249  	clusterFixture.
   250  		GivenWithSameState(t).
   251  		Project(ProjectName).
   252  		Upsert(true).
   253  		Server(KubernetesInternalAPIServerAddr).
   254  		When().
   255  		Create().
   256  		DeleteByName().
   257  		Then().
   258  		AndCLIOutput(func(output string, err error) {
   259  			assert.True(t, strings.Contains(err.Error(), "PermissionDenied desc = permission denied: clusters, delete"))
   260  		})
   261  
   262  	// Attempt to remove cluster creds by server
   263  	clusterFixture.
   264  		GivenWithSameState(t).
   265  		Project(ProjectName).
   266  		Upsert(true).
   267  		Server(KubernetesInternalAPIServerAddr).
   268  		When().
   269  		Create().
   270  		DeleteByServer().
   271  		Then().
   272  		AndCLIOutput(func(output string, err error) {
   273  			assert.True(t, strings.Contains(err.Error(), "PermissionDenied desc = permission denied: clusters, delete"))
   274  		})
   275  }
   276  
   277  func TestClusterDelete(t *testing.T) {
   278  	accountFixture.Given(t).
   279  		Name("default").
   280  		When().
   281  		Create().
   282  		Login().
   283  		SetPermissions([]fixture.ACL{
   284  			{
   285  				Resource: "clusters",
   286  				Action:   "create",
   287  				Scope:    ProjectName + "/*",
   288  			},
   289  			{
   290  				Resource: "clusters",
   291  				Action:   "get",
   292  				Scope:    ProjectName + "/*",
   293  			},
   294  			{
   295  				Resource: "clusters",
   296  				Action:   "delete",
   297  				Scope:    ProjectName + "/*",
   298  			},
   299  		}, "org-admin")
   300  
   301  	clstAction := clusterFixture.
   302  		GivenWithSameState(t).
   303  		Name("default").
   304  		Project(ProjectName).
   305  		Upsert(true).
   306  		Server(KubernetesInternalAPIServerAddr).
   307  		When().
   308  		CreateWithRBAC()
   309  
   310  	// Check that RBAC is created
   311  	_, err := fixture.Run("", "kubectl", "get", "serviceaccount", "argocd-manager", "-n", "kube-system")
   312  	if err != nil {
   313  		t.Errorf("Expected no error from not finding serviceaccount argocd-manager but got:\n%s", err.Error())
   314  	}
   315  
   316  	_, err = fixture.Run("", "kubectl", "get", "clusterrole", "argocd-manager-role")
   317  	if err != nil {
   318  		t.Errorf("Expected no error from not finding clusterrole argocd-manager-role but got:\n%s", err.Error())
   319  	}
   320  
   321  	_, err = fixture.Run("", "kubectl", "get", "clusterrolebinding", "argocd-manager-role-binding")
   322  	if err != nil {
   323  		t.Errorf("Expected no error from not finding clusterrolebinding argocd-manager-role-binding but got:\n%s", err.Error())
   324  	}
   325  
   326  	clstAction.DeleteByName().
   327  		Then().
   328  		AndCLIOutput(func(output string, err error) {
   329  			assert.Equal(t, "Cluster 'default' removed", output)
   330  		})
   331  
   332  	// Check that RBAC is removed after delete
   333  	output, err := fixture.Run("", "kubectl", "get", "serviceaccount", "argocd-manager", "-n", "kube-system")
   334  	if err == nil {
   335  		t.Errorf("Expected error from not finding serviceaccount argocd-manager but got:\n%s", output)
   336  	}
   337  
   338  	output, err = fixture.Run("", "kubectl", "get", "clusterrole", "argocd-manager-role")
   339  	if err == nil {
   340  		t.Errorf("Expected error from not finding clusterrole argocd-manager-role but got:\n%s", output)
   341  	}
   342  
   343  	output, err = fixture.Run("", "kubectl", "get", "clusterrolebinding", "argocd-manager-role-binding")
   344  	if err == nil {
   345  		t.Errorf("Expected error from not finding clusterrolebinding argocd-manager-role-binding but got:\n%s", output)
   346  	}
   347  }