mirror of https://github.com/hashicorp/consul
use provider specific env variable and add precedence
parent
977e90dfda
commit
0aa03f71ca
|
@ -1,3 +1,3 @@
|
|||
```release-note:improvement
|
||||
connect: add support for setting Vault address and token from VAULT_ADDR and VAULT_TOKEN environment variables for the Connect CA provider
|
||||
connect: add support for setting Vault address and token through environment variables CONSUL_MESH_CA_VAULT_ADDR and CONSUL_MESH_CA_VAULT_TOKEN for the CA provider
|
||||
```
|
||||
|
|
|
@ -29,6 +29,9 @@ import (
|
|||
const (
|
||||
VaultCALeafCertRole = "leaf-cert"
|
||||
|
||||
VaultCAEnvAddr = "CONSUL_MESH_CA_VAULT_ADDR"
|
||||
VaultCAEnvToken = "CONSUL_MESH_CA_VAULT_TOKEN"
|
||||
|
||||
VaultAuthMethodTypeAliCloud = "alicloud"
|
||||
VaultAuthMethodTypeAppRole = "approle"
|
||||
VaultAuthMethodTypeAWS = "aws"
|
||||
|
@ -925,36 +928,28 @@ func ParseVaultCAConfig(raw map[string]interface{}, isPrimary bool) (*structs.Va
|
|||
return nil, fmt.Errorf("error decoding config: %s", err)
|
||||
}
|
||||
|
||||
envAddr := os.Getenv(vaultapi.EnvVaultAddress)
|
||||
envAddr := os.Getenv(VaultCAEnvAddr)
|
||||
if config.Address == "" && envAddr == "" {
|
||||
return nil, fmt.Errorf("must provide a Vault address")
|
||||
}
|
||||
|
||||
if config.Address != "" && envAddr != "" {
|
||||
return nil, fmt.Errorf("only one Vault address can be provided")
|
||||
}
|
||||
|
||||
if envAddr != "" {
|
||||
config.Address = envAddr
|
||||
}
|
||||
|
||||
envToken := os.Getenv(vaultapi.EnvVaultToken)
|
||||
envToken := os.Getenv(VaultCAEnvToken)
|
||||
if config.Token == "" && envToken == "" && config.AuthMethod == nil {
|
||||
return nil, fmt.Errorf("must provide a Vault token or configure a Vault auth method")
|
||||
}
|
||||
|
||||
if config.Token != "" && envToken != "" {
|
||||
return nil, fmt.Errorf("only one Vault token can be provided")
|
||||
if envToken != "" {
|
||||
config.Token = envToken
|
||||
}
|
||||
|
||||
if config.Token != "" && config.AuthMethod != nil {
|
||||
return nil, fmt.Errorf("only one of Vault token or Vault auth method can be provided, but not both")
|
||||
}
|
||||
|
||||
if envToken != "" {
|
||||
config.Token = envToken
|
||||
}
|
||||
|
||||
if isPrimary && config.RootPKIPath == "" {
|
||||
return nil, fmt.Errorf("must provide a valid path to a root PKI backend")
|
||||
}
|
||||
|
|
|
@ -68,39 +68,44 @@ func TestVaultCAProvider_ParseVaultCAConfig(t *testing.T) {
|
|||
rawConfig: map[string]interface{}{},
|
||||
expError: "must provide a Vault address",
|
||||
},
|
||||
"no token and no auth method provided": {
|
||||
rawConfig: map[string]interface{}{"Address": "http://127.0.0.1:8200"},
|
||||
"no token or auth method provided": {
|
||||
rawConfig: map[string]interface{}{"Address": "http://vaultConfigAddr:8200"},
|
||||
expError: "must provide a Vault token or configure a Vault auth method",
|
||||
},
|
||||
"both token and auth method provided": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "AuthMethod": map[string]interface{}{"Type": "test"}, "Address": "http://127.0.0.1:8200"},
|
||||
rawConfig: map[string]interface{}{"Token": "test", "AuthMethod": map[string]interface{}{"Type": "test"}, "Address": "http://vaultConfigAddr:8200"},
|
||||
expError: "only one of Vault token or Vault auth method can be provided, but not both",
|
||||
},
|
||||
"both env token and auth method provided": {
|
||||
rawConfig: map[string]interface{}{"AuthMethod": map[string]interface{}{"Type": "test"}, "Address": "http://vaultConfigAddr:8200"},
|
||||
envConfig: map[string]string{"CONSUL_MESH_CA_VAULT_TOKEN": "test"},
|
||||
expError: "only one of Vault token or Vault auth method can be provided, but not both",
|
||||
},
|
||||
"primary no root PKI path": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "IntermediatePKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
rawConfig: map[string]interface{}{"Token": "test", "IntermediatePKIPath": "test", "Address": "http://vaultConfigAddr:8200"},
|
||||
isPrimary: true,
|
||||
expError: "must provide a valid path to a root PKI backend",
|
||||
},
|
||||
"secondary no root PKI path": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "IntermediatePKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
rawConfig: map[string]interface{}{"Token": "test", "IntermediatePKIPath": "test", "Address": "http://vaultConfigAddr:8200"},
|
||||
isPrimary: false,
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://127.0.0.1:8200",
|
||||
Address: "http://vaultConfigAddr:8200",
|
||||
Token: "test",
|
||||
IntermediatePKIPath: "test/",
|
||||
},
|
||||
},
|
||||
"no root intermediate path": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "Address": "http://vaultconfigAddr:8200"},
|
||||
expError: "must provide a valid path for the intermediate PKI backend",
|
||||
},
|
||||
"adds a slash to RootPKIPath and IntermediatePKIPath": {
|
||||
isPrimary: true,
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://vaultConfigAddr:8200"},
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://127.0.0.1:8200",
|
||||
Address: "http://vaultConfigAddr:8200",
|
||||
Token: "test",
|
||||
RootPKIPath: "test/",
|
||||
IntermediatePKIPath: "test/",
|
||||
|
@ -108,42 +113,54 @@ func TestVaultCAProvider_ParseVaultCAConfig(t *testing.T) {
|
|||
},
|
||||
"vault address provided from env": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test"},
|
||||
envConfig: map[string]string{"VAULT_ADDR": "http://127.0.0.1:8200"},
|
||||
envConfig: map[string]string{"CONSUL_MESH_CA_VAULT_ADDR": "http://vaultEnvAddr:8200"},
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://127.0.0.1:8200",
|
||||
Address: "http://vaultEnvAddr:8200",
|
||||
Token: "test",
|
||||
RootPKIPath: "test/",
|
||||
IntermediatePKIPath: "test/",
|
||||
},
|
||||
},
|
||||
"vault address provided from env and config": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
envConfig: map[string]string{"VAULT_ADDR": "http://127.0.0.1:8200"},
|
||||
expError: "only one Vault address can be provided",
|
||||
"vault address precedence when provided from env and config": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://vaultConfigAddr:8200"},
|
||||
envConfig: map[string]string{"CONSUL_MESH_CA_VAULT_ADDR": "http://vaultEnvAddr:8200"},
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://vaultEnvAddr:8200",
|
||||
Token: "test",
|
||||
RootPKIPath: "test/",
|
||||
IntermediatePKIPath: "test/",
|
||||
},
|
||||
},
|
||||
"vault token provided from env": {
|
||||
rawConfig: map[string]interface{}{"RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
envConfig: map[string]string{"VAULT_TOKEN": "test"},
|
||||
rawConfig: map[string]interface{}{"RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://vaultConfigAddr:8200"},
|
||||
envConfig: map[string]string{"CONSUL_MESH_CA_VAULT_TOKEN": "test"},
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://127.0.0.1:8200",
|
||||
Address: "http://vaultConfigAddr:8200",
|
||||
Token: "test",
|
||||
RootPKIPath: "test/",
|
||||
IntermediatePKIPath: "test/",
|
||||
},
|
||||
},
|
||||
"vault token provided from env and config": {
|
||||
rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://127.0.0.1:8200"},
|
||||
envConfig: map[string]string{"VAULT_TOKEN": "test"},
|
||||
expError: "only one Vault token can be provided",
|
||||
"vault token precedence when provided from env and config": {
|
||||
rawConfig: map[string]interface{}{"Token": "tokenFromConfig", "RootPKIPath": "test", "IntermediatePKIPath": "test", "Address": "http://vaultConfigAddr:8200"},
|
||||
envConfig: map[string]string{"CONSUL_MESH_CA_VAULT_TOKEN": "tokenFromEnv"},
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://vaultConfigAddr:8200",
|
||||
Token: "tokenFromEnv",
|
||||
RootPKIPath: "test/",
|
||||
IntermediatePKIPath: "test/",
|
||||
},
|
||||
},
|
||||
"vault token and addr provided from env": {
|
||||
rawConfig: map[string]interface{}{"RootPKIPath": "test", "IntermediatePKIPath": "test"},
|
||||
envConfig: map[string]string{"VAULT_ADDR": "http://127.0.0.1:8200", "VAULT_TOKEN": "test"},
|
||||
envConfig: map[string]string{"CONSUL_MESH_CA_VAULT_ADDR": "http://vaultEnvAddr:8200", "CONSUL_MESH_CA_VAULT_TOKEN": "test"},
|
||||
expConfig: &structs.VaultCAProviderConfig{
|
||||
CommonCAProviderConfig: defaultCommonConfig(),
|
||||
Address: "http://127.0.0.1:8200",
|
||||
Address: "http://vaultEnvAddr:8200",
|
||||
Token: "test",
|
||||
RootPKIPath: "test/",
|
||||
IntermediatePKIPath: "test/",
|
||||
|
@ -328,13 +345,13 @@ func TestVaultCAProvider_ConfigureFromEnv(t *testing.T) {
|
|||
"DefaultConfigWithEnvTokenMissing": {
|
||||
envOnlyToken: true,
|
||||
envOnlyAddr: false,
|
||||
envConfigOverride: map[string]string{"VAULT_TOKEN": ""},
|
||||
envConfigOverride: map[string]string{"CONSUL_MESH_CA_VAULT_TOKEN": ""},
|
||||
expError: "must provide a Vault token or configure a Vault auth method",
|
||||
},
|
||||
"DefaultConfigWithEnvAddrMissing": {
|
||||
envOnlyToken: true,
|
||||
envOnlyAddr: true,
|
||||
envConfigOverride: map[string]string{"VAULT_ADDR": ""},
|
||||
envConfigOverride: map[string]string{"CONSUL_MESH_CA_VAULT_ADDR": ""},
|
||||
expError: "must provide a Vault address",
|
||||
},
|
||||
}
|
||||
|
@ -345,12 +362,12 @@ func TestVaultCAProvider_ConfigureFromEnv(t *testing.T) {
|
|||
token := CreateVaultTokenWithAttrs(t, testVault.client, attr)
|
||||
|
||||
if c.envOnlyToken {
|
||||
t.Setenv(vaultapi.EnvVaultToken, token)
|
||||
t.Setenv(VaultCAEnvToken, token)
|
||||
token = ""
|
||||
}
|
||||
|
||||
if c.envOnlyAddr {
|
||||
t.Setenv(vaultapi.EnvVaultAddress, testVault.Addr)
|
||||
t.Setenv(VaultCAEnvAddr, testVault.Addr)
|
||||
testVault.Addr = ""
|
||||
}
|
||||
|
||||
|
|
|
@ -86,14 +86,14 @@ The first key refers to the option name for use in API calls.
|
|||
The key after the slash refers to the corresponding option name in the agent configuration file.
|
||||
|
||||
- `Address` / `address` (`string: <required>`) - The address of the Vault
|
||||
server. You can also provide the address through the `VAULT_ADDR` environment variable. The address must be provided either through the configuration file or through the environment variable, but you cannot provide the address using both methods at the same time.
|
||||
server. You can also provide the address through the `CONSUL_MESH_CA_VAULT_ADDR` environment variable. If the address is provided through the environment variable it takes precedence over the value set in the configuration file.
|
||||
|
||||
- `Token` / `token` (`string: ""`) - A token for accessing Vault.
|
||||
This is write-only and will not be exposed when reading the CA configuration.
|
||||
This token must have [proper privileges](#vault-acl-policies) for the PKI
|
||||
paths configured. In Consul 1.8.5 and later, if the token has the [renewable](/vault/api-docs/auth/token#renewable)
|
||||
flag set, Consul will attempt to renew its lease periodically after half the
|
||||
duration has expired. You can also provide the token through the `VAULT_TOKEN` environment variable. The token must be provided either through the configuration file or through the environment variable, but you cannot provide the token using both methods at the same time.
|
||||
duration has expired. You can also provide the token through the `CONSUL_MESH_CA_VAULT_TOKEN` environment variable. If the token is provided through the environment variable it takes precedence over the value set in the configuration file.
|
||||
|
||||
!> **Warning:** You must either provide a token or configure an auth method below.
|
||||
|
||||
|
|
Loading…
Reference in New Issue