Skip to content

Commit f3a706d

Browse files
InverseIntegralMarcosDY
authored andcommitted
Test vault key manager configure function (spiffe#5058)
Signed-off-by: Matteo Kamm <[email protected]>
1 parent d3b4af0 commit f3a706d

File tree

2 files changed

+391
-0
lines changed

2 files changed

+391
-0
lines changed
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
package hashicorpvault
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"github.com/stretchr/testify/require"
7+
"google.golang.org/grpc/codes"
8+
"testing"
9+
"text/template"
10+
11+
"github.com/spiffe/go-spiffe/v2/spiffeid"
12+
"github.com/spiffe/spire/pkg/common/catalog"
13+
"github.com/spiffe/spire/test/plugintest"
14+
"github.com/spiffe/spire/test/spiretest"
15+
)
16+
17+
func TestConfigure(t *testing.T) {
18+
fakeVaultServer := setupFakeVaultServer()
19+
fakeVaultServer.CertAuthResponseCode = 200
20+
fakeVaultServer.CertAuthResponse = []byte(testCertAuthResponse)
21+
fakeVaultServer.CertAuthReqEndpoint = "/v1/auth/test-cert-auth/login"
22+
fakeVaultServer.AppRoleAuthResponseCode = 200
23+
fakeVaultServer.AppRoleAuthResponse = []byte(testAppRoleAuthResponse)
24+
fakeVaultServer.AppRoleAuthReqEndpoint = "/v1/auth/test-approle-auth/login"
25+
26+
s, addr, err := fakeVaultServer.NewTLSServer()
27+
require.NoError(t, err)
28+
29+
s.Start()
30+
defer s.Close()
31+
32+
for _, tt := range []struct {
33+
name string
34+
configTmpl string
35+
plainConfig string
36+
expectMsgPrefix string
37+
expectCode codes.Code
38+
wantAuth AuthMethod
39+
expectNamespace string
40+
envKeyVal map[string]string
41+
expectToken string
42+
expectCertAuthMountPoint string
43+
expectClientCertPath string
44+
expectClientKeyPath string
45+
appRoleAuthMountPoint string
46+
appRoleID string
47+
appRoleSecretID string
48+
expectK8sAuthMountPoint string
49+
expectK8sAuthRoleName string
50+
expectK8sAuthTokenPath string
51+
expectTransitEnginePath string
52+
}{
53+
{
54+
name: "Configure plugin with Client Certificate authentication params given in config file",
55+
configTmpl: testTokenAuthConfigTpl,
56+
wantAuth: TOKEN,
57+
expectToken: "test-token",
58+
expectTransitEnginePath: "transit",
59+
},
60+
{
61+
name: "Configure plugin with Token authentication params given as environment variables",
62+
configTmpl: testTokenAuthConfigWithEnvTpl,
63+
envKeyVal: map[string]string{
64+
envVaultToken: "test-token",
65+
},
66+
wantAuth: TOKEN,
67+
expectToken: "test-token",
68+
expectTransitEnginePath: "transit",
69+
},
70+
{
71+
name: "Configure plugin with Client Certificate authentication params given in config file",
72+
configTmpl: testCertAuthConfigTpl,
73+
wantAuth: CERT,
74+
expectCertAuthMountPoint: "test-cert-auth",
75+
expectClientCertPath: "testdata/client-cert.pem",
76+
expectClientKeyPath: "testdata/client-key.pem",
77+
expectTransitEnginePath: "transit",
78+
},
79+
{
80+
name: "Configure plugin with Client Certificate authentication params given as environment variables",
81+
configTmpl: testCertAuthConfigWithEnvTpl,
82+
envKeyVal: map[string]string{
83+
envVaultClientCert: "testdata/client-cert.pem",
84+
envVaultClientKey: testClientKey,
85+
},
86+
wantAuth: CERT,
87+
expectCertAuthMountPoint: "test-cert-auth",
88+
expectClientCertPath: testClientCert,
89+
expectClientKeyPath: testClientKey,
90+
expectTransitEnginePath: "transit",
91+
},
92+
{
93+
name: "Configure plugin with AppRole authenticate params given in config file",
94+
configTmpl: testAppRoleAuthConfigTpl,
95+
wantAuth: APPROLE,
96+
appRoleAuthMountPoint: "test-approle-auth",
97+
appRoleID: "test-approle-id",
98+
appRoleSecretID: "test-approle-secret-id",
99+
expectTransitEnginePath: "transit",
100+
},
101+
{
102+
name: "Configure plugin with AppRole authentication params given as environment variables",
103+
configTmpl: testAppRoleAuthConfigWithEnvTpl,
104+
envKeyVal: map[string]string{
105+
envVaultAppRoleID: "test-approle-id",
106+
envVaultAppRoleSecretID: "test-approle-secret-id",
107+
},
108+
wantAuth: APPROLE,
109+
appRoleAuthMountPoint: "test-approle-auth",
110+
appRoleID: "test-approle-id",
111+
appRoleSecretID: "test-approle-secret-id",
112+
expectTransitEnginePath: "transit",
113+
},
114+
{
115+
name: "Configure plugin with Kubernetes authentication params given in config file",
116+
configTmpl: testK8sAuthConfigTpl,
117+
wantAuth: K8S,
118+
expectK8sAuthMountPoint: "test-k8s-auth",
119+
expectK8sAuthTokenPath: "testdata/k8s/token",
120+
expectK8sAuthRoleName: "my-role",
121+
expectTransitEnginePath: "transit",
122+
},
123+
{
124+
name: "Multiple authentication methods configured",
125+
configTmpl: testMultipleAuthConfigsTpl,
126+
expectCode: codes.InvalidArgument,
127+
expectMsgPrefix: "only one authentication method can be configured",
128+
},
129+
{
130+
name: "Pass VaultAddr via the environment variable",
131+
configTmpl: testConfigWithVaultAddrEnvTpl,
132+
envKeyVal: map[string]string{
133+
envVaultAddr: fmt.Sprintf("https://%v/", addr),
134+
},
135+
wantAuth: TOKEN,
136+
expectToken: "test-token",
137+
expectTransitEnginePath: "transit",
138+
},
139+
{
140+
name: "Configure plugin with transit engine path given in config file",
141+
configTmpl: testConfigWithTransitEnginePathTpl,
142+
wantAuth: TOKEN,
143+
expectToken: "test-token",
144+
expectTransitEnginePath: "test-path",
145+
},
146+
{
147+
name: "Configure plugin with transit engine path given as environment variables",
148+
configTmpl: testConfigWithTransitEnginePathEnvTpl,
149+
envKeyVal: map[string]string{
150+
envVaultTransitEnginePath: "test-path",
151+
},
152+
wantAuth: TOKEN,
153+
expectToken: "test-token",
154+
expectTransitEnginePath: "test-path",
155+
},
156+
{
157+
name: "Configure plugin with namespace given in config file",
158+
configTmpl: testNamespaceConfigTpl,
159+
wantAuth: TOKEN,
160+
expectNamespace: "test-ns",
161+
expectTransitEnginePath: "transit",
162+
expectToken: "test-token",
163+
},
164+
{
165+
name: "Configure plugin with given namespace given as environment variable",
166+
configTmpl: testNamespaceEnvTpl,
167+
wantAuth: TOKEN,
168+
envKeyVal: map[string]string{
169+
envVaultNamespace: "test-ns",
170+
},
171+
expectNamespace: "test-ns",
172+
expectTransitEnginePath: "transit",
173+
expectToken: "test-token",
174+
},
175+
{
176+
name: "Malformed configuration",
177+
plainConfig: "invalid-config",
178+
expectCode: codes.InvalidArgument,
179+
expectMsgPrefix: "unable to decode configuration:",
180+
},
181+
{
182+
name: "Required parameters are not given / k8s_auth_role_name",
183+
configTmpl: testK8sAuthNoRoleNameTpl,
184+
wantAuth: K8S,
185+
expectCode: codes.InvalidArgument,
186+
expectMsgPrefix: "k8s_auth_role_name is required",
187+
},
188+
{
189+
name: "Required parameters are not given / token_path",
190+
configTmpl: testK8sAuthNoTokenPathTpl,
191+
wantAuth: K8S,
192+
expectCode: codes.InvalidArgument,
193+
expectMsgPrefix: "token_path is required",
194+
},
195+
} {
196+
tt := tt
197+
t.Run(tt.name, func(t *testing.T) {
198+
var err error
199+
200+
p := New()
201+
p.hooks.lookupEnv = func(s string) (string, bool) {
202+
if len(tt.envKeyVal) == 0 {
203+
return "", false
204+
}
205+
v, ok := tt.envKeyVal[s]
206+
return v, ok
207+
}
208+
209+
plainConfig := ""
210+
if tt.plainConfig != "" {
211+
plainConfig = tt.plainConfig
212+
} else {
213+
plainConfig = getTestConfigureRequest(t, fmt.Sprintf("https://%v/", addr), tt.configTmpl)
214+
}
215+
plugintest.Load(t, builtin(p), nil,
216+
plugintest.CaptureConfigureError(&err),
217+
plugintest.Configure(plainConfig),
218+
plugintest.CoreConfig(catalog.CoreConfig{
219+
TrustDomain: spiffeid.RequireTrustDomainFromString("localhost"),
220+
}),
221+
)
222+
223+
spiretest.RequireGRPCStatusHasPrefix(t, err, tt.expectCode, tt.expectMsgPrefix)
224+
if tt.expectCode != codes.OK {
225+
return
226+
}
227+
228+
require.NotNil(t, p.cc)
229+
require.NotNil(t, p.cc.clientParams)
230+
231+
switch tt.wantAuth {
232+
case TOKEN:
233+
require.Equal(t, tt.expectToken, p.cc.clientParams.Token)
234+
case CERT:
235+
require.Equal(t, tt.expectCertAuthMountPoint, p.cc.clientParams.CertAuthMountPoint)
236+
require.Equal(t, tt.expectClientCertPath, p.cc.clientParams.ClientCertPath)
237+
require.Equal(t, tt.expectClientKeyPath, p.cc.clientParams.ClientKeyPath)
238+
case APPROLE:
239+
require.NotNil(t, p.cc.clientParams.AppRoleAuthMountPoint)
240+
require.NotNil(t, p.cc.clientParams.AppRoleID)
241+
require.NotNil(t, p.cc.clientParams.AppRoleSecretID)
242+
case K8S:
243+
require.Equal(t, tt.expectK8sAuthMountPoint, p.cc.clientParams.K8sAuthMountPoint)
244+
require.Equal(t, tt.expectK8sAuthRoleName, p.cc.clientParams.K8sAuthRoleName)
245+
require.Equal(t, tt.expectK8sAuthTokenPath, p.cc.clientParams.K8sAuthTokenPath)
246+
}
247+
248+
require.Equal(t, tt.expectTransitEnginePath, p.cc.clientParams.TransitEnginePath)
249+
require.Equal(t, tt.expectNamespace, p.cc.clientParams.Namespace)
250+
})
251+
}
252+
}
253+
254+
func getTestConfigureRequest(t *testing.T, addr string, tpl string) string {
255+
templ, err := template.New("plugin config").Parse(tpl)
256+
require.NoError(t, err)
257+
258+
cp := &struct{ Addr string }{Addr: addr}
259+
260+
var c bytes.Buffer
261+
err = templ.Execute(&c, cp)
262+
require.NoError(t, err)
263+
264+
return c.String()
265+
}
266+
267+
func setupFakeVaultServer() *FakeVaultServerConfig {
268+
fakeVaultServer := NewFakeVaultServerConfig()
269+
fakeVaultServer.ServerCertificatePemPath = testServerCert
270+
fakeVaultServer.ServerKeyPemPath = testServerKey
271+
fakeVaultServer.RenewResponseCode = 200
272+
fakeVaultServer.RenewResponse = []byte(testRenewResponse)
273+
return fakeVaultServer
274+
}

pkg/server/plugin/keymanager/hashicorpvault/vault_fake_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,123 @@ const (
2121
)
2222

2323
var (
24+
testTokenAuthConfigTpl = `
25+
vault_addr = "{{ .Addr }}"
26+
ca_cert_path = "testdata/root-cert.pem"
27+
token_auth {
28+
token = "test-token"
29+
}`
30+
31+
testTokenAuthConfigWithEnvTpl = `
32+
vault_addr = "{{ .Addr }}"
33+
ca_cert_path = "testdata/root-cert.pem"
34+
token_auth {}`
35+
36+
testCertAuthConfigTpl = `
37+
vault_addr = "{{ .Addr }}"
38+
ca_cert_path = "testdata/root-cert.pem"
39+
cert_auth {
40+
cert_auth_mount_point = "test-cert-auth"
41+
cert_auth_role_name = "test"
42+
client_cert_path = "testdata/client-cert.pem"
43+
client_key_path = "testdata/client-key.pem"
44+
}`
45+
46+
testCertAuthConfigWithEnvTpl = `
47+
vault_addr = "{{ .Addr }}"
48+
ca_cert_path = "testdata/root-cert.pem"
49+
cert_auth {
50+
cert_auth_mount_point = "test-cert-auth"
51+
}`
52+
53+
testAppRoleAuthConfigTpl = `
54+
vault_addr = "{{ .Addr }}"
55+
ca_cert_path = "testdata/root-cert.pem"
56+
approle_auth {
57+
approle_auth_mount_point = "test-approle-auth"
58+
approle_id = "test-approle-id"
59+
approle_secret_id = "test-approle-secret-id"
60+
}`
61+
62+
testAppRoleAuthConfigWithEnvTpl = `
63+
vault_addr = "{{ .Addr }}"
64+
ca_cert_path = "testdata/root-cert.pem"
65+
approle_auth {
66+
approle_auth_mount_point = "test-approle-auth"
67+
}`
68+
69+
testK8sAuthConfigTpl = `
70+
vault_addr = "{{ .Addr }}"
71+
ca_cert_path = "testdata/root-cert.pem"
72+
k8s_auth {
73+
k8s_auth_mount_point = "test-k8s-auth"
74+
k8s_auth_role_name = "my-role"
75+
token_path = "testdata/k8s/token"
76+
}`
77+
78+
testMultipleAuthConfigsTpl = `
79+
vault_addr = "{{ .Addr }}"
80+
ca_cert_path = "testdata/root-cert.pem"
81+
cert_auth {}
82+
token_auth {}
83+
approle_auth {
84+
approle_auth_mount_point = "test-approle-auth"
85+
approle_id = "test-approle-id"
86+
approle_secret_id = "test-approle-secret-id"
87+
}`
88+
89+
testConfigWithVaultAddrEnvTpl = `
90+
ca_cert_path = "testdata/root-cert.pem"
91+
token_auth {
92+
token = "test-token"
93+
}`
94+
95+
testConfigWithTransitEnginePathTpl = `
96+
transit_engine_path = "test-path"
97+
vault_addr = "{{ .Addr }}"
98+
ca_cert_path = "testdata/root-cert.pem"
99+
token_auth {
100+
token = "test-token"
101+
}`
102+
103+
testConfigWithTransitEnginePathEnvTpl = `
104+
vault_addr = "{{ .Addr }}"
105+
ca_cert_path = "testdata/root-cert.pem"
106+
token_auth {
107+
token = "test-token"
108+
}`
109+
110+
testNamespaceConfigTpl = `
111+
namespace = "test-ns"
112+
vault_addr = "{{ .Addr }}"
113+
ca_cert_path = "testdata/root-cert.pem"
114+
token_auth {
115+
token = "test-token"
116+
}`
117+
118+
testNamespaceEnvTpl = `
119+
vault_addr = "{{ .Addr }}"
120+
ca_cert_path = "testdata/root-cert.pem"
121+
token_auth {
122+
token = "test-token"
123+
}`
124+
125+
testK8sAuthNoRoleNameTpl = `
126+
vault_addr = "{{ .Addr }}"
127+
ca_cert_path = "testdata/root-cert.pem"
128+
k8s_auth {
129+
k8s_auth_mount_point = "test-k8s-auth"
130+
token_path = "testdata/k8s/token"
131+
}`
132+
133+
testK8sAuthNoTokenPathTpl = `
134+
vault_addr = "{{ .Addr }}"
135+
ca_cert_path = "testdata/root-cert.pem"
136+
k8s_auth {
137+
k8s_auth_mount_point = "test-k8s-auth"
138+
k8s_auth_role_name = "my-role"
139+
}`
140+
24141
testCertAuthResponse = `{
25142
"auth": {
26143
"client_token": "cf95f87d-f95b-47ff-b1f5-ba7bff850425",

0 commit comments

Comments
 (0)