github.com/argoproj/argo-cd/v2@v2.10.5/util/db/repository_test.go (about)

     1  package db
     2  
     3  import (
     4  	"testing"
     5  
     6  	"context"
     7  	"github.com/stretchr/testify/assert"
     8  	corev1 "k8s.io/api/core/v1"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  
    11  	"github.com/argoproj/argo-cd/v2/common"
    12  	appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
    13  	"github.com/argoproj/argo-cd/v2/util/settings"
    14  )
    15  
    16  const (
    17  	repoArgoProj = `
    18  - name: OtherRepo
    19    url: git@github.com:argoproj/argoproj.git
    20    usernameSecret:
    21      name: managed-secret
    22      key: username
    23    passwordSecret:
    24      name: managed-secret
    25      key: password
    26    type: git`
    27  )
    28  
    29  var (
    30  	repoArgoCD = &corev1.Secret{
    31  		ObjectMeta: metav1.ObjectMeta{
    32  			Namespace: testNamespace,
    33  			Name:      "some-repo-secret",
    34  			Annotations: map[string]string{
    35  				common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
    36  			},
    37  			Labels: map[string]string{
    38  				common.LabelKeySecretType: common.LabelValueSecretTypeRepository,
    39  			},
    40  		},
    41  		Data: map[string][]byte{
    42  			"name":     []byte("SomeRepo"),
    43  			"url":      []byte("git@github.com:argoproj/argo-cd.git"),
    44  			"username": []byte("someUsername"),
    45  			"password": []byte("somePassword"),
    46  			"type":     []byte("git"),
    47  		},
    48  	}
    49  )
    50  
    51  func TestDb_CreateRepository(t *testing.T) {
    52  	clientset := getClientset(map[string]string{})
    53  	settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace)
    54  	testee := &db{
    55  		ns:            testNamespace,
    56  		kubeclientset: clientset,
    57  		settingsMgr:   settingsManager,
    58  	}
    59  
    60  	input := &appsv1.Repository{
    61  		Name:     "TestRepo",
    62  		Repo:     "git@github.com:argoproj/argo-cd.git",
    63  		Username: "someUsername",
    64  		Password: "somePassword",
    65  	}
    66  
    67  	// The repository was indeed created successfully
    68  	output, err := testee.CreateRepository(context.TODO(), input)
    69  	assert.NoError(t, err)
    70  	assert.Same(t, input, output)
    71  
    72  	// New repositories should not be stored in the settings anymore
    73  	settingRepositories, err := settingsManager.GetRepositories()
    74  	assert.NoError(t, err)
    75  	assert.Empty(t, settingRepositories)
    76  
    77  	// New repositories should be now stored as secrets
    78  	secret, err := clientset.CoreV1().Secrets(testNamespace).Get(
    79  		context.TODO(),
    80  		RepoURLToSecretName(repoSecretPrefix, input.Repo),
    81  		metav1.GetOptions{},
    82  	)
    83  	assert.NotNil(t, secret)
    84  	assert.NoError(t, err)
    85  }
    86  
    87  func TestDb_GetRepository(t *testing.T) {
    88  	clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD)
    89  	settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace)
    90  	testee := &db{
    91  		ns:            testNamespace,
    92  		kubeclientset: clientset,
    93  		settingsMgr:   settingsManager,
    94  	}
    95  
    96  	repository, err := testee.GetRepository(context.TODO(), "git@github.com:argoproj/argoproj.git")
    97  	assert.NoError(t, err)
    98  	assert.NotNil(t, repository)
    99  	assert.Equal(t, "OtherRepo", repository.Name)
   100  
   101  	repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git")
   102  	assert.NoError(t, err)
   103  	assert.NotNil(t, repository)
   104  	assert.Equal(t, "SomeRepo", repository.Name)
   105  
   106  	repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/not-existing.git")
   107  	assert.NoError(t, err)
   108  	assert.NotNil(t, repository)
   109  	assert.Equal(t, "git@github.com:argoproj/not-existing.git", repository.Repo)
   110  }
   111  
   112  func TestDb_ListRepositories(t *testing.T) {
   113  	clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD)
   114  	settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace)
   115  	testee := &db{
   116  		ns:            testNamespace,
   117  		kubeclientset: clientset,
   118  		settingsMgr:   settingsManager,
   119  	}
   120  
   121  	repositories, err := testee.ListRepositories(context.TODO())
   122  	assert.NoError(t, err)
   123  	assert.Len(t, repositories, 2)
   124  }
   125  
   126  func TestDb_UpdateRepository(t *testing.T) {
   127  	secretRepository := &appsv1.Repository{
   128  		Name:     "SomeRepo",
   129  		Repo:     "git@github.com:argoproj/argo-cd.git",
   130  		Username: "someUsername",
   131  		Password: "somePassword",
   132  		Type:     "git",
   133  	}
   134  	settingRepository := &appsv1.Repository{
   135  		Name:     "OtherRepo",
   136  		Repo:     "git@github.com:argoproj/argoproj.git",
   137  		Username: "otherUsername",
   138  		Password: "otherPassword",
   139  		Type:     "git",
   140  	}
   141  
   142  	clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD)
   143  	settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace)
   144  	testee := &db{
   145  		ns:            testNamespace,
   146  		kubeclientset: clientset,
   147  		settingsMgr:   settingsManager,
   148  	}
   149  
   150  	// Verify that legacy repository can still be updated
   151  	settingRepository.Username = "OtherUpdatedUsername"
   152  	repository, err := testee.UpdateRepository(context.TODO(), settingRepository)
   153  	assert.NoError(t, err)
   154  	assert.NotNil(t, repository)
   155  	assert.Same(t, settingRepository, repository)
   156  
   157  	secret, err := clientset.CoreV1().Secrets(testNamespace).Get(
   158  		context.TODO(),
   159  		"managed-secret",
   160  		metav1.GetOptions{},
   161  	)
   162  	assert.NoError(t, err)
   163  	assert.NotNil(t, secret)
   164  	assert.Equal(t, "OtherUpdatedUsername", string(secret.Data["username"]))
   165  
   166  	// Verify that secret-based repository can be updated
   167  	secretRepository.Username = "UpdatedUsername"
   168  	repository, err = testee.UpdateRepository(context.TODO(), secretRepository)
   169  	assert.NoError(t, err)
   170  	assert.NotNil(t, repository)
   171  	assert.Same(t, secretRepository, repository)
   172  
   173  	secret, err = clientset.CoreV1().Secrets(testNamespace).Get(
   174  		context.TODO(),
   175  		"some-repo-secret",
   176  		metav1.GetOptions{},
   177  	)
   178  	assert.NoError(t, err)
   179  	assert.NotNil(t, secret)
   180  	assert.Equal(t, "UpdatedUsername", string(secret.Data["username"]))
   181  }
   182  
   183  func TestDb_DeleteRepository(t *testing.T) {
   184  	clientset := getClientset(map[string]string{"repositories": repoArgoProj}, newManagedSecret(), repoArgoCD)
   185  	settingsManager := settings.NewSettingsManager(context.TODO(), clientset, testNamespace)
   186  	testee := &db{
   187  		ns:            testNamespace,
   188  		kubeclientset: clientset,
   189  		settingsMgr:   settingsManager,
   190  	}
   191  
   192  	err := testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argoproj.git")
   193  	assert.NoError(t, err)
   194  
   195  	repositories, err := settingsManager.GetRepositories()
   196  	assert.NoError(t, err)
   197  	assert.Empty(t, repositories)
   198  
   199  	err = testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git")
   200  	assert.NoError(t, err)
   201  
   202  	_, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "some-repo-secret", metav1.GetOptions{})
   203  	assert.Error(t, err)
   204  }
   205  
   206  func TestDb_GetRepositoryCredentials(t *testing.T) {
   207  	repositoryCredentialsSettings := `
   208  - type: git
   209    url: git@github.com:argoproj
   210    usernameSecret:
   211      name: managed-secret
   212      key: username
   213    passwordSecret:
   214      name: managed-secret
   215      key: password
   216  `
   217  	repoCredsSecret := &corev1.Secret{
   218  		ObjectMeta: metav1.ObjectMeta{
   219  			Namespace: testNamespace,
   220  			Name:      "some-repocreds-secret",
   221  			Labels: map[string]string{
   222  				common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds,
   223  			},
   224  		},
   225  		Data: map[string][]byte{
   226  			"type":     []byte("git"),
   227  			"url":      []byte("git@gitlab.com"),
   228  			"username": []byte("someUsername"),
   229  			"password": []byte("somePassword"),
   230  		},
   231  	}
   232  
   233  	clientset := getClientset(map[string]string{"repository.credentials": repositoryCredentialsSettings}, newManagedSecret(), repoCredsSecret)
   234  	testee := NewDB(testNamespace, settings.NewSettingsManager(context.TODO(), clientset, testNamespace), clientset)
   235  
   236  	repoCreds, err := testee.GetRepositoryCredentials(context.TODO(), "git@github.com:argoproj/argoproj.git")
   237  	assert.NoError(t, err)
   238  	assert.NotNil(t, repoCreds)
   239  	assert.Equal(t, "git@github.com:argoproj", repoCreds.URL)
   240  
   241  	repoCreds, err = testee.GetRepositoryCredentials(context.TODO(), "git@gitlab.com:someorg/foobar.git")
   242  	assert.NoError(t, err)
   243  	assert.NotNil(t, repoCreds)
   244  	assert.Equal(t, "git@gitlab.com", repoCreds.URL)
   245  
   246  	repoCreds, err = testee.GetRepositoryCredentials(context.TODO(), "git@github.com:example/not-existing.git")
   247  	assert.NoError(t, err)
   248  	assert.Nil(t, repoCreds)
   249  }
   250  
   251  func TestRepoURLToSecretName(t *testing.T) {
   252  	tables := map[string]string{
   253  		"git://git@github.com:argoproj/ARGO-cd.git": "repo-83273445",
   254  		"https://github.com/argoproj/ARGO-cd":       "repo-1890113693",
   255  		"https://github.com/argoproj/argo-cd":       "repo-42374749",
   256  		"https://github.com/argoproj/argo-cd.git":   "repo-821842295",
   257  		"https://github.com/argoproj/argo_cd.git":   "repo-1049844989",
   258  		"ssh://git@github.com/argoproj/argo-cd.git": "repo-3569564120",
   259  	}
   260  
   261  	for k, v := range tables {
   262  		if sn := RepoURLToSecretName(repoSecretPrefix, k); sn != v {
   263  			t.Errorf("Expected secret name %q for repo %q; instead, got %q", v, k, sn)
   264  		}
   265  	}
   266  }
   267  
   268  func Test_CredsURLToSecretName(t *testing.T) {
   269  	tables := map[string]string{
   270  		"git://git@github.com:argoproj":  "creds-2483499391",
   271  		"git://git@github.com:argoproj/": "creds-1465032944",
   272  		"git@github.com:argoproj":        "creds-2666065091",
   273  		"git@github.com:argoproj/":       "creds-346879876",
   274  	}
   275  
   276  	for k, v := range tables {
   277  		if sn := RepoURLToSecretName(credSecretPrefix, k); sn != v {
   278  			t.Errorf("Expected secret name %q for repo %q; instead, got %q", v, k, sn)
   279  		}
   280  	}
   281  }
   282  
   283  func Test_GetProjectRepositories(t *testing.T) {
   284  	repoSecretWithProject := &corev1.Secret{
   285  		ObjectMeta: metav1.ObjectMeta{
   286  			Namespace: testNamespace,
   287  			Name:      "some-repo-secret",
   288  			Labels: map[string]string{
   289  				common.LabelKeySecretType: common.LabelValueSecretTypeRepository,
   290  			},
   291  		},
   292  		Data: map[string][]byte{
   293  			"type":    []byte("git"),
   294  			"url":     []byte("git@github.com:argoproj/argo-cd"),
   295  			"project": []byte("some-project"),
   296  		},
   297  	}
   298  
   299  	repoSecretWithoutProject := &corev1.Secret{
   300  		ObjectMeta: metav1.ObjectMeta{
   301  			Namespace: testNamespace,
   302  			Name:      "some-other-repo-secret",
   303  			Labels: map[string]string{
   304  				common.LabelKeySecretType: common.LabelValueSecretTypeRepository,
   305  			},
   306  		},
   307  		Data: map[string][]byte{
   308  			"type": []byte("git"),
   309  			"url":  []byte("git@github.com:argoproj/argo-cd"),
   310  		},
   311  	}
   312  
   313  	clientset := getClientset(map[string]string{}, repoSecretWithProject, repoSecretWithoutProject)
   314  	argoDB := NewDB(testNamespace, settings.NewSettingsManager(context.TODO(), clientset, testNamespace), clientset)
   315  
   316  	repos, err := argoDB.GetProjectRepositories(context.TODO(), "some-project")
   317  	assert.NoError(t, err)
   318  	assert.Len(t, repos, 1)
   319  	assert.Equal(t, "git@github.com:argoproj/argo-cd", repos[0].Repo)
   320  }