From d5da380c6d68a74b31194b38460304400cbea992 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Wed, 28 Feb 2024 17:24:28 -0800 Subject: [PATCH 1/3] Set VaultConnection headers on the vault client --- controllers/vaultconnection_controller.go | 1 + internal/vault/client.go | 1 + internal/vault/config.go | 7 +++++- internal/vault/config_test.go | 29 +++++++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/controllers/vaultconnection_controller.go b/controllers/vaultconnection_controller.go index a01917499..3647da73f 100644 --- a/controllers/vaultconnection_controller.go +++ b/controllers/vaultconnection_controller.go @@ -73,6 +73,7 @@ func (r *VaultConnectionReconciler) Reconcile(ctx context.Context, req ctrl.Requ Address: o.Spec.Address, SkipTLSVerify: o.Spec.SkipTLSVerify, TLSServerName: o.Spec.TLSServerName, + Headers: o.Spec.Headers, } var errs error diff --git a/internal/vault/client.go b/internal/vault/client.go index 687d01964..c407f1f81 100644 --- a/internal/vault/client.go +++ b/internal/vault/client.go @@ -606,6 +606,7 @@ func (c *defaultClient) init(ctx context.Context, client ctrlclient.Client, VaultNamespace: authObj.Spec.Namespace, K8sNamespace: connObj.Namespace, CACertSecretRef: connObj.Spec.CACertSecretRef, + Headers: connObj.Spec.Headers, } vc, err := MakeVaultClient(ctx, cfg, client) diff --git a/internal/vault/config.go b/internal/vault/config.go index a6ac0cfe8..c6aefae34 100644 --- a/internal/vault/config.go +++ b/internal/vault/config.go @@ -9,7 +9,7 @@ import ( "fmt" "github.com/hashicorp/vault/api" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" @@ -35,6 +35,8 @@ type ClientConfig struct { TLSServerName string // VaultNamespace is the namespace in Vault to auth to VaultNamespace string + // Headers are http headers to set on the Vault client + Headers map[string]string } // MakeVaultClient creates a Vault api.Client from a ClientConfig. @@ -96,6 +98,9 @@ func MakeVaultClient(ctx context.Context, cfg *ClientConfig, client ctrlclient.C if cfg.VaultNamespace != "" { c.SetNamespace(cfg.VaultNamespace) } + for k, v := range cfg.Headers { + c.AddHeader(k, v) + } return c, nil } diff --git a/internal/vault/config_test.go b/internal/vault/config_test.go index acaf041e5..6d128a415 100644 --- a/internal/vault/config_test.go +++ b/internal/vault/config_test.go @@ -72,6 +72,17 @@ func TestMakeVaultClient(t *testing.T) { CACert: nil, expectedError: nil, }, + "headers": { + vaultConfig: &ClientConfig{ + Headers: map[string]string{ + "X-Proxy-Setting": "yes", + "Y-Proxy-Setting": "no", + }, + VaultNamespace: "vault-test-namespace", + }, + CACert: nil, + expectedError: nil, + }, } for name, tc := range tests { @@ -116,7 +127,25 @@ func TestMakeVaultClient(t *testing.T) { require.NoError(t, err) assert.True(t, tlsConfig.RootCAs.Equal(expectedCertPool), "The CA cert in the client doesn't match the expected cert") } + + expectedHeaders := makeVaultHttpHeaders(t, tc.vaultConfig.VaultNamespace, tc.vaultConfig.Headers) + assert.Equal(t, expectedHeaders, vaultClient.Headers(), "The headers in the client don't match the expected headers") } }) } } + +func makeVaultHttpHeaders(t *testing.T, namespace string, headers map[string]string) http.Header { + t.Helper() + + h := make(http.Header) + for k, v := range headers { + h.Set(k, v) + } + h.Set("X-Vault-Request", "true") + if len(namespace) > 0 { + h.Set(vconsts.NamespaceHeaderName, namespace) + } + + return h +} From 10af3b436e5eecb59f858ab6fb1156e3493e936e Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Mon, 4 Mar 2024 22:25:49 -0800 Subject: [PATCH 2/3] prevent vault namespace header override in VaultConnection --- internal/vault/config.go | 8 ++++++-- internal/vault/config_test.go | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/internal/vault/config.go b/internal/vault/config.go index c6aefae34..cd30fc866 100644 --- a/internal/vault/config.go +++ b/internal/vault/config.go @@ -9,6 +9,7 @@ import ( "fmt" "github.com/hashicorp/vault/api" + vconsts "github.com/hashicorp/vault/sdk/helper/consts" v1 "k8s.io/api/core/v1" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" @@ -95,12 +96,15 @@ func MakeVaultClient(ctx context.Context, cfg *ClientConfig, client ctrlclient.C l.Error(err, "error setting up Vault API client") return nil, err } - if cfg.VaultNamespace != "" { - c.SetNamespace(cfg.VaultNamespace) + if _, exists := cfg.Headers[vconsts.NamespaceHeaderName]; exists { + return nil, fmt.Errorf("setting header %q on VaultConnection is not permitted", vconsts.NamespaceHeaderName) } for k, v := range cfg.Headers { c.AddHeader(k, v) } + if cfg.VaultNamespace != "" { + c.SetNamespace(cfg.VaultNamespace) + } return c, nil } diff --git a/internal/vault/config_test.go b/internal/vault/config_test.go index 6d128a415..554d9ef87 100644 --- a/internal/vault/config_test.go +++ b/internal/vault/config_test.go @@ -83,6 +83,18 @@ func TestMakeVaultClient(t *testing.T) { CACert: nil, expectedError: nil, }, + "headers can't override namespace": { + vaultConfig: &ClientConfig{ + Headers: map[string]string{ + "X-Proxy-Setting": "yes", + "Y-Proxy-Setting": "no", + vconsts.NamespaceHeaderName: "nope", + }, + VaultNamespace: "vault-test-namespace", + }, + CACert: nil, + expectedError: fmt.Errorf(`setting header "X-Vault-Namespace" on VaultConnection is not permitted`), + }, } for name, tc := range tests { @@ -108,7 +120,7 @@ func TestMakeVaultClient(t *testing.T) { assert.Nil(t, vaultClient) } else { assert.NoError(t, err) - assert.NotNil(t, vaultClient) + require.NotNil(t, vaultClient) vaultClient.SetCloneHeaders(true) vaultConfig := vaultClient.CloneConfig() From 02366042b67e2453536af14258390918e93f84d7 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Tue, 5 Mar 2024 23:13:33 -0800 Subject: [PATCH 3/3] string check --- internal/vault/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/vault/config_test.go b/internal/vault/config_test.go index 554d9ef87..62918d410 100644 --- a/internal/vault/config_test.go +++ b/internal/vault/config_test.go @@ -155,7 +155,7 @@ func makeVaultHttpHeaders(t *testing.T, namespace string, headers map[string]str h.Set(k, v) } h.Set("X-Vault-Request", "true") - if len(namespace) > 0 { + if namespace != "" { h.Set(vconsts.NamespaceHeaderName, namespace) }