diff --git a/secret/selector.go b/secret/selector.go index f868835a..970e867c 100644 --- a/secret/selector.go +++ b/secret/selector.go @@ -48,6 +48,10 @@ type SelectSecretOption struct { // ExcludedSecretTypes exclude some secret types when do selecting ExcludedSecretTypes SecretTypeList + // SecretTypes means only secret which type exist in this list will be selected + // if it is empty means there is no limit for secret type when selecting + SecretTypes SecretTypeList + // Namespace indicates current namespace that current resource belongs. // the secret will be searched in this namespace // as a default action, secret in the same namespace could be used by other resources in same namespace @@ -191,9 +195,13 @@ func selectToolSecretFrom(logger *zap.SugaredLogger, secretList []corev1.Secret, for _, _secret := range sortedSecrets { var sec = _secret + if len(option.SecretTypes) != 0 && !option.SecretTypes.Contains(sec.Type) { + continue + } if len(option.ExcludedSecretTypes) != 0 && option.ExcludedSecretTypes.Contains(sec.Type) { continue } + address := sec.Annotations[metav1alpha1.IntegrationAddressAnnotation] if address == "" { continue diff --git a/secret/selector_test.go b/secret/selector_test.go index 42cf2654..2fdb28e7 100644 --- a/secret/selector_test.go +++ b/secret/selector_test.go @@ -34,10 +34,12 @@ func TestSelect(t *testing.T) { zaplog, _ := zap.NewDevelopment() log := zaplog.Sugar() - var buildSecret = func(name, namespace, address string, scopes []string, applyNamespaces []string, isGlobal bool) corev1.Secret { + var buildSecret = func(name, namespace, address string, secretType corev1.SecretType, scopes []string, applyNamespaces []string, isGlobal bool) corev1.Secret { return corev1.Secret{ + Type: secretType, TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ + Name: name, Namespace: namespace, Annotations: map[string]string{ @@ -64,9 +66,9 @@ func TestSelect(t *testing.T) { t.Run("has namespaced credentials and correct scopes", func(t *testing.T) { secrets := []corev1.Secret{ buildSecret("secret-1", "project-1", "https://gitlab.com/", - []string{"/devops-1/"}, []string{}, false), + "", []string{"/devops-1/"}, []string{}, false), buildSecret("secret-2", "project-2", "https://gitlab.com/", - []string{"/devops-2/"}, []string{}, false), + "", []string{"/devops-2/"}, []string{}, false), } actual, err := selectToolSecret(log, secrets, []corev1.Secret{}, "https://gitlab.com/devops-2/demo", SelectSecretOption{ PerferredSecret: types.NamespacedName{}, @@ -80,13 +82,13 @@ func TestSelect(t *testing.T) { t.Run("has namespaced credentials and correct scopes and perferred secret", func(t *testing.T) { secrets := []corev1.Secret{ buildSecret("secret-1", "project-1", "https://gitlab.com/", - []string{"/devops-1/"}, []string{}, false), + "", []string{"/devops-1/"}, []string{}, false), buildSecret("secret-2", "project-2", "https://gitlab.com/", - []string{"/devops-2/"}, []string{}, false), + "", []string{"/devops-2/"}, []string{}, false), buildSecret("secret-2.1", "project-2", "https://gitlab.com/", - []string{"/devops-2/"}, []string{}, false), + "", []string{"/devops-2/"}, []string{}, false), buildSecret("secret-2.0", "project-2", "https://gitlab.com/", - []string{"/devops-2/"}, []string{}, false), + "", []string{"/devops-2/"}, []string{}, false), } actual, err := selectToolSecret(log, secrets, []corev1.Secret{}, "https://gitlab.com/devops-2/demo", SelectSecretOption{ PerferredSecret: types.NamespacedName{Namespace: "project-2", Name: "secret-2.1"}, @@ -101,11 +103,11 @@ func TestSelect(t *testing.T) { t.Run("has global credentials but with not apply namespaces", func(t *testing.T) { secrets := []corev1.Secret{ buildSecret("secret-1", "project-1", "https://gitlab.com/", - []string{"/devops-1/"}, []string{}, false), + "", []string{"/devops-1/"}, []string{}, false), } globalSecrets := []corev1.Secret{ buildSecret("secret-2", "global-credentials", "https://gitlab.com/", - []string{"/devops-2/"}, []string{}, true), + "", []string{"/devops-2/"}, []string{}, true), } actual, err := selectToolSecret(log, secrets, globalSecrets, "https://gitlab.com/devops-2/demo", SelectSecretOption{ PerferredSecret: types.NamespacedName{Namespace: "project-2", Name: "secret-2.1"}, @@ -125,11 +127,11 @@ func TestSelect(t *testing.T) { t.Run("has global credentials and with correct apply namespaces", func(t *testing.T) { secrets := []corev1.Secret{ buildSecret("secret-1", "project-1", "https://gitlab.com/", - []string{"/devops-1/"}, []string{}, false), + "", []string{"/devops-1/"}, []string{}, false), } globalSecrets := []corev1.Secret{ buildSecret("secret-2", "global-credentials", "https://gitlab.com/", - []string{"/devops-2/"}, []string{"project-1"}, true), + "", []string{"/devops-2/"}, []string{"project-1"}, true), } actual, err := selectToolSecret(log, secrets, globalSecrets, "https://gitlab.com/devops-2/demo", SelectSecretOption{ PerferredSecret: types.NamespacedName{Namespace: "project-2", Name: "secret-what-ever"}, @@ -143,11 +145,11 @@ func TestSelect(t *testing.T) { t.Run("has global credentials but with not correct apply namespaces", func(t *testing.T) { secrets := []corev1.Secret{ buildSecret("secret-1", "project-1", "https://gitlab.com/", - []string{"/devops-1/"}, []string{}, false), + "", []string{"/devops-1/"}, []string{}, false), } globalSecrets := []corev1.Secret{ buildSecret("secret-2", "global-credentials", "https://gitlab.com/", - []string{"/devops-2/"}, []string{"project-2"}, true), + "", []string{"/devops-2/"}, []string{"project-2"}, true), } actual, err := selectToolSecret(log, secrets, globalSecrets, "https://gitlab.com/devops-2/demo", SelectSecretOption{ PerferredSecret: types.NamespacedName{Namespace: "project-2", Name: "secret-what-ever"}, @@ -181,6 +183,115 @@ func TestSelect(t *testing.T) { t.Errorf("should contain") } }) + + t.Run("only basicAuth type secret can be selected", func(t *testing.T) { + sList := []corev1.Secret{ + buildSecret("secret-basic", "default", "https://1.2.3.4/", + corev1.SecretTypeBasicAuth, []string{"/devops/"}, []string{""}, false), + buildSecret("secret-basic1", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops/"}, []string{""}, false), + buildSecret("secret-basic2", "default", "https://1.2.3.4/", + corev1.SecretTypeBootstrapToken, []string{"/devops/"}, []string{""}, false), + } + + option := SelectSecretOption{SecretTypes: []corev1.SecretType{corev1.SecretTypeBasicAuth}} + secret, err := selectToolSecret(log, sList, []corev1.Secret{}, "https://1.2.3.4/devops/test.git", option) + if err != nil { + t.Errorf("should be nil") + } + + if !option.SecretTypes.Contains(sList[0].Type) { + t.Errorf("should contain") + } + + if secret == nil { + t.Errorf("should not be nil") + } + + if secret.Name != "secret-basic" { + t.Errorf("find wrong secret") + } + }) + + t.Run("only the correct basicAuth secret will be return", func(t *testing.T) { + sList := []corev1.Secret{ + buildSecret("secret-basic", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops/"}, []string{""}, false), + buildSecret("secret-basic1", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops1/"}, []string{""}, false), + buildSecret("secret-basic2", "default", "https://1.2.3.4/", + corev1.SecretTypeBasicAuth, []string{"/devops/"}, []string{""}, false), + } + + option := SelectSecretOption{SecretTypes: []corev1.SecretType{corev1.SecretTypeSSHAuth, corev1.SecretTypeBasicAuth}} + secret, err := selectToolSecret(log, sList, []corev1.Secret{}, "https://1.2.3.4/devops/test.git", option) + if err != nil { + t.Errorf("should be nil") + } + + if !option.SecretTypes.Contains(sList[0].Type) { + t.Errorf("should contain") + } + + if secret == nil { + t.Errorf("should not be nil") + } + + if secret.Name != "secret-basic" { + t.Errorf("find wrong secret") + } + }) + + t.Run("no secret will be return", func(t *testing.T) { + sList := []corev1.Secret{ + buildSecret("secret-basic", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops0/"}, []string{""}, false), + buildSecret("secret-basic1", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops1/"}, []string{""}, false), + buildSecret("secret-basic2", "default", "https://1.2.3.4/", + corev1.SecretTypeBasicAuth, []string{"/devops/"}, []string{""}, false), + } + + option := SelectSecretOption{SecretTypes: []corev1.SecretType{corev1.SecretTypeSSHAuth}} + secret, err := selectToolSecret(log, sList, []corev1.Secret{}, "https://1.2.3.4/devops/test.git", option) + if err != nil { + t.Errorf("should be nil") + } + + if !option.SecretTypes.Contains(sList[0].Type) { + t.Errorf("should contain") + } + + if secret != nil { + t.Errorf("should not return secret because no sutiable secret proviede") + } + }) + + t.Run("secretType is not provided so secret secret-basic2 will be return", func(t *testing.T) { + sList := []corev1.Secret{ + buildSecret("secret-basic", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops0/"}, []string{""}, false), + buildSecret("secret-basic1", "default", "https://1.2.3.4/", + corev1.SecretTypeSSHAuth, []string{"/devops1/"}, []string{""}, false), + buildSecret("secret-basic2", "default", "https://1.2.3.4/", + corev1.SecretTypeBasicAuth, []string{"/devops/"}, []string{""}, false), + } + + option := SelectSecretOption{SecretTypes: []corev1.SecretType{}} + secret, err := selectToolSecret(log, sList, []corev1.Secret{}, "https://1.2.3.4/devops/test.git", option) + if err != nil { + t.Errorf("should be nil") + } + + if secret == nil { + t.Errorf("should return secret") + } + + if secret.Name != "secret-basic2" { + t.Errorf("should return secret secret-basic2") + } + }) + } func TestSortSecretList(t *testing.T) {