diff --git a/pkg/vendir/config/config.go b/pkg/vendir/config/config.go index 479e88ec..0ec3aef1 100644 --- a/pkg/vendir/config/config.go +++ b/pkg/vendir/config/config.go @@ -6,6 +6,7 @@ package config import ( "fmt" "path/filepath" + "reflect" "strings" semver "github.com/hashicorp/go-version" @@ -31,7 +32,7 @@ func NewConfigFromFiles(paths []string) (Config, []Secret, []ConfigMap, error) { var configs []Config var secrets []Secret var configMaps []ConfigMap - + secretsNames := map[string]Secret{} err := parseResources(paths, func(docBytes []byte) error { var res resource @@ -48,7 +49,14 @@ func NewConfigFromFiles(paths []string) (Config, []Secret, []ConfigMap, error) { if err != nil { return fmt.Errorf("Unmarshaling secret: %s", err) } - secrets = append(secrets, secret) + + if s, ok := secretsNames[secret.Metadata.Name]; ok { + if !reflect.DeepEqual(s.Data, secret.Data) { + return fmt.Errorf( + "Expected to find one secret '%s', but found multiple", s.Metadata.Name) + } + } + secretsNames[secret.Metadata.Name] = secret case res.APIVersion == "v1" && res.Kind == "ConfigMap": var cm ConfigMap @@ -72,6 +80,11 @@ func NewConfigFromFiles(paths []string) (Config, []Secret, []ConfigMap, error) { } return nil }) + + for _, v := range secretsNames { + secrets = append(secrets, v) + } + if err != nil { return Config{}, nil, nil, err } diff --git a/pkg/vendir/config/config_test.go b/pkg/vendir/config/config_test.go index eef12112..aa975f9c 100644 --- a/pkg/vendir/config/config_test.go +++ b/pkg/vendir/config/config_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vmware-tanzu/carvel-vendir/pkg/vendir/config" ) @@ -27,3 +28,234 @@ kind: Config`) require.NoError(t, err) }) } + +func TestSecretsForNewConfigFromFiles(t *testing.T) { + t.Run("Config with single secret", func(t *testing.T) { + tempConfigPath := filepath.Join(t.TempDir(), "config.yml") + configWithWhitespace := []byte(` +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: "repo" + contents: + - path: "folder-1" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-1/**/* + - path: "folder-2" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-2/**/* +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +`) + + require.NoError(t, os.WriteFile(tempConfigPath, configWithWhitespace, 0666)) + + _, _, _, err := config.NewConfigFromFiles([]string{tempConfigPath}) + require.NoError(t, err) + }) + + t.Run("Config with same secret", func(t *testing.T) { + tempConfigPath := filepath.Join(t.TempDir(), "config.yml") + configWithWhitespace := []byte(` +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: "repo" + contents: + - path: "folder-1" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-1/**/* + - path: "folder-2" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-2/**/* +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +`) + + require.NoError(t, os.WriteFile(tempConfigPath, configWithWhitespace, 0666)) + + _, _, _, err := config.NewConfigFromFiles([]string{tempConfigPath}) + require.NoError(t, err) + }) + + t.Run("Config with multiple secret", func(t *testing.T) { + tempConfigPath := filepath.Join(t.TempDir(), "config.yml") + configWithWhitespace := []byte(` +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: "repo" + contents: + - path: "folder-1" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-1/**/* + - path: "folder-2" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-2/**/* +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +--- +apiVersion: v1 +data: + ssh-privatekey: BAR= +kind: Secret +metadata: + name: another-secret +--- +apiVersion: v1 +data: + ssh-privatekey: BAR= +kind: Secret +metadata: + name: another-secret +`) + + require.NoError(t, os.WriteFile(tempConfigPath, configWithWhitespace, 0666)) + + _, s, _, err := config.NewConfigFromFiles([]string{tempConfigPath}) + assert.Equal(t, len(s), 2) + require.NoError(t, err) + }) + + t.Run("Config with same secrets name but different data", func(t *testing.T) { + tempConfigPath := filepath.Join(t.TempDir(), "config.yml") + configWithWhitespace := []byte(` +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: "repo" + contents: + - path: "folder-1" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-1/**/* + - path: "folder-2" + git: + url: git@my-git-server.com:my-user/my-repo.git + secretRef: + name: ssh-key-secret + ref: origin/main + includePaths: + - folder-2/**/* +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: FOO= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: BAR= +kind: Secret +metadata: + name: ssh-key-secret +--- +apiVersion: v1 +data: + ssh-privatekey: BAR= +kind: Secret +metadata: + name: another-secret +--- +apiVersion: v1 +data: + ssh-privatekey: BAZ= +kind: Secret +metadata: + name: another-secret +`) + + require.NoError(t, os.WriteFile(tempConfigPath, configWithWhitespace, 0666)) + + _, _, _, err := config.NewConfigFromFiles([]string{tempConfigPath}) + require.Error(t, err) + assert.Contains(t, err.Error(), "Expected to find one secret 'ssh-key-secret', but found multiple") + }) +}