From 5a0eeb51211f87fc03f4fdb4ee1d650f0f552099 Mon Sep 17 00:00:00 2001 From: dnitsch Date: Thu, 28 Mar 2024 12:40:23 +0000 Subject: [PATCH] fix: add additional tests TODO: still uncomment some not ported negative assertions --- .github/workflows/build.yml | 6 ++ internal/config/config.go | 3 +- internal/config/config_test.go | 40 ++++++++-- internal/store/store_test.go | 24 ++++++ internal/strategy/strategy.go | 15 ++-- internal/strategy/strategy_test.go | 117 ++++++++++++++++++++++++++++- 6 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 internal/store/store_test.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4d78a4..f76a6e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,12 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + - name: install deps + run: | + apt-get update && apt-get install -y jq git + git config --global --add safe.directory "$GITHUB_WORKSPACE" + git config user.email ${{ github.actor }}-ci@gha.org + git config user.name ${{ github.actor }} - name: Install GitVersion uses: gittools/actions/gitversion/setup@v1.1.1 with: diff --git a/internal/config/config.go b/internal/config/config.go index a3f4666..ebb2f4b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -104,7 +104,8 @@ func (c *GenVarsConfig) KeySeparator() string { // Config returns the derefed value func (c *GenVarsConfig) Config() GenVarsConfig { - return *c + cc := *c + return cc } // Parsed token config section diff --git a/internal/config/config_test.go b/internal/config/config_test.go index e01b6d8..0767e62 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -110,17 +110,45 @@ func Test_MarshalMetadata_with_label_struct_succeeds(t *testing.T) { } } -func Test_StripPrefix(t *testing.T) { +func Test_TokenParser_config(t *testing.T) { + type mockConfAwsSecrMgr struct { + Version string `json:"version"` + } ttests := map[string]struct { - objType any + input string + expPrefix config.ImplementationPrefix + expLookupKeys string + expStoreToken string + expString string // fullToken + expMetadataVersion string }{ - "test1": { - objType: nil, - }, + "bare": {"AWSSECRETS://foo/bar", config.SecretMgrPrefix, "", "foo/bar", "AWSSECRETS://foo/bar", ""}, + "with metadata version": {"AWSSECRETS://foo/bar[version=123]", config.SecretMgrPrefix, "", "foo/bar", "AWSSECRETS://foo/bar[version=123]", "123"}, + "with keys lookup and label": {"AWSSECRETS://foo/bar|key1.key2[version=123]", config.SecretMgrPrefix, "key1.key2", "foo/bar", "AWSSECRETS://foo/bar|key1.key2[version=123]", "123"}, + "with keys lookup and longer token": {"AWSSECRETS://foo/bar|key1.key2]version=123]", config.SecretMgrPrefix, "key1.key2]version=123]", "foo/bar", "AWSSECRETS://foo/bar|key1.key2]version=123]", ""}, + "with keys lookup but no keys": {"AWSSECRETS://foo/bar/sdf/sddd.90dsfsd|[version=123]", config.SecretMgrPrefix, "", "foo/bar/sdf/sddd.90dsfsd", "AWSSECRETS://foo/bar/sdf/sddd.90dsfsd|[version=123]", "123"}, } - for name, _ := range ttests { + for name, tt := range ttests { t.Run(name, func(t *testing.T) { + conf := &mockConfAwsSecrMgr{} + got, _ := config.NewParsedTokenConfig(tt.input, *config.NewConfig()) + got.ParseMetadata(conf) + if got.LookupKeys() != tt.expLookupKeys { + t.Errorf(testutils.TestPhrase, got.LookupKeys(), tt.expLookupKeys) + } + if got.StoreToken() != tt.expStoreToken { + t.Errorf(testutils.TestPhrase, got.StoreToken(), tt.expLookupKeys) + } + if got.String() != tt.expString { + t.Errorf(testutils.TestPhrase, got.String(), tt.expString) + } + if got.Prefix() != tt.expPrefix { + t.Errorf(testutils.TestPhrase, got.Prefix(), tt.expPrefix) + } + if conf.Version != tt.expMetadataVersion { + t.Errorf(testutils.TestPhrase, conf.Version, tt.expMetadataVersion) + } }) } } diff --git a/internal/store/store_test.go b/internal/store/store_test.go new file mode 100644 index 0000000..76de451 --- /dev/null +++ b/internal/store/store_test.go @@ -0,0 +1,24 @@ +package store_test + +import ( + "testing" + + "github.com/dnitsch/configmanager/internal/store" +) + +func Test_StoreDefault(t *testing.T) { + + t.Run("Default Shoudl not errror", func(t *testing.T) { + rs := store.NewDefatultStrategy() + if rs == nil { + t.Fatal("unable to init default strategy") + } + }) + t.Run("Token method should error", func(t *testing.T) { + rs := store.NewDefatultStrategy() + if _, err := rs.Token(); err == nil { + t.Fatal("Token should return not implemented error") + } + }) + +} diff --git a/internal/strategy/strategy.go b/internal/strategy/strategy.go index 5e9c532..9e4a3e4 100644 --- a/internal/strategy/strategy.go +++ b/internal/strategy/strategy.go @@ -11,7 +11,10 @@ import ( var ErrTokenInvalid = errors.New("invalid token - cannot get prefix") +// StrategyFunc type StrategyFunc func(ctx context.Context, token *config.ParsedTokenConfig) (store.Strategy, error) + +// StrategyFuncMap type StrategyFuncMap map[config.ImplementationPrefix]StrategyFunc var defaultStrategyFuncMap = map[config.ImplementationPrefix]StrategyFunc{ @@ -30,12 +33,12 @@ var defaultStrategyFuncMap = map[config.ImplementationPrefix]StrategyFunc{ config.ParamStorePrefix: func(ctx context.Context, token *config.ParsedTokenConfig) (store.Strategy, error) { return store.NewParamStore(ctx) }, - // config.ParamStorePrefix: - // return NewParamStore(ctx) - // case AzKeyVaultSecretsPrefix: - // return NewKvScrtStore(ctx, in, config) - // case HashicorpVaultPrefix: - // return NewVaultStore(ctx, in, config) + config.AzKeyVaultSecretsPrefix: func(ctx context.Context, token *config.ParsedTokenConfig) (store.Strategy, error) { + return store.NewKvScrtStore(ctx, token) + }, + config.HashicorpVaultPrefix: func(ctx context.Context, token *config.ParsedTokenConfig) (store.Strategy, error) { + return store.NewVaultStore(ctx, token) + }, } type RetrieveStrategy struct { diff --git a/internal/strategy/strategy_test.go b/internal/strategy/strategy_test.go index df4bbbd..433720e 100644 --- a/internal/strategy/strategy_test.go +++ b/internal/strategy/strategy_test.go @@ -25,6 +25,19 @@ func (m mockGenerate) Token() (s string, e error) { return m.value, m.err } +var TEST_GCP_CREDS = []byte(`{ + "type": "service_account", + "project_id": "xxxxx", + "private_key_id": "yyyyyyyyyyyy", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDf842hcn5Nvp6e\n7yKARaCVIDfLXpKDhRwUOvHMzJ1ioRgQo/kbv1n4yHGCSUFyY6hKGj0HBjaGj5kE\n79H/6Y3dJNGhnsMnxBhHdo+3FI8QF0CHZh460NMZSAJ41UMQSBGssGVsNfyUzXGH\nLc45sIx/Twx3yr1k2GD3E8FlDcKlZqa3xGHf+aipg2X3NxbYi+Sz7Yed+SOMhNHl\ncX6E/TqG9n1aTyIwjMIHscCYarJqURkJxr24ukDroCeMxAfxYTdMvRU2e8pFEdoY\nrgUC88fYfaVI5txJ6j/ZKauKQX9Pa8tSyXJeGva3JYp4VC7V4IyoVviCUgEGWZDN\n6/i3zoF/AgMBAAECggEAcVBCcVYFIkE48SH+Svjv74SFtpj7eSB4vKO2hPFjEOyB\nyKmu+aMwWvjQtiNqwf46wIPWLR+vpxYxTpYpo1sBNMvUZfp2tEA8KKyMuw3j9ThO\npjO9R/UxWrFcztbZP/u3NbFrH/2Q95mbv9IlbnsuG5xbqqEig0wYg+uzBvaXbig3\n/Jr0vLT2BkRCBKQkYGjVZcHlHVLoF7/J8cghFgkV1PGvknOv6/q7qzn9L4TjQIet\nfhrhN8Z1vgFiSYtpjP6YQEUEPSHmCQeD3WzJcnASPpU2uCUwd/z65ltKPnn+rqMt\n6jt9R1S1Ju2ZSjv+kR5fIXzihdOzncyzDDm33c/QwQKBgQD2QDZuzLjTxnhsfGii\nKJDAts+Jqfs/6SeEJcJKtEngj4m7rgzyEjbKVp8qtRHIzglKRWAe62/qzzy2BkKi\nvAd4+ZzmG2SkgypGsKVfjGXVFixz2gtUdmBOmK/TnYsxNT9yTt+rX9IGqKK60q73\nOWl8VsliLIsfvSH7+bqi7sRcXQKBgQDo0VUebyQHoTAXPdzGy2ysrVPDiHcldH0Y\n/hvhQTZwxYaJr3HpOCGol2Xl6zyawuudEQsoQwJ3Li6yeb0YMGiWX77/t+qX3pSn\nkGuoftGaNDV7sLn9UV2y+InF8EL1CasrhG1k5RIuxyfV0w+QUo+E7LpVR5XkbJqT\n9QNKnDQXiwKBgQDvvEYCCqbp7e/xVhEbxbhfFdro4Cat6tRAz+3egrTlvXhO0jzi\nMp9Kz5f3oP5ma0gaGX5hu75icE1fvKqE+d+ghAqe7w5FJzkyRulJI0tEb2jphN7A\n5NoPypBqyZboWjmhlG4mzouPVf/POCuEnk028truDAWJ6by7Lj3oP+HFNQKBgQCc\n5BQ8QiFBkvnZb7LLtGIzq0n7RockEnAK25LmJRAOxs13E2fsBguIlR3x5qgckqY8\nXjPqmd2bet+1HhyzpEuWqkcIBGRum2wJz2T9UxjklbJE/D8Z2i8OYDZX0SUOA8n5\ntXASwduS8lqB2Y1vcHOO3AhlV6xHFnjEpCPnr4PbKQKBgAhQ9D9MPeuz+5yw3yHg\nkvULZRtud+uuaKrOayprN25RTxr9c0erxqnvM7KHeo6/urOXeEa7x2n21kAT0Nch\nkF2RtWBLZKXGZEVBtw1Fw0UKNh4IDgM26dwlzRfTVHCiw6M6dCiTNk9KkP2vlkim\n3QFDSSUp+eBTXA17WkDAQf7w\n-----END PRIVATE KEY-----\n", + "client_email": "foo@project.iam.gserviceaccount.com", + "client_id": "99999911111111", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/bla" + }`) + func Test_Strategy_Retrieve_succeeds(t *testing.T) { ttests := map[string]struct { @@ -70,7 +83,6 @@ func Test_Strategy_Retrieve_succeeds(t *testing.T) { } func Test_CustomStrategyFuncMap_add_own(t *testing.T) { - // t.Skip() ttests := map[string]struct { }{ "default": {}, @@ -129,13 +141,110 @@ func Test_SelectImpl_With(t *testing.T) { "AZTABLESTORE#foo/bar1", config.NewConfig().WithTokenSeparator("#"), func() store.Strategy { - conf, _ := config.NewParsedTokenConfig("AZTABLESTORE#foo/bar1", *config.NewConfig().WithTokenSeparator("#")) - s, _ := store.NewAzTableStore(context.TODO(), conf) + token, _ := config.NewParsedTokenConfig("AZTABLESTORE#foo/bar1", *config.NewConfig().WithTokenSeparator("#")) + s, _ := store.NewAzTableStore(context.TODO(), token) + return s + }, + nil, + }, + "success AWSPARAMSTR": { + func() func() { + os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA") + os.Setenv("AWS_SECRET_ACCESS_KEY", "00000000000000000000111111111") + return func() { + os.Clearenv() + } + }, + "AWSPARAMSTR#foo/bar1", + config.NewConfig().WithTokenSeparator("#"), + func() store.Strategy { + s, _ := store.NewParamStore(context.TODO()) + return s + }, + nil, + }, + "success AWSSECRETS": { + func() func() { + os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA") + os.Setenv("AWS_SECRET_ACCESS_KEY", "00000000000000000000111111111") + return func() { + os.Clearenv() + } + }, + "AWSSECRETS#foo/bar1", + config.NewConfig().WithTokenSeparator("#"), + func() store.Strategy { + s, _ := store.NewSecretsMgr(context.TODO()) + return s + }, + nil, + }, + "success AZKVSECRET": { + func() func() { + os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA") + os.Setenv("AWS_SECRET_ACCESS_KEY", "00000000000000000000111111111") + return func() { + os.Clearenv() + } + }, + "AZKVSECRET#foo/bar1", + config.NewConfig().WithTokenSeparator("#"), + func() store.Strategy { + token, _ := config.NewParsedTokenConfig("AZKVSECRET#foo/bar1", *config.NewConfig().WithTokenSeparator("#")) + s, _ := store.NewKvScrtStore(context.TODO(), token) + return s + }, + nil, + }, + "success AZAPPCONF": { + func() func() { + return func() { + os.Clearenv() + } + }, + "AZAPPCONF#foo/bar1", + config.NewConfig().WithTokenSeparator("#"), + func() store.Strategy { + token, _ := config.NewParsedTokenConfig("AZAPPCONF#foo/bar1", *config.NewConfig().WithTokenSeparator("#")) + s, _ := store.NewAzAppConf(context.TODO(), token) + return s + }, + nil, + }, + "success VAULT": { + func() func() { + os.Setenv("VAULT_", "AAAAAAAAAAAAAAA") + return func() { + os.Clearenv() + } + }, + "VAULT#foo/bar1", + config.NewConfig().WithTokenSeparator("#"), + func() store.Strategy { + token, _ := config.NewParsedTokenConfig("VAULT#foo/bar1", *config.NewConfig().WithTokenSeparator("#")) + s, _ := store.NewVaultStore(context.TODO(), token) + return s + }, + nil, + }, + "success GCPSECRETS": { + func() func() { + cf, _ := os.CreateTemp(".", "*") + cf.Write(TEST_GCP_CREDS) + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", cf.Name()) + return func() { + os.Remove(cf.Name()) + os.Clearenv() + } + }, + "GCPSECRETS#foo/bar1", + config.NewConfig().WithTokenSeparator("#"), + func() store.Strategy { + s, _ := store.NewGcpSecrets(context.TODO()) return s }, nil, }, - // "default Error": { // func() func() { // os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA")