github.com/argoproj/argo-cd@v1.8.7/test/e2e/project_management_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"k8s.io/apimachinery/pkg/api/errors"
    14  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	"k8s.io/apimachinery/pkg/fields"
    16  	"k8s.io/utils/pointer"
    17  
    18  	"github.com/argoproj/argo-cd/common"
    19  	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
    20  	"github.com/argoproj/argo-cd/test/e2e/fixture"
    21  	"github.com/argoproj/argo-cd/util/argo"
    22  )
    23  
    24  func assertProjHasEvent(t *testing.T, a *v1alpha1.AppProject, message string, reason string) {
    25  	list, err := fixture.KubeClientset.CoreV1().Events(fixture.ArgoCDNamespace).List(context.Background(), metav1.ListOptions{
    26  		FieldSelector: fields.SelectorFromSet(map[string]string{
    27  			"involvedObject.name":      a.Name,
    28  			"involvedObject.uid":       string(a.UID),
    29  			"involvedObject.namespace": fixture.ArgoCDNamespace,
    30  		}).String(),
    31  	})
    32  	assert.NoError(t, err)
    33  
    34  	for i := range list.Items {
    35  		event := list.Items[i]
    36  		if event.Reason == reason && strings.Contains(event.Message, message) {
    37  			return
    38  		}
    39  	}
    40  	t.Errorf("Unable to find event with reason=%s; message=%s", reason, message)
    41  }
    42  
    43  func TestProjectCreation(t *testing.T) {
    44  	fixture.EnsureCleanState(t)
    45  
    46  	projectName := "proj-" + fixture.Name()
    47  	_, err := fixture.RunCli("proj", "create", projectName,
    48  		"--description", "Test description",
    49  		"-d", "https://192.168.99.100:8443,default",
    50  		"-d", "https://192.168.99.100:8443,service",
    51  		"-s", "https://github.com/argoproj/argo-cd.git",
    52  		"--orphaned-resources")
    53  	assert.Nil(t, err)
    54  
    55  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
    56  	assert.NoError(t, err)
    57  	assert.Equal(t, projectName, proj.Name)
    58  	assert.Equal(t, 2, len(proj.Spec.Destinations))
    59  
    60  	assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[0].Server)
    61  	assert.Equal(t, "default", proj.Spec.Destinations[0].Namespace)
    62  
    63  	assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[1].Server)
    64  	assert.Equal(t, "service", proj.Spec.Destinations[1].Namespace)
    65  
    66  	assert.Equal(t, 1, len(proj.Spec.SourceRepos))
    67  	assert.Equal(t, "https://github.com/argoproj/argo-cd.git", proj.Spec.SourceRepos[0])
    68  
    69  	assert.NotNil(t, proj.Spec.OrphanedResources)
    70  	assert.True(t, proj.Spec.OrphanedResources.IsWarn())
    71  
    72  	assertProjHasEvent(t, proj, "create", argo.EventReasonResourceCreated)
    73  
    74  	// create a manifest with the same name to upsert
    75  	newDescription := "Upserted description"
    76  	proj.Spec.Description = newDescription
    77  	proj.ResourceVersion = ""
    78  	data, err := json.Marshal(proj)
    79  	stdinString := string(data)
    80  	assert.NoError(t, err)
    81  
    82  	// fail without upsert flag
    83  	_, err = fixture.RunCliWithStdin(stdinString, "proj", "create",
    84  		"-f", "-")
    85  	assert.Error(t, err)
    86  
    87  	// succeed with the upsert flag
    88  	_, err = fixture.RunCliWithStdin(stdinString, "proj", "create",
    89  		"-f", "-", "--upsert")
    90  	assert.NoError(t, err)
    91  	proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
    92  	assert.NoError(t, err)
    93  	assert.Equal(t, newDescription, proj.Spec.Description)
    94  }
    95  
    96  func TestProjectDeletion(t *testing.T) {
    97  	fixture.EnsureCleanState(t)
    98  
    99  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   100  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(
   101  		context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{})
   102  	assert.NoError(t, err)
   103  
   104  	_, err = fixture.RunCli("proj", "delete", projectName)
   105  	assert.NoError(t, err)
   106  
   107  	_, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   108  	assert.True(t, errors.IsNotFound(err))
   109  	assertProjHasEvent(t, proj, "delete", argo.EventReasonResourceDeleted)
   110  }
   111  
   112  func TestSetProject(t *testing.T) {
   113  	fixture.EnsureCleanState(t)
   114  
   115  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   116  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(
   117  		context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{})
   118  	assert.NoError(t, err)
   119  
   120  	_, err = fixture.RunCli("proj", "set", projectName,
   121  		"--description", "updated description",
   122  		"-d", "https://192.168.99.100:8443,default",
   123  		"-d", "https://192.168.99.100:8443,service",
   124  		"--orphaned-resources-warn=false")
   125  	assert.NoError(t, err)
   126  
   127  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   128  	assert.NoError(t, err)
   129  	assert.Equal(t, projectName, proj.Name)
   130  	assert.Equal(t, 2, len(proj.Spec.Destinations))
   131  
   132  	assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[0].Server)
   133  	assert.Equal(t, "default", proj.Spec.Destinations[0].Namespace)
   134  
   135  	assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[1].Server)
   136  	assert.Equal(t, "service", proj.Spec.Destinations[1].Namespace)
   137  
   138  	assert.NotNil(t, proj.Spec.OrphanedResources)
   139  	assert.False(t, proj.Spec.OrphanedResources.IsWarn())
   140  
   141  	assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
   142  }
   143  
   144  func TestAddProjectDestination(t *testing.T) {
   145  	fixture.EnsureCleanState(t)
   146  
   147  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   148  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(
   149  		context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{})
   150  	if err != nil {
   151  		t.Fatalf("Unable to create project %v", err)
   152  	}
   153  
   154  	_, err = fixture.RunCli("proj", "add-destination", projectName,
   155  		"https://192.168.99.100:8443",
   156  		"test1",
   157  	)
   158  
   159  	if err != nil {
   160  		t.Fatalf("Unable to add project destination %v", err)
   161  	}
   162  
   163  	_, err = fixture.RunCli("proj", "add-destination", projectName,
   164  		"https://192.168.99.100:8443",
   165  		"test1",
   166  	)
   167  	assert.Error(t, err)
   168  	assert.True(t, strings.Contains(err.Error(), "already defined"))
   169  
   170  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   171  	assert.NoError(t, err)
   172  	assert.Equal(t, projectName, proj.Name)
   173  	assert.Equal(t, 1, len(proj.Spec.Destinations))
   174  
   175  	assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[0].Server)
   176  	assert.Equal(t, "test1", proj.Spec.Destinations[0].Namespace)
   177  	assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
   178  }
   179  
   180  func TestRemoveProjectDestination(t *testing.T) {
   181  	fixture.EnsureCleanState(t)
   182  
   183  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   184  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(context.Background(), &v1alpha1.AppProject{
   185  		ObjectMeta: metav1.ObjectMeta{Name: projectName},
   186  		Spec: v1alpha1.AppProjectSpec{
   187  			Destinations: []v1alpha1.ApplicationDestination{{
   188  				Server:    "https://192.168.99.100:8443",
   189  				Namespace: "test",
   190  			}},
   191  		},
   192  	}, metav1.CreateOptions{})
   193  
   194  	if err != nil {
   195  		t.Fatalf("Unable to create project %v", err)
   196  	}
   197  
   198  	_, err = fixture.RunCli("proj", "remove-destination", projectName,
   199  		"https://192.168.99.100:8443",
   200  		"test",
   201  	)
   202  
   203  	if err != nil {
   204  		t.Fatalf("Unable to remove project destination %v", err)
   205  	}
   206  
   207  	_, err = fixture.RunCli("proj", "remove-destination", projectName,
   208  		"https://192.168.99.100:8443",
   209  		"test1",
   210  	)
   211  	assert.Error(t, err)
   212  	assert.Contains(t, err.Error(), "does not exist")
   213  
   214  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   215  	if err != nil {
   216  		t.Fatalf("Unable to get project %v", err)
   217  	}
   218  	assert.Equal(t, projectName, proj.Name)
   219  	assert.Equal(t, 0, len(proj.Spec.Destinations))
   220  	assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
   221  }
   222  
   223  func TestAddProjectSource(t *testing.T) {
   224  	fixture.EnsureCleanState(t)
   225  
   226  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   227  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(
   228  		context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{})
   229  	if err != nil {
   230  		t.Fatalf("Unable to create project %v", err)
   231  	}
   232  
   233  	_, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git")
   234  
   235  	if err != nil {
   236  		t.Fatalf("Unable to add project source %v", err)
   237  	}
   238  
   239  	_, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git")
   240  	assert.Nil(t, err)
   241  
   242  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   243  	assert.NoError(t, err)
   244  	assert.Equal(t, projectName, proj.Name)
   245  	assert.Equal(t, 1, len(proj.Spec.SourceRepos))
   246  
   247  	assert.Equal(t, "https://github.com/argoproj/argo-cd.git", proj.Spec.SourceRepos[0])
   248  }
   249  
   250  func TestRemoveProjectSource(t *testing.T) {
   251  	fixture.EnsureCleanState(t)
   252  
   253  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   254  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(context.Background(), &v1alpha1.AppProject{
   255  		ObjectMeta: metav1.ObjectMeta{Name: projectName},
   256  		Spec: v1alpha1.AppProjectSpec{
   257  			SourceRepos: []string{"https://github.com/argoproj/argo-cd.git"},
   258  		},
   259  	}, metav1.CreateOptions{})
   260  
   261  	assert.NoError(t, err)
   262  
   263  	_, err = fixture.RunCli("proj", "remove-source", projectName, "https://github.com/argoproj/argo-cd.git")
   264  
   265  	assert.NoError(t, err)
   266  
   267  	_, err = fixture.RunCli("proj", "remove-source", projectName, "https://github.com/argoproj/argo-cd.git")
   268  	assert.NoError(t, err)
   269  
   270  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   271  	assert.NoError(t, err)
   272  	assert.Equal(t, projectName, proj.Name)
   273  	assert.Equal(t, 0, len(proj.Spec.SourceRepos))
   274  	assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
   275  }
   276  
   277  func TestUseJWTToken(t *testing.T) {
   278  	fixture.EnsureCleanState(t)
   279  
   280  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   281  	appName := "app-" + strconv.FormatInt(time.Now().Unix(), 10)
   282  	roleName := "roleTest"
   283  	testApp := &v1alpha1.Application{
   284  		ObjectMeta: metav1.ObjectMeta{
   285  			Name: appName,
   286  		},
   287  		Spec: v1alpha1.ApplicationSpec{
   288  			Source: v1alpha1.ApplicationSource{
   289  				RepoURL: fixture.RepoURL(fixture.RepoURLTypeFile),
   290  				Path:    "guestbook",
   291  			},
   292  			Destination: v1alpha1.ApplicationDestination{
   293  				Server:    common.KubernetesInternalAPIServerAddr,
   294  				Namespace: fixture.ArgoCDNamespace,
   295  			},
   296  			Project: projectName,
   297  		},
   298  	}
   299  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(context.Background(), &v1alpha1.AppProject{
   300  		ObjectMeta: metav1.ObjectMeta{Name: projectName},
   301  		Spec: v1alpha1.AppProjectSpec{
   302  			Destinations: []v1alpha1.ApplicationDestination{{
   303  				Server:    common.KubernetesInternalAPIServerAddr,
   304  				Namespace: fixture.ArgoCDNamespace,
   305  			}},
   306  			SourceRepos: []string{"*"},
   307  		},
   308  	}, metav1.CreateOptions{})
   309  	assert.Nil(t, err)
   310  
   311  	_, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Create(context.Background(), testApp, metav1.CreateOptions{})
   312  	assert.NoError(t, err)
   313  
   314  	_, err = fixture.RunCli("proj", "role", "create", projectName, roleName)
   315  	assert.NoError(t, err)
   316  
   317  	roleGetResult, err := fixture.RunCli("proj", "role", "get", projectName, roleName)
   318  	assert.NoError(t, err)
   319  	assert.True(t, strings.HasSuffix(roleGetResult, "ID  ISSUED-AT  EXPIRES-AT"))
   320  
   321  	_, err = fixture.RunCli("proj", "role", "create-token", projectName, roleName)
   322  	assert.NoError(t, err)
   323  
   324  	for _, action := range []string{"get", "update", "sync", "create", "override", "*"} {
   325  		_, err = fixture.RunCli("proj", "role", "add-policy", projectName, roleName, "-a", action, "-o", "*", "-p", "allow")
   326  		assert.NoError(t, err)
   327  	}
   328  
   329  	newProj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   330  	assert.NoError(t, err)
   331  	assert.Len(t, newProj.Status.JWTTokensByRole[roleName].Items, 1)
   332  	assert.ElementsMatch(t, newProj.Status.JWTTokensByRole[roleName].Items, newProj.Spec.Roles[0].JWTTokens)
   333  
   334  	roleGetResult, err = fixture.RunCli("proj", "role", "get", projectName, roleName)
   335  	assert.NoError(t, err)
   336  	assert.True(t, strings.Contains(roleGetResult, strconv.FormatInt((newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt), 10)))
   337  
   338  	_, err = fixture.RunCli("proj", "role", "delete-token", projectName, roleName, strconv.FormatInt((newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt), 10))
   339  	assert.NoError(t, err)
   340  	newProj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   341  	assert.NoError(t, err)
   342  	assert.Nil(t, newProj.Status.JWTTokensByRole[roleName].Items)
   343  	assert.Nil(t, newProj.Spec.Roles[0].JWTTokens)
   344  
   345  }
   346  
   347  func TestAddOrphanedIgnore(t *testing.T) {
   348  	fixture.EnsureCleanState(t)
   349  
   350  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   351  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(
   352  		context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{})
   353  	if err != nil {
   354  		t.Fatalf("Unable to create project %v", err)
   355  	}
   356  
   357  	_, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName,
   358  		"group",
   359  		"kind",
   360  		"--name",
   361  		"name",
   362  	)
   363  
   364  	if err != nil {
   365  		t.Fatalf("Unable to add resource to orphaned ignore %v", err)
   366  	}
   367  
   368  	_, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName,
   369  		"group",
   370  		"kind",
   371  		"--name",
   372  		"name",
   373  	)
   374  	assert.Error(t, err)
   375  	assert.True(t, strings.Contains(err.Error(), "already defined"))
   376  
   377  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   378  	assert.NoError(t, err)
   379  	assert.Equal(t, projectName, proj.Name)
   380  	assert.Equal(t, 1, len(proj.Spec.OrphanedResources.Ignore))
   381  
   382  	assert.Equal(t, "group", proj.Spec.OrphanedResources.Ignore[0].Group)
   383  	assert.Equal(t, "kind", proj.Spec.OrphanedResources.Ignore[0].Kind)
   384  	assert.Equal(t, "name", proj.Spec.OrphanedResources.Ignore[0].Name)
   385  	assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
   386  }
   387  
   388  func TestRemoveOrphanedIgnore(t *testing.T) {
   389  	fixture.EnsureCleanState(t)
   390  
   391  	projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10)
   392  	_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Create(context.Background(), &v1alpha1.AppProject{
   393  		ObjectMeta: metav1.ObjectMeta{Name: projectName},
   394  		Spec: v1alpha1.AppProjectSpec{
   395  			OrphanedResources: &v1alpha1.OrphanedResourcesMonitorSettings{
   396  				Warn:   pointer.BoolPtr(true),
   397  				Ignore: []v1alpha1.OrphanedResourceKey{{Group: "group", Kind: "kind", Name: "name"}},
   398  			},
   399  		},
   400  	}, metav1.CreateOptions{})
   401  
   402  	if err != nil {
   403  		t.Fatalf("Unable to create project %v", err)
   404  	}
   405  
   406  	_, err = fixture.RunCli("proj", "remove-orphaned-ignore", projectName,
   407  		"group",
   408  		"kind",
   409  		"--name",
   410  		"name",
   411  	)
   412  
   413  	if err != nil {
   414  		t.Fatalf("Unable to remove resource from orphaned ignore list %v", err)
   415  	}
   416  
   417  	_, err = fixture.RunCli("proj", "remove-orphaned-ignore", projectName,
   418  		"group",
   419  		"kind",
   420  		"--name",
   421  		"name",
   422  	)
   423  	assert.Error(t, err)
   424  	assert.Contains(t, err.Error(), "does not exist")
   425  
   426  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   427  	if err != nil {
   428  		t.Fatalf("Unable to get project %v", err)
   429  	}
   430  	assert.Equal(t, projectName, proj.Name)
   431  	assert.Equal(t, 0, len(proj.Spec.OrphanedResources.Ignore))
   432  	assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
   433  }
   434  
   435  func createAndConfigGlobalProject() error {
   436  	//Create global project
   437  	projectGlobalName := "proj-g-" + fixture.Name()
   438  	_, err := fixture.RunCli("proj", "create", projectGlobalName,
   439  		"--description", "Test description",
   440  		"-d", "https://192.168.99.100:8443,default",
   441  		"-d", "https://192.168.99.100:8443,service",
   442  		"-s", "https://github.com/argoproj/argo-cd.git",
   443  		"--orphaned-resources")
   444  	if err != nil {
   445  		return err
   446  	}
   447  
   448  	projGlobal, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectGlobalName, metav1.GetOptions{})
   449  	if err != nil {
   450  		return err
   451  	}
   452  
   453  	projGlobal.Spec.NamespaceResourceBlacklist = []metav1.GroupKind{
   454  		{Group: "", Kind: "Service"},
   455  	}
   456  
   457  	projGlobal.Spec.NamespaceResourceWhitelist = []metav1.GroupKind{
   458  		{Group: "", Kind: "Deployment"},
   459  	}
   460  
   461  	projGlobal.Spec.ClusterResourceWhitelist = []metav1.GroupKind{
   462  		{Group: "", Kind: "Job"},
   463  	}
   464  
   465  	projGlobal.Spec.ClusterResourceBlacklist = []metav1.GroupKind{
   466  		{Group: "", Kind: "Pod"},
   467  	}
   468  
   469  	projGlobal.Spec.SyncWindows = v1alpha1.SyncWindows{}
   470  	win := &v1alpha1.SyncWindow{Kind: "deny", Schedule: "* * * * *", Duration: "1h", Applications: []string{"*"}}
   471  	projGlobal.Spec.SyncWindows = append(projGlobal.Spec.SyncWindows, win)
   472  
   473  	_, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Update(context.Background(), projGlobal, metav1.UpdateOptions{})
   474  	if err != nil {
   475  		return err
   476  	}
   477  
   478  	//Configure global project settings
   479  	globalProjectsSettings := `data:
   480    accounts.config-service: apiKey
   481    globalProjects: |
   482      - labelSelector:
   483          matchExpressions:
   484            - key: opt
   485              operator: In
   486              values:
   487                - me
   488                - you
   489        projectName: %s`
   490  
   491  	_, err = fixture.Run("", "kubectl", "patch", "cm", "argocd-cm",
   492  		"-n", fixture.ArgoCDNamespace,
   493  		"-p", fmt.Sprintf(globalProjectsSettings, projGlobal.Name))
   494  	if err != nil {
   495  		return err
   496  	}
   497  
   498  	return nil
   499  }
   500  
   501  func TestGetVirtualProjectNoMatch(t *testing.T) {
   502  	fixture.EnsureCleanState(t)
   503  	err := createAndConfigGlobalProject()
   504  	assert.NoError(t, err)
   505  
   506  	//Create project which does not match global project settings
   507  	projectName := "proj-" + fixture.Name()
   508  	_, err = fixture.RunCli("proj", "create", projectName,
   509  		"--description", "Test description",
   510  		"-d", fmt.Sprintf("%s,*", common.KubernetesInternalAPIServerAddr),
   511  		"-s", "*",
   512  		"--orphaned-resources")
   513  	assert.NoError(t, err)
   514  
   515  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   516  	assert.NoError(t, err)
   517  
   518  	//Create an app belongs to proj project
   519  	_, err = fixture.RunCli("app", "create", fixture.Name(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
   520  		"--path", guestbookPath, "--project", proj.Name, "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
   521  	assert.NoError(t, err)
   522  
   523  	//App trying to sync a resource which is not blacked listed anywhere
   524  	_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10))
   525  	assert.NoError(t, err)
   526  
   527  	//app trying to sync a resource which is black listed by global project
   528  	_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10))
   529  	assert.NoError(t, err)
   530  
   531  }
   532  
   533  func TestGetVirtualProjectMatch(t *testing.T) {
   534  	fixture.EnsureCleanState(t)
   535  	err := createAndConfigGlobalProject()
   536  	assert.NoError(t, err)
   537  
   538  	//Create project which matches global project settings
   539  	projectName := "proj-" + fixture.Name()
   540  	_, err = fixture.RunCli("proj", "create", projectName,
   541  		"--description", "Test description",
   542  		"-d", fmt.Sprintf("%s,*", common.KubernetesInternalAPIServerAddr),
   543  		"-s", "*",
   544  		"--orphaned-resources")
   545  	assert.NoError(t, err)
   546  
   547  	proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Get(context.Background(), projectName, metav1.GetOptions{})
   548  	assert.NoError(t, err)
   549  
   550  	//Add a label to this project so that this project match global project selector
   551  	proj.Labels = map[string]string{"opt": "me"}
   552  	_, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.ArgoCDNamespace).Update(context.Background(), proj, metav1.UpdateOptions{})
   553  	assert.NoError(t, err)
   554  
   555  	//Create an app belongs to proj project
   556  	_, err = fixture.RunCli("app", "create", fixture.Name(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
   557  		"--path", guestbookPath, "--project", proj.Name, "--dest-server", common.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
   558  	assert.NoError(t, err)
   559  
   560  	//App trying to sync a resource which is not blacked listed anywhere
   561  	_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10))
   562  	assert.Error(t, err)
   563  	assert.Contains(t, err.Error(), "Blocked by sync window")
   564  
   565  	//app trying to sync a resource which is black listed by global project
   566  	_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10))
   567  	assert.Contains(t, err.Error(), "Blocked by sync window")
   568  
   569  }