diff --git a/secretstores/hashicorp/vault/vault.go b/secretstores/hashicorp/vault/vault.go index 2a1c8de1a..2d65777cb 100644 --- a/secretstores/hashicorp/vault/vault.go +++ b/secretstores/hashicorp/vault/vault.go @@ -32,6 +32,7 @@ const ( componentCaPem string = "caPem" componentSkipVerify string = "skipVerify" componentTLSServerName string = "tlsServerName" + componentVaultToken string = "vaultToken" componentVaultTokenMountPath string = "vaultTokenMountPath" componentVaultKVPrefix string = "vaultKVPrefix" defaultVaultKVPrefix string = "dapr" @@ -43,6 +44,7 @@ const ( type vaultSecretStore struct { client *http.Client vaultAddress string + vaultToken string vaultTokenMountPath string vaultKVPrefix string @@ -92,6 +94,26 @@ func (v *vaultSecretStore) Init(metadata secretstores.Metadata) error { v.vaultAddress = address + v.vaultToken = props[componentVaultToken] + v.vaultTokenMountPath = props[componentVaultTokenMountPath] + + // Test that at least one of them are set if not return error + if v.vaultToken == "" && v.vaultTokenMountPath == "" { + return fmt.Errorf("token mount path and token not set") + } + + // Test that both are not set. If so return error + if v.vaultToken != "" && v.vaultTokenMountPath != "" { + return fmt.Errorf("token mount path and token both set") + } + + vaultKVPrefix := props[componentVaultKVPrefix] + if vaultKVPrefix == "" { + vaultKVPrefix = defaultVaultKVPrefix + } + + v.vaultKVPrefix = vaultKVPrefix + // Generate TLS config tlsConf := metadataToTLSConfig(props) @@ -102,20 +124,6 @@ func (v *vaultSecretStore) Init(metadata secretstores.Metadata) error { v.client = client - tokenMountPath := props[componentVaultTokenMountPath] - if tokenMountPath == "" { - return fmt.Errorf("token mount path not set") - } - - v.vaultTokenMountPath = tokenMountPath - - vaultKVPrefix := props[componentVaultKVPrefix] - if vaultKVPrefix == "" { - vaultKVPrefix = defaultVaultKVPrefix - } - - v.vaultKVPrefix = vaultKVPrefix - return nil } @@ -262,6 +270,10 @@ func (v *vaultSecretStore) BulkGetSecret(req secretstores.BulkGetSecretRequest) } func (v *vaultSecretStore) readVaultToken() (string, error) { + if v.vaultToken != "" { + return v.vaultToken, nil + } + data, err := ioutil.ReadFile(v.vaultTokenMountPath) if err != nil { return "", fmt.Errorf("couldn't read vault token: %s", err) diff --git a/secretstores/hashicorp/vault/vault_test.go b/secretstores/hashicorp/vault/vault_test.go index 95189fdd5..5d392c4f9 100644 --- a/secretstores/hashicorp/vault/vault_test.go +++ b/secretstores/hashicorp/vault/vault_test.go @@ -18,7 +18,9 @@ import ( const ( // base64 encoded certificate - certificate = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURVakNDQWpvQ0NRRFlZdzdMeXN4VXRUQU5CZ2txaGtpRzl3MEJBUXNGQURCck1Rc3dDUVlEVlFRR0V3SkQKUVRFWk1CY0dBMVVFQ0F3UVFuSnBkR2x6YUNCRGIyeDFiV0pwWVRFU01CQUdBMVVFQnd3SlZtRnVZMjkxZG1WeQpNUk13RVFZRFZRUUtEQXB0YVhOb2NtRmpiM0p3TVJnd0ZnWURWUVFEREE5MllYVnNkSEJ5YjJwbFkzUXVhVzh3CkhoY05NVGt4TVRBeE1UQTBPREV5V2hjTk1qQXhNRE14TVRBME9ERXlXakJyTVFzd0NRWURWUVFHRXdKRFFURVoKTUJjR0ExVUVDQXdRUW5KcGRHbHphQ0JEYjJ4MWJXSnBZVEVTTUJBR0ExVUVCd3dKVm1GdVkyOTFkbVZ5TVJNdwpFUVlEVlFRS0RBcHRhWE5vY21GamIzSndNUmd3RmdZRFZRUUREQTkyWVhWc2RIQnliMnBsWTNRdWFXOHdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3JtaitTTmtGUHEvK2FXUFV1MlpFamtSK3AKTm1PeEVNSnZZcGhHNkJvRFAySE9ZbGRzdk9FWkRkbTBpWFlmeFIwZm5rUmtTMWEzSlZiYmhINWJnTElKb0dxcwo5aWpzN2hyQ0Rrdk9uRWxpUEZuc05pQ2NWNDNxNkZYaFMvNFpoNGpOMnlyUkU2UmZiS1BEeUw0a282NkFhSld1CnVkTldKVWpzSFZBSWowZHlnTXFKYm0rT29iSzk5ckUxcDg5Z3RNUStJdzFkWnUvUFF4SjlYOStMeXdxZUxPckQKOWhpNWkxajNFUUp2RXQxSVUzclEwc2E0NU5zZkt4YzEwZjdhTjJuSDQzSnhnMVRiZXNPOWYrcWlyeDBHYmVSYQpyVmNaazNVaFc2cHZmam9XbDBEc0NwNTJwZDBQN05rUmhmak44b2RMN0h3bFVIc1NqemlSYytsTG5YREJBZ01CCkFBRXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSVdKdmRPZ01PUnQxWk53SENkNTNieTlkMlBkcW5tWHFZZ20KNDZHK2Fvb1dSeTJKMEMwS3ZOVGZGbEJFOUlydzNXUTVNMnpqY25qSUp5bzNLRUM5TDdPMnQ1WC9LTGVDck5ZVgpIc1d4cU5BTVBGY2VBa09HT0I1TThGVllkdjJTaVV2UDJjMEZQSzc2WFVzcVNkdnRsWGFkTk5ENzE3T0NTNm0yCnBIVjh1NWJNd1VmR2NCVFpEV2o4bjIzRVdHaXdnYkJkdDc3Z3h3YWc5NTROZkM2Ny9nSUc5ZlRrTTQ4aVJCUzEKc0NGYVBjMkFIT3hiMSs0ajVCMVY2Z29iZDZYWkFvbHdNaTNHUUtkbEM1NXZNeTNwK09WbDNNbEc3RWNTVUpMdApwZ2ZKaWw3L3dTWWhpUnhJU3hrYkk5cWhvNEwzZm5PZVB3clFVd2FzU1ZiL1lxbHZ2WHM9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" + certificate = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURVakNDQWpvQ0NRRFlZdzdMeXN4VXRUQU5CZ2txaGtpRzl3MEJBUXNGQURCck1Rc3dDUVlEVlFRR0V3SkQKUVRFWk1CY0dBMVVFQ0F3UVFuSnBkR2x6YUNCRGIyeDFiV0pwWVRFU01CQUdBMVVFQnd3SlZtRnVZMjkxZG1WeQpNUk13RVFZRFZRUUtEQXB0YVhOb2NtRmpiM0p3TVJnd0ZnWURWUVFEREE5MllYVnNkSEJ5YjJwbFkzUXVhVzh3CkhoY05NVGt4TVRBeE1UQTBPREV5V2hjTk1qQXhNRE14TVRBME9ERXlXakJyTVFzd0NRWURWUVFHRXdKRFFURVoKTUJjR0ExVUVDQXdRUW5KcGRHbHphQ0JEYjJ4MWJXSnBZVEVTTUJBR0ExVUVCd3dKVm1GdVkyOTFkbVZ5TVJNdwpFUVlEVlFRS0RBcHRhWE5vY21GamIzSndNUmd3RmdZRFZRUUREQTkyWVhWc2RIQnliMnBsWTNRdWFXOHdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3JtaitTTmtGUHEvK2FXUFV1MlpFamtSK3AKTm1PeEVNSnZZcGhHNkJvRFAySE9ZbGRzdk9FWkRkbTBpWFlmeFIwZm5rUmtTMWEzSlZiYmhINWJnTElKb0dxcwo5aWpzN2hyQ0Rrdk9uRWxpUEZuc05pQ2NWNDNxNkZYaFMvNFpoNGpOMnlyUkU2UmZiS1BEeUw0a282NkFhSld1CnVkTldKVWpzSFZBSWowZHlnTXFKYm0rT29iSzk5ckUxcDg5Z3RNUStJdzFkWnUvUFF4SjlYOStMeXdxZUxPckQKOWhpNWkxajNFUUp2RXQxSVUzclEwc2E0NU5zZkt4YzEwZjdhTjJuSDQzSnhnMVRiZXNPOWYrcWlyeDBHYmVSYQpyVmNaazNVaFc2cHZmam9XbDBEc0NwNTJwZDBQN05rUmhmak44b2RMN0h3bFVIc1NqemlSYytsTG5YREJBZ01CCkFBRXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSVdKdmRPZ01PUnQxWk53SENkNTNieTlkMlBkcW5tWHFZZ20KNDZHK2Fvb1dSeTJKMEMwS3ZOVGZGbEJFOUlydzNXUTVNMnpqY25qSUp5bzNLRUM5TDdPMnQ1WC9LTGVDck5ZVgpIc1d4cU5BTVBGY2VBa09HT0I1TThGVllkdjJTaVV2UDJjMEZQSzc2WFVzcVNkdnRsWGFkTk5ENzE3T0NTNm0yCnBIVjh1NWJNd1VmR2NCVFpEV2o4bjIzRVdHaXdnYkJkdDc3Z3h3YWc5NTROZkM2Ny9nSUc5ZlRrTTQ4aVJCUzEKc0NGYVBjMkFIT3hiMSs0ajVCMVY2Z29iZDZYWkFvbHdNaTNHUUtkbEM1NXZNeTNwK09WbDNNbEc3RWNTVUpMdApwZ2ZKaWw3L3dTWWhpUnhJU3hrYkk5cWhvNEwzZm5PZVB3clFVd2FzU1ZiL1lxbHZ2WHM9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" + expectedTok = "myRootToken" + expectedTokMountPath = "./vault.txt" ) func TestReadVaultToken(t *testing.T) { @@ -60,6 +62,17 @@ func TestReadVaultToken(t *testing.T) { assert.Nil(t, err) assert.NotEqual(t, "thisistheroottoken", token) }) + + t.Run("read token from vaultToken", func(t *testing.T) { + v := vaultSecretStore{ + vaultToken: expectedTok, + } + + actualToken, err := v.readVaultToken() + + assert.Nil(t, err) + assert.Equal(t, expectedTok, actualToken) + }) } func TestVaultTLSConfig(t *testing.T) { @@ -84,6 +97,99 @@ func TestVaultTLSConfig(t *testing.T) { }) } +func TestVaultTokenMountPathOrVaultTokenRequired(t *testing.T) { + t.Run("without vaultTokenMount or vaultToken", func(t *testing.T) { + properties := map[string]string{} + + m := secretstores.Metadata{ + Properties: properties, + } + + target := &vaultSecretStore{ + client: nil, + logger: nil, + } + + err := target.Init(m) + + assert.Equal(t, "", target.vaultToken) + assert.Equal(t, "", target.vaultTokenMountPath) + assert.NotNil(t, err) + assert.Equal(t, "token mount path and token not set", err.Error()) + }) + + t.Run("with vaultTokenMount", func(t *testing.T) { + properties := map[string]string{ + "vaultTokenMountPath": expectedTokMountPath, + } + + m := secretstores.Metadata{ + Properties: properties, + } + + target := &vaultSecretStore{ + client: nil, + logger: nil, + } + + // This call will throw an error on Windows systems because of the of + // the call x509.SystemCertPool() because system root pool is not + // available on Windows so ignore the error for when the tests are run + // on the Windows platform during CI + _ = target.Init(m) + + assert.Equal(t, "", target.vaultToken) + assert.Equal(t, expectedTokMountPath, target.vaultTokenMountPath) + }) + + t.Run("with vaultToken", func(t *testing.T) { + properties := map[string]string{ + "vaultToken": expectedTok, + } + + m := secretstores.Metadata{ + Properties: properties, + } + + target := &vaultSecretStore{ + client: nil, + logger: nil, + } + + // This call will throw an error on Windows systems because of the of + // the call x509.SystemCertPool() because system root pool is not + // available on Windows so ignore the error for when the tests are run + // on the Windows platform during CI + _ = target.Init(m) + + assert.Equal(t, "", target.vaultTokenMountPath) + assert.Equal(t, expectedTok, target.vaultToken) + }) + + t.Run("with vaultTokenMount and vaultToken", func(t *testing.T) { + properties := map[string]string{ + "vaultToken": expectedTok, + "vaultTokenMountPath": expectedTokMountPath, + } + + m := secretstores.Metadata{ + Properties: properties, + } + + target := &vaultSecretStore{ + client: nil, + logger: nil, + } + + err := target.Init(m) + + assert.Equal(t, expectedTok, target.vaultToken) + assert.Equal(t, expectedTokMountPath, target.vaultTokenMountPath) + assert.NotNil(t, err) + assert.Equal(t, "token mount path and token both set", err.Error()) + }) +} + func TestDefaultVaultAddress(t *testing.T) { t.Run("with blank vaultAddr", func(t *testing.T) { properties := map[string]string{