Support Vault Namespaces explicitly in CA config (#11477)

* Support Vault Namespaces explicitly in CA config

If there is a Namespace entry included in the Vault CA configuration,
set it as the Vault Namespace on the Vault client

Currently the only way to support Vault namespaces in the Consul CA
config is by doing one of the following:
1) Set the VAULT_NAMESPACE environment variable which will be picked up
by the Vault API client
2) Prefix all Vault paths with the namespace

Neither of these are super pleasant. The first requires direct access
and modification to the Consul runtime environment. It's possible and
expected, not super pleasant.

The second requires more indepth knowledge of Vault and how it uses
Namespaces and could be confusing for anyone without that context. It
also infers that it is not supported

* Add changelog

* Remove fmt.Fprint calls

* Make comment clearer

* Add next consul version to website docs

* Add new test for default configuration

* go mod tidy

* Add skip if vault not present

* Tweak changelog text
This commit is contained in:
Connor 2021-11-05 11:42:28 -05:00 committed by GitHub
parent 573ea1a95d
commit b3af482e09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 0 deletions

3
.changelog/11477.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
connect: add Namespace configuration setting for Vault CA provider
```

View File

@ -75,6 +75,14 @@ func (v *VaultProvider) Configure(cfg ProviderConfig) error {
}
client.SetToken(config.Token)
// We don't want to set the namespace if it's empty to prevent potential
// unknown behavior (what does Vault do with an empty namespace). The Vault
// client also makes sure the inputs are not empty strings so let's do the
// same.
if config.Namespace != "" {
client.SetNamespace(config.Namespace)
}
v.config = config
v.client = client
v.isPrimary = cfg.IsPrimary

View File

@ -10,6 +10,7 @@ import (
"github.com/hashicorp/go-hclog"
vaultapi "github.com/hashicorp/vault/api"
vaultconst "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/agent/connect"
@ -36,6 +37,46 @@ func TestVaultCAProvider_VaultTLSConfig(t *testing.T) {
require.Equal(config.TLSSkipVerify, tlsConfig.Insecure)
}
func TestVaultCAProvider_Configure(t *testing.T) {
SkipIfVaultNotPresent(t)
testcases := []struct {
name string
rawConfig map[string]interface{}
expectedValue func(t *testing.T, v *VaultProvider)
}{
{
name: "DefaultConfig",
rawConfig: map[string]interface{}{},
expectedValue: func(t *testing.T, v *VaultProvider) {
headers := v.client.Headers()
require.Equal(t, "", headers.Get(vaultconst.NamespaceHeaderName))
require.Equal(t, "pki-root/", v.config.RootPKIPath)
require.Equal(t, "pki-intermediate/", v.config.IntermediatePKIPath)
},
},
{
name: "TestConfigWithNamespace",
rawConfig: map[string]interface{}{"namespace": "ns1"},
expectedValue: func(t *testing.T, v *VaultProvider) {
h := v.client.Headers()
require.Equal(t, "ns1", h.Get(vaultconst.NamespaceHeaderName))
},
},
}
for _, testcase := range testcases {
t.Run(testcase.name, func(t *testing.T) {
provider, _ := testVaultProviderWithConfig(t, true, testcase.rawConfig)
testcase.expectedValue(t, provider)
})
}
return
}
func TestVaultCAProvider_SecondaryActiveIntermediate(t *testing.T) {
SkipIfVaultNotPresent(t)

View File

@ -473,6 +473,7 @@ type VaultCAProviderConfig struct {
Token string
RootPKIPath string
IntermediatePKIPath string
Namespace string
CAFile string
CAPath string

1
go.mod
View File

@ -57,6 +57,7 @@ require (
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea
github.com/hashicorp/serf v0.9.6-0.20210609195804-2b5dd0cd2de9
github.com/hashicorp/vault/api v1.0.5-0.20200717191844-f687267c8086
github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267
github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493
github.com/imdario/mergo v0.3.6
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f // indirect

View File

@ -132,6 +132,10 @@ The configuration options are listed below.
- `TLSSkipVerify` / `tls_skip_verify` (`bool: false`) - Specifies if SSL peer
validation should be enforced.
- `Namespace` / `namespace` (`string: <optional>`) - The Vault Namespace that
the `Token` and PKI Certificates are a part of. Vault Namespaces are a Vault
Enterprise feature. Added in Consul 1.11.0
@include 'http_api_connect_ca_common_options.mdx'
## Root and Intermediate PKI Paths