github.com/argoproj/argo-cd/v2@v2.10.5/util/db/repository_secrets_test.go (about) 1 package db 2 3 import ( 4 "strconv" 5 "testing" 6 7 "context" 8 9 "github.com/stretchr/testify/assert" 10 "google.golang.org/grpc/codes" 11 "google.golang.org/grpc/status" 12 corev1 "k8s.io/api/core/v1" 13 k8serrors "k8s.io/apimachinery/pkg/api/errors" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/apimachinery/pkg/runtime" 16 "k8s.io/apimachinery/pkg/runtime/schema" 17 "k8s.io/apimachinery/pkg/watch" 18 "k8s.io/client-go/kubernetes/fake" 19 k8stesting "k8s.io/client-go/testing" 20 21 "github.com/argoproj/argo-cd/v2/common" 22 appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 23 "github.com/argoproj/argo-cd/v2/util/settings" 24 ) 25 26 func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { 27 type fixture struct { 28 clientSet *fake.Clientset 29 repoBackend *secretsRepositoryBackend 30 } 31 repo := &appsv1.Repository{ 32 Name: "ArgoCD", 33 Repo: "git@github.com:argoproj/argo-cd.git", 34 Username: "someUsername", 35 Password: "somePassword", 36 InsecureIgnoreHostKey: false, 37 EnableLFS: true, 38 } 39 setupWithK8sObjects := func(objects ...runtime.Object) *fixture { 40 41 clientset := getClientset(map[string]string{}, objects...) 42 settingsMgr := settings.NewSettingsManager(context.Background(), clientset, testNamespace) 43 repoBackend := &secretsRepositoryBackend{db: &db{ 44 ns: testNamespace, 45 kubeclientset: clientset, 46 settingsMgr: settingsMgr, 47 }} 48 return &fixture{ 49 clientSet: clientset, 50 repoBackend: repoBackend, 51 } 52 } 53 t.Run("will create repository successfully", func(t *testing.T) { 54 // given 55 t.Parallel() 56 f := setupWithK8sObjects() 57 58 // when 59 output, err := f.repoBackend.CreateRepository(context.Background(), repo) 60 61 // then 62 assert.NoError(t, err) 63 assert.Same(t, repo, output) 64 65 secret, err := f.clientSet.CoreV1().Secrets(testNamespace).Get( 66 context.TODO(), 67 RepoURLToSecretName(repoSecretPrefix, repo.Repo), 68 metav1.GetOptions{}, 69 ) 70 assert.NotNil(t, secret) 71 assert.NoError(t, err) 72 73 assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy]) 74 assert.Equal(t, common.LabelValueSecretTypeRepository, secret.Labels[common.LabelKeySecretType]) 75 76 assert.Equal(t, repo.Name, string(secret.Data["name"])) 77 assert.Equal(t, repo.Repo, string(secret.Data["url"])) 78 assert.Equal(t, repo.Username, string(secret.Data["username"])) 79 assert.Equal(t, repo.Password, string(secret.Data["password"])) 80 assert.Equal(t, "", string(secret.Data["insecureIgnoreHostKey"])) 81 assert.Equal(t, strconv.FormatBool(repo.EnableLFS), string(secret.Data["enableLfs"])) 82 }) 83 t.Run("will return proper error if secret does not have expected label", func(t *testing.T) { 84 // given 85 t.Parallel() 86 secret := &corev1.Secret{} 87 repositoryToSecret(repo, secret) 88 delete(secret.Labels, common.LabelKeySecretType) 89 f := setupWithK8sObjects(secret) 90 f.clientSet.ReactionChain = nil 91 f.clientSet.AddReactor("create", "secrets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { 92 gr := schema.GroupResource{ 93 Group: "v1", 94 Resource: "secrets", 95 } 96 return true, nil, k8serrors.NewAlreadyExists(gr, "already exists") 97 }) 98 99 // when 100 output, err := f.repoBackend.CreateRepository(context.Background(), repo) 101 102 // then 103 assert.Error(t, err) 104 assert.Nil(t, output) 105 status, ok := status.FromError(err) 106 assert.True(t, ok) 107 assert.Equal(t, codes.InvalidArgument, status.Code()) 108 }) 109 t.Run("will return proper error if secret already exists", func(t *testing.T) { 110 // given 111 t.Parallel() 112 secName := RepoURLToSecretName(repoSecretPrefix, repo.Repo) 113 secret := &corev1.Secret{ 114 TypeMeta: metav1.TypeMeta{ 115 Kind: "Secret", 116 APIVersion: "v1", 117 }, 118 ObjectMeta: metav1.ObjectMeta{ 119 Name: secName, 120 Namespace: "default", 121 }, 122 } 123 repositoryToSecret(repo, secret) 124 f := setupWithK8sObjects(secret) 125 f.clientSet.ReactionChain = nil 126 f.clientSet.WatchReactionChain = nil 127 f.clientSet.AddReactor("create", "secrets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { 128 gr := schema.GroupResource{ 129 Group: "v1", 130 Resource: "secrets", 131 } 132 return true, nil, k8serrors.NewAlreadyExists(gr, "already exists") 133 }) 134 watcher := watch.NewFakeWithChanSize(1, true) 135 watcher.Add(secret) 136 f.clientSet.AddWatchReactor("secrets", func(action k8stesting.Action) (handled bool, ret watch.Interface, err error) { 137 return true, watcher, nil 138 }) 139 140 // when 141 output, err := f.repoBackend.CreateRepository(context.Background(), repo) 142 143 // then 144 assert.Error(t, err) 145 assert.Nil(t, output) 146 status, ok := status.FromError(err) 147 assert.True(t, ok) 148 assert.Equal(t, codes.AlreadyExists, status.Code()) 149 }) 150 } 151 152 func TestSecretsRepositoryBackend_GetRepository(t *testing.T) { 153 repoSecrets := []runtime.Object{ 154 &corev1.Secret{ 155 ObjectMeta: metav1.ObjectMeta{ 156 Namespace: testNamespace, 157 Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj/argo-cd.git"), 158 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 159 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 160 }, 161 Data: map[string][]byte{ 162 "name": []byte("ArgoCD"), 163 "url": []byte("git@github.com:argoproj/argo-cd.git"), 164 "username": []byte("someUsername"), 165 "password": []byte("somePassword"), 166 }, 167 }, 168 &corev1.Secret{ 169 ObjectMeta: metav1.ObjectMeta{ 170 Namespace: testNamespace, 171 Name: "user-managed", 172 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 173 }, 174 Data: map[string][]byte{ 175 "name": []byte("UserManagedRepo"), 176 "url": []byte("git@github.com:argoproj/argoproj.git"), 177 "username": []byte("someOtherUsername"), 178 "password": []byte("someOtherPassword"), 179 }, 180 }, 181 } 182 183 clientset := getClientset(map[string]string{}, repoSecrets...) 184 testee := &secretsRepositoryBackend{db: &db{ 185 ns: testNamespace, 186 kubeclientset: clientset, 187 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 188 }} 189 190 repository, err := testee.GetRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git") 191 assert.NoError(t, err) 192 assert.NotNil(t, repository) 193 assert.Equal(t, "ArgoCD", repository.Name) 194 assert.Equal(t, "git@github.com:argoproj/argo-cd.git", repository.Repo) 195 assert.Equal(t, "someUsername", repository.Username) 196 assert.Equal(t, "somePassword", repository.Password) 197 198 repository, err = testee.GetRepository(context.TODO(), "git@github.com:argoproj/argoproj.git") 199 assert.NoError(t, err) 200 assert.NotNil(t, repository) 201 assert.Equal(t, "UserManagedRepo", repository.Name) 202 assert.Equal(t, "git@github.com:argoproj/argoproj.git", repository.Repo) 203 assert.Equal(t, "someOtherUsername", repository.Username) 204 assert.Equal(t, "someOtherPassword", repository.Password) 205 } 206 207 func TestSecretsRepositoryBackend_ListRepositories(t *testing.T) { 208 repoSecrets := []runtime.Object{ 209 &corev1.Secret{ 210 ObjectMeta: metav1.ObjectMeta{ 211 Namespace: testNamespace, 212 Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj/argo-cd.git"), 213 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 214 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 215 }, 216 Data: map[string][]byte{ 217 "name": []byte("ArgoCD"), 218 "url": []byte("git@github.com:argoproj/argo-cd.git"), 219 "username": []byte("someUsername"), 220 "password": []byte("somePassword"), 221 }, 222 }, 223 &corev1.Secret{ 224 ObjectMeta: metav1.ObjectMeta{ 225 Namespace: testNamespace, 226 Name: "user-managed", 227 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 228 }, 229 Data: map[string][]byte{ 230 "name": []byte("UserManagedRepo"), 231 "url": []byte("git@github.com:argoproj/argoproj.git"), 232 "username": []byte("someOtherUsername"), 233 "password": []byte("someOtherPassword"), 234 }, 235 }, 236 } 237 238 clientset := getClientset(map[string]string{}, repoSecrets...) 239 testee := &secretsRepositoryBackend{db: &db{ 240 ns: testNamespace, 241 kubeclientset: clientset, 242 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 243 }} 244 245 repositories, err := testee.ListRepositories(context.TODO(), nil) 246 assert.NoError(t, err) 247 assert.Len(t, repositories, 2) 248 249 for _, repository := range repositories { 250 if repository.Name == "ArgoCD" { 251 assert.Equal(t, "git@github.com:argoproj/argo-cd.git", repository.Repo) 252 assert.Equal(t, "someUsername", repository.Username) 253 assert.Equal(t, "somePassword", repository.Password) 254 } else if repository.Name == "UserManagedRepo" { 255 assert.Equal(t, "git@github.com:argoproj/argoproj.git", repository.Repo) 256 assert.Equal(t, "someOtherUsername", repository.Username) 257 assert.Equal(t, "someOtherPassword", repository.Password) 258 } else { 259 assert.Fail(t, "unexpected repository found in list") 260 } 261 } 262 } 263 264 func TestSecretsRepositoryBackend_UpdateRepository(t *testing.T) { 265 managedRepository := &appsv1.Repository{ 266 Name: "Managed", 267 Repo: "git@github.com:argoproj/argo-cd.git", 268 Username: "someUsername", 269 Password: "somePassword", 270 } 271 userProvidedRepository := &appsv1.Repository{ 272 Name: "User Provided", 273 Repo: "git@github.com:argoproj/argoproj.git", 274 Username: "someOtherUsername", 275 Password: "someOtherPassword", 276 } 277 newRepository := &appsv1.Repository{ 278 Name: "New", 279 Repo: "git@github.com:argoproj/argo-events.git", 280 Username: "foo", 281 Password: "bar", 282 } 283 284 managedSecretName := RepoURLToSecretName(repoSecretPrefix, managedRepository.Repo) 285 newSecretName := RepoURLToSecretName(repoSecretPrefix, newRepository.Repo) 286 repoSecrets := []runtime.Object{ 287 &corev1.Secret{ 288 ObjectMeta: metav1.ObjectMeta{ 289 Namespace: testNamespace, 290 Name: managedSecretName, 291 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 292 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 293 }, 294 Data: map[string][]byte{ 295 "name": []byte(managedRepository.Name), 296 "url": []byte(managedRepository.Repo), 297 "username": []byte(managedRepository.Username), 298 "password": []byte(managedRepository.Password), 299 }, 300 }, 301 &corev1.Secret{ 302 ObjectMeta: metav1.ObjectMeta{ 303 Namespace: testNamespace, 304 Name: "user-managed", 305 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 306 }, 307 Data: map[string][]byte{ 308 "name": []byte(userProvidedRepository.Name), 309 "url": []byte(userProvidedRepository.Repo), 310 "username": []byte(userProvidedRepository.Username), 311 "password": []byte(userProvidedRepository.Password), 312 }, 313 }, 314 } 315 316 clientset := getClientset(map[string]string{}, repoSecrets...) 317 testee := &secretsRepositoryBackend{db: &db{ 318 ns: testNamespace, 319 kubeclientset: clientset, 320 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 321 }} 322 323 managedRepository.Username = "newUsername" 324 updateRepository, err := testee.UpdateRepository(context.TODO(), managedRepository) 325 assert.NoError(t, err) 326 assert.Same(t, managedRepository, updateRepository) 327 assert.Equal(t, managedRepository.Username, updateRepository.Username) 328 329 secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedSecretName, metav1.GetOptions{}) 330 assert.NoError(t, err) 331 assert.NotNil(t, secret) 332 assert.Equal(t, "newUsername", string(secret.Data["username"])) 333 334 userProvidedRepository.Username = "newOtherUsername" 335 updateRepository, err = testee.UpdateRepository(context.TODO(), userProvidedRepository) 336 assert.NoError(t, err) 337 assert.Same(t, userProvidedRepository, updateRepository) 338 assert.Equal(t, userProvidedRepository.Username, updateRepository.Username) 339 340 secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) 341 assert.NoError(t, err) 342 assert.NotNil(t, secret) 343 assert.Equal(t, "newOtherUsername", string(secret.Data["username"])) 344 345 updateRepository, err = testee.UpdateRepository(context.TODO(), newRepository) 346 assert.NoError(t, err) 347 assert.Same(t, newRepository, updateRepository) 348 349 secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), newSecretName, metav1.GetOptions{}) 350 assert.NoError(t, err) 351 assert.NotNil(t, secret) 352 assert.Equal(t, "foo", string(secret.Data["username"])) 353 } 354 355 func TestSecretsRepositoryBackend_DeleteRepository(t *testing.T) { 356 managedSecretName := RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj/argo-cd.git") 357 repoSecrets := []runtime.Object{ 358 &corev1.Secret{ 359 ObjectMeta: metav1.ObjectMeta{ 360 Namespace: testNamespace, 361 Name: managedSecretName, 362 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 363 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 364 }, 365 Data: map[string][]byte{ 366 "name": []byte("ArgoCD"), 367 "url": []byte("git@github.com:argoproj/argo-cd.git"), 368 "username": []byte("someUsername"), 369 "password": []byte("somePassword"), 370 }, 371 }, 372 &corev1.Secret{ 373 ObjectMeta: metav1.ObjectMeta{ 374 Namespace: testNamespace, 375 Name: "user-managed", 376 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepository}, 377 }, 378 Data: map[string][]byte{ 379 "name": []byte("UserManagedRepo"), 380 "url": []byte("git@github.com:argoproj/argoproj.git"), 381 "username": []byte("someOtherUsername"), 382 "password": []byte("someOtherPassword"), 383 }, 384 }, 385 } 386 387 clientset := getClientset(map[string]string{}, repoSecrets...) 388 testee := &secretsRepositoryBackend{db: &db{ 389 ns: testNamespace, 390 kubeclientset: clientset, 391 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 392 }} 393 394 err := testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argo-cd.git") 395 assert.NoError(t, err) 396 397 _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedSecretName, metav1.GetOptions{}) 398 assert.Error(t, err) 399 400 err = testee.DeleteRepository(context.TODO(), "git@github.com:argoproj/argoproj.git") 401 assert.NoError(t, err) 402 403 secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) 404 assert.NoError(t, err) 405 assert.NotNil(t, secret) 406 assert.Empty(t, secret.Labels[common.LabelValueSecretTypeRepository]) 407 } 408 409 func TestSecretsRepositoryBackend_CreateRepoCreds(t *testing.T) { 410 411 clientset := getClientset(map[string]string{}) 412 testee := &secretsRepositoryBackend{db: &db{ 413 ns: testNamespace, 414 kubeclientset: clientset, 415 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 416 }} 417 418 testCases := []struct { 419 name string 420 repoCreds appsv1.RepoCreds 421 // Note: URL needs to be a different one for every testCase 422 // otherwise we would need to use the DeleteRepoCreds method to clean up the secret after each test 423 // which results in an unwanted dependency in a unit test 424 }{ 425 { 426 name: "minimal_https_fields", 427 repoCreds: appsv1.RepoCreds{ 428 URL: "git@github.com:argoproj", 429 Username: "someUsername", 430 Password: "somePassword", 431 EnableOCI: true, 432 }, 433 }, 434 { 435 name: "with_proxy", 436 repoCreds: appsv1.RepoCreds{ 437 URL: "git@github.com:kubernetes", 438 Username: "anotherUsername", 439 Password: "anotherPassword", 440 Proxy: "https://proxy.argoproj.io:3128", 441 }, 442 }, 443 } 444 445 for _, testCase := range testCases { 446 t.Run(testCase.name, func(t *testing.T) { 447 output, err := testee.CreateRepoCreds(context.TODO(), &testCase.repoCreds) 448 assert.NoError(t, err) 449 assert.Same(t, &testCase.repoCreds, output) 450 451 secret, err := clientset.CoreV1().Secrets(testNamespace).Get( 452 context.TODO(), 453 RepoURLToSecretName(credSecretPrefix, testCase.repoCreds.URL), 454 metav1.GetOptions{}, 455 ) 456 assert.NotNil(t, secret) 457 assert.NoError(t, err) 458 459 assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy]) 460 assert.Equal(t, common.LabelValueSecretTypeRepoCreds, secret.Labels[common.LabelKeySecretType]) 461 462 // check every possible field of the secret if it has the same (default) value as the repoCred struct 463 // non-string fields must be parsed so that their default value matches the one of the corresponding type 464 assert.Equal(t, testCase.repoCreds.URL, string(secret.Data["url"])) 465 assert.Equal(t, testCase.repoCreds.Username, string(secret.Data["username"])) 466 assert.Equal(t, testCase.repoCreds.Password, string(secret.Data["password"])) 467 if enableOCI, err := strconv.ParseBool(string(secret.Data["githubAppPrivateKey"])); err == nil { 468 assert.Equal(t, strconv.FormatBool(testCase.repoCreds.EnableOCI), enableOCI) 469 } 470 assert.Equal(t, testCase.repoCreds.SSHPrivateKey, string(secret.Data["sshPrivateKey"])) 471 assert.Equal(t, testCase.repoCreds.TLSClientCertData, string(secret.Data["tlsClientCertData"])) 472 assert.Equal(t, testCase.repoCreds.TLSClientCertKey, string(secret.Data["tlsClientCertKey"])) 473 assert.Equal(t, testCase.repoCreds.Type, string(secret.Data["type"])) 474 assert.Equal(t, testCase.repoCreds.GithubAppPrivateKey, string(secret.Data["githubAppPrivateKey"])) 475 if githubAppPrivateKey, err := strconv.ParseInt(string(secret.Data["githubAppPrivateKey"]), 10, 64); err == nil { 476 assert.Equal(t, testCase.repoCreds.GithubAppId, githubAppPrivateKey) 477 } 478 if githubAppID, err := strconv.ParseInt(string(secret.Data["githubAppId"]), 10, 64); err == nil { 479 assert.Equal(t, testCase.repoCreds.GithubAppInstallationId, githubAppID) 480 } 481 assert.Equal(t, testCase.repoCreds.GitHubAppEnterpriseBaseURL, string(secret.Data["githubAppEnterpriseUrl"])) 482 assert.Equal(t, testCase.repoCreds.Proxy, string(secret.Data["proxy"])) 483 484 }) 485 } 486 } 487 488 func TestSecretsRepositoryBackend_GetRepoCreds(t *testing.T) { 489 repoCredSecrets := []runtime.Object{ 490 &corev1.Secret{ 491 ObjectMeta: metav1.ObjectMeta{ 492 Namespace: testNamespace, 493 Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj"), 494 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 495 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 496 }, 497 Data: map[string][]byte{ 498 "url": []byte("git@github.com:argoproj"), 499 "username": []byte("someUsername"), 500 "password": []byte("somePassword"), 501 }, 502 }, 503 &corev1.Secret{ 504 ObjectMeta: metav1.ObjectMeta{ 505 Namespace: testNamespace, 506 Name: "user-managed", 507 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 508 }, 509 Data: map[string][]byte{ 510 "url": []byte("git@gitlab.com"), 511 "username": []byte("someOtherUsername"), 512 "password": []byte("someOtherPassword"), 513 }, 514 }, 515 } 516 517 clientset := getClientset(map[string]string{}, repoCredSecrets...) 518 testee := &secretsRepositoryBackend{db: &db{ 519 ns: testNamespace, 520 kubeclientset: clientset, 521 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 522 }} 523 524 repoCred, err := testee.GetRepoCreds(context.TODO(), "git@github.com:argoproj") 525 assert.NoError(t, err) 526 assert.NotNil(t, repoCred) 527 assert.Equal(t, "git@github.com:argoproj", repoCred.URL) 528 assert.Equal(t, "someUsername", repoCred.Username) 529 assert.Equal(t, "somePassword", repoCred.Password) 530 531 repoCred, err = testee.GetRepoCreds(context.TODO(), "git@gitlab.com") 532 assert.NoError(t, err) 533 assert.NotNil(t, repoCred) 534 assert.Equal(t, "git@gitlab.com", repoCred.URL) 535 assert.Equal(t, "someOtherUsername", repoCred.Username) 536 assert.Equal(t, "someOtherPassword", repoCred.Password) 537 } 538 539 func TestSecretsRepositoryBackend_ListRepoCreds(t *testing.T) { 540 repoCredSecrets := []runtime.Object{ 541 &corev1.Secret{ 542 ObjectMeta: metav1.ObjectMeta{ 543 Namespace: testNamespace, 544 Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj"), 545 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 546 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 547 }, 548 Data: map[string][]byte{ 549 "url": []byte("git@github.com:argoproj"), 550 "username": []byte("someUsername"), 551 "password": []byte("somePassword"), 552 }, 553 }, 554 &corev1.Secret{ 555 ObjectMeta: metav1.ObjectMeta{ 556 Namespace: testNamespace, 557 Name: "user-managed", 558 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 559 }, 560 Data: map[string][]byte{ 561 "url": []byte("git@gitlab.com"), 562 "username": []byte("someOtherUsername"), 563 "password": []byte("someOtherPassword"), 564 }, 565 }, 566 } 567 568 clientset := getClientset(map[string]string{}, repoCredSecrets...) 569 testee := &secretsRepositoryBackend{db: &db{ 570 ns: testNamespace, 571 kubeclientset: clientset, 572 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 573 }} 574 575 repoCreds, err := testee.ListRepoCreds(context.TODO()) 576 assert.NoError(t, err) 577 assert.Len(t, repoCreds, 2) 578 assert.Contains(t, repoCreds, "git@github.com:argoproj") 579 assert.Contains(t, repoCreds, "git@gitlab.com") 580 } 581 582 func TestSecretsRepositoryBackend_UpdateRepoCreds(t *testing.T) { 583 managedCreds := &appsv1.RepoCreds{ 584 URL: "git@github.com:argoproj", 585 Username: "someUsername", 586 Password: "somePassword", 587 } 588 userProvidedCreds := &appsv1.RepoCreds{ 589 URL: "git@gitlab.com", 590 Username: "someOtherUsername", 591 Password: "someOtherPassword", 592 } 593 newCreds := &appsv1.RepoCreds{ 594 URL: "git@github.com:foobar", 595 Username: "foo", 596 Password: "bar", 597 } 598 599 managedCredsName := RepoURLToSecretName(credSecretPrefix, managedCreds.URL) 600 newCredsName := RepoURLToSecretName(credSecretPrefix, newCreds.URL) 601 repoCredSecrets := []runtime.Object{ 602 &corev1.Secret{ 603 ObjectMeta: metav1.ObjectMeta{ 604 Namespace: testNamespace, 605 Name: managedCredsName, 606 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 607 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 608 }, 609 Data: map[string][]byte{ 610 "url": []byte(managedCreds.URL), 611 "username": []byte(managedCreds.Username), 612 "password": []byte(managedCreds.Password), 613 }, 614 }, 615 &corev1.Secret{ 616 ObjectMeta: metav1.ObjectMeta{ 617 Namespace: testNamespace, 618 Name: "user-managed", 619 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 620 }, 621 Data: map[string][]byte{ 622 "url": []byte(userProvidedCreds.URL), 623 "username": []byte(userProvidedCreds.Username), 624 "password": []byte(userProvidedCreds.Password), 625 }, 626 }, 627 } 628 629 clientset := getClientset(map[string]string{}, repoCredSecrets...) 630 testee := &secretsRepositoryBackend{db: &db{ 631 ns: testNamespace, 632 kubeclientset: clientset, 633 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 634 }} 635 636 managedCreds.Username = "newUsername" 637 updateRepoCreds, err := testee.UpdateRepoCreds(context.TODO(), managedCreds) 638 assert.NoError(t, err) 639 assert.NotSame(t, managedCreds, updateRepoCreds) 640 assert.Equal(t, managedCreds.Username, updateRepoCreds.Username) 641 642 secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedCredsName, metav1.GetOptions{}) 643 assert.NoError(t, err) 644 assert.NotNil(t, secret) 645 assert.Equal(t, "newUsername", string(secret.Data["username"])) 646 647 userProvidedCreds.Username = "newOtherUsername" 648 updateRepoCreds, err = testee.UpdateRepoCreds(context.TODO(), userProvidedCreds) 649 assert.NoError(t, err) 650 assert.NotSame(t, userProvidedCreds, updateRepoCreds) 651 assert.Equal(t, userProvidedCreds.Username, updateRepoCreds.Username) 652 653 secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) 654 assert.NoError(t, err) 655 assert.NotNil(t, secret) 656 assert.Equal(t, "newOtherUsername", string(secret.Data["username"])) 657 658 updateRepoCreds, err = testee.UpdateRepoCreds(context.TODO(), newCreds) 659 assert.NoError(t, err) 660 assert.Same(t, newCreds, updateRepoCreds) 661 662 secret, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), newCredsName, metav1.GetOptions{}) 663 assert.NoError(t, err) 664 assert.NotNil(t, secret) 665 assert.Equal(t, "foo", string(secret.Data["username"])) 666 } 667 668 func TestSecretsRepositoryBackend_DeleteRepoCreds(t *testing.T) { 669 managedSecretName := RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj/argo-cd.git") 670 repoSecrets := []runtime.Object{ 671 &corev1.Secret{ 672 ObjectMeta: metav1.ObjectMeta{ 673 Namespace: testNamespace, 674 Name: managedSecretName, 675 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 676 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 677 }, 678 Data: map[string][]byte{ 679 "url": []byte("git@github.com:argoproj"), 680 "username": []byte("someUsername"), 681 "password": []byte("somePassword"), 682 }, 683 }, 684 &corev1.Secret{ 685 ObjectMeta: metav1.ObjectMeta{ 686 Namespace: testNamespace, 687 Name: "user-managed", 688 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 689 }, 690 Data: map[string][]byte{ 691 "url": []byte("git@gitlab.com"), 692 "username": []byte("someOtherUsername"), 693 "password": []byte("someOtherPassword"), 694 }, 695 }, 696 } 697 698 clientset := getClientset(map[string]string{}, repoSecrets...) 699 testee := &secretsRepositoryBackend{db: &db{ 700 ns: testNamespace, 701 kubeclientset: clientset, 702 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 703 }} 704 705 err := testee.DeleteRepoCreds(context.TODO(), "git@github.com:argoproj") 706 assert.NoError(t, err) 707 708 _, err = clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), managedSecretName, metav1.GetOptions{}) 709 assert.Error(t, err) 710 711 err = testee.DeleteRepoCreds(context.TODO(), "git@gitlab.com") 712 assert.NoError(t, err) 713 714 secret, err := clientset.CoreV1().Secrets(testNamespace).Get(context.TODO(), "user-managed", metav1.GetOptions{}) 715 assert.NoError(t, err) 716 assert.NotNil(t, secret) 717 assert.Empty(t, secret.Labels[common.LabelValueSecretTypeRepoCreds]) 718 } 719 720 func TestSecretsRepositoryBackend_GetAllHelmRepoCreds(t *testing.T) { 721 repoCredSecrets := []runtime.Object{ 722 &corev1.Secret{ 723 ObjectMeta: metav1.ObjectMeta{ 724 Namespace: testNamespace, 725 Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj"), 726 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 727 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 728 }, 729 Data: map[string][]byte{ 730 "url": []byte("git@github.com:argoproj"), 731 "username": []byte("someUsername"), 732 "password": []byte("somePassword"), 733 "type": []byte("helm"), 734 }, 735 }, 736 &corev1.Secret{ 737 ObjectMeta: metav1.ObjectMeta{ 738 Namespace: testNamespace, 739 Name: RepoURLToSecretName(repoSecretPrefix, "git@gitlab.com"), 740 Annotations: map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, 741 Labels: map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, 742 }, 743 Data: map[string][]byte{ 744 "url": []byte("git@gitlab.com"), 745 "username": []byte("someOtherUsername"), 746 "password": []byte("someOtherPassword"), 747 "type": []byte("git"), 748 }, 749 }, 750 } 751 752 clientset := getClientset(map[string]string{}, repoCredSecrets...) 753 testee := &secretsRepositoryBackend{db: &db{ 754 ns: testNamespace, 755 kubeclientset: clientset, 756 settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace), 757 }} 758 759 repoCreds, err := testee.GetAllHelmRepoCreds(context.TODO()) 760 assert.NoError(t, err) 761 assert.Len(t, repoCreds, 1) 762 } 763 764 func TestRepoCredsToSecret(t *testing.T) { 765 s := &corev1.Secret{} 766 creds := &appsv1.RepoCreds{ 767 URL: "URL", 768 Username: "Username", 769 Password: "Password", 770 SSHPrivateKey: "SSHPrivateKey", 771 EnableOCI: true, 772 TLSClientCertData: "TLSClientCertData", 773 TLSClientCertKey: "TLSClientCertKey", 774 Type: "Type", 775 GithubAppPrivateKey: "GithubAppPrivateKey", 776 GithubAppId: 123, 777 GithubAppInstallationId: 456, 778 GitHubAppEnterpriseBaseURL: "GitHubAppEnterpriseBaseURL", 779 } 780 repoCredsToSecret(creds, s) 781 assert.Equal(t, []byte(creds.URL), s.Data["url"]) 782 assert.Equal(t, []byte(creds.Username), s.Data["username"]) 783 assert.Equal(t, []byte(creds.Password), s.Data["password"]) 784 assert.Equal(t, []byte(creds.SSHPrivateKey), s.Data["sshPrivateKey"]) 785 assert.Equal(t, []byte(strconv.FormatBool(creds.EnableOCI)), s.Data["enableOCI"]) 786 assert.Equal(t, []byte(creds.TLSClientCertData), s.Data["tlsClientCertData"]) 787 assert.Equal(t, []byte(creds.TLSClientCertKey), s.Data["tlsClientCertKey"]) 788 assert.Equal(t, []byte(creds.Type), s.Data["type"]) 789 assert.Equal(t, []byte(creds.GithubAppPrivateKey), s.Data["githubAppPrivateKey"]) 790 assert.Equal(t, []byte(strconv.FormatInt(creds.GithubAppId, 10)), s.Data["githubAppID"]) 791 assert.Equal(t, []byte(strconv.FormatInt(creds.GithubAppInstallationId, 10)), s.Data["githubAppInstallationID"]) 792 assert.Equal(t, []byte(creds.GitHubAppEnterpriseBaseURL), s.Data["githubAppEnterpriseBaseUrl"]) 793 assert.Equal(t, map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, s.Annotations) 794 assert.Equal(t, map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, s.Labels) 795 }