2016-08-02 17:32:54 +00:00
|
|
|
package config
|
|
|
|
|
2016-08-10 03:15:13 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
vault "github.com/hashicorp/vault/api"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// VaultTokenCreateTTL is the duration the wrapped token for the client is
|
|
|
|
// valid for. The units are in seconds.
|
|
|
|
VaultTokenCreateTTL = "60s"
|
|
|
|
)
|
2016-08-02 17:32:54 +00:00
|
|
|
|
|
|
|
// VaultConfig contains the configuration information necessary to
|
|
|
|
// communicate with Vault in order to:
|
|
|
|
//
|
|
|
|
// - Renew Vault tokens/leases.
|
|
|
|
//
|
|
|
|
// - Pass a token for the Nomad Server to derive sub-tokens.
|
|
|
|
//
|
|
|
|
// - Create child tokens with policy subsets of the Server's token.
|
|
|
|
type VaultConfig struct {
|
|
|
|
|
2016-08-09 21:52:20 +00:00
|
|
|
// Enabled enables or disables Vault support.
|
|
|
|
Enabled bool `mapstructure:"enabled"`
|
|
|
|
|
2016-08-13 04:59:31 +00:00
|
|
|
// Token is the Vault token given to Nomad such that it can
|
|
|
|
// derive child tokens. Nomad will renew this token at half its lease
|
|
|
|
// lifetime.
|
|
|
|
Token string `mapstructure:"token"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
|
|
|
// AllowUnauthenticated allows users to submit jobs requiring Vault tokens
|
|
|
|
// without providing a Vault token proving they have access to these
|
|
|
|
// policies.
|
|
|
|
AllowUnauthenticated bool `mapstructure:"allow_unauthenticated"`
|
|
|
|
|
2016-08-13 04:59:31 +00:00
|
|
|
// TaskTokenTTL is the TTL of the tokens created by Nomad Servers and used
|
2016-08-02 17:32:54 +00:00
|
|
|
// by the client. There should be a minimum time value such that the client
|
|
|
|
// does not have to renew with Vault at a very high frequency
|
2016-08-13 04:59:31 +00:00
|
|
|
TaskTokenTTL string `mapstructure:"task_token_ttl"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
|
|
|
// Addr is the address of the local Vault agent
|
|
|
|
Addr string `mapstructure:"address"`
|
|
|
|
|
2016-08-08 22:16:40 +00:00
|
|
|
// TLSCaFile is the path to a PEM-encoded CA cert file to use to verify the
|
2016-08-02 17:32:54 +00:00
|
|
|
// Vault server SSL certificate.
|
2016-08-08 22:16:40 +00:00
|
|
|
TLSCaFile string `mapstructure:"tls_ca_file"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
2016-08-08 22:16:40 +00:00
|
|
|
// TLSCaFile is the path to a directory of PEM-encoded CA cert files to
|
|
|
|
// verify the Vault server SSL certificate.
|
|
|
|
TLSCaPath string `mapstructure:"tls_ca_path"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
2016-08-08 22:16:40 +00:00
|
|
|
// TLSCertFile is the path to the certificate for Vault communication
|
|
|
|
TLSCertFile string `mapstructure:"tls_cert_file"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
2016-08-08 22:16:40 +00:00
|
|
|
// TLSKeyFile is the path to the private key for Vault communication
|
|
|
|
TLSKeyFile string `mapstructure:"tls_key_file"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
2016-08-08 22:16:40 +00:00
|
|
|
// TLSSkipVerify enables or disables SSL verification
|
|
|
|
TLSSkipVerify bool `mapstructure:"tls_skip_verify"`
|
2016-08-02 17:32:54 +00:00
|
|
|
|
|
|
|
// TLSServerName, if set, is used to set the SNI host when connecting via TLS.
|
|
|
|
TLSServerName string `mapstructure:"tls_server_name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultVaultConfig() returns the canonical defaults for the Nomad
|
|
|
|
// `vault` configuration.
|
|
|
|
func DefaultVaultConfig() *VaultConfig {
|
|
|
|
return &VaultConfig{
|
2016-08-09 21:52:20 +00:00
|
|
|
Enabled: true,
|
2016-08-02 17:32:54 +00:00
|
|
|
AllowUnauthenticated: false,
|
|
|
|
Addr: "vault.service.consul:8200",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge merges two Vault configurations together.
|
|
|
|
func (a *VaultConfig) Merge(b *VaultConfig) *VaultConfig {
|
|
|
|
result := *a
|
|
|
|
|
2016-08-13 04:59:31 +00:00
|
|
|
if b.Token != "" {
|
|
|
|
result.Token = b.Token
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
2016-08-13 04:59:31 +00:00
|
|
|
if b.TaskTokenTTL != "" {
|
|
|
|
result.TaskTokenTTL = b.TaskTokenTTL
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
|
|
|
if b.Addr != "" {
|
|
|
|
result.Addr = b.Addr
|
|
|
|
}
|
2016-08-08 22:16:40 +00:00
|
|
|
if b.TLSCaFile != "" {
|
|
|
|
result.TLSCaFile = b.TLSCaFile
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
2016-08-08 22:16:40 +00:00
|
|
|
if b.TLSCaPath != "" {
|
|
|
|
result.TLSCaPath = b.TLSCaPath
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
2016-08-08 22:16:40 +00:00
|
|
|
if b.TLSCertFile != "" {
|
|
|
|
result.TLSCertFile = b.TLSCertFile
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
2016-08-08 22:16:40 +00:00
|
|
|
if b.TLSKeyFile != "" {
|
|
|
|
result.TLSKeyFile = b.TLSKeyFile
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
|
|
|
if b.TLSServerName != "" {
|
|
|
|
result.TLSServerName = b.TLSServerName
|
|
|
|
}
|
2016-08-08 22:35:22 +00:00
|
|
|
|
|
|
|
result.AllowUnauthenticated = b.AllowUnauthenticated
|
|
|
|
result.TLSSkipVerify = b.TLSSkipVerify
|
2016-08-09 21:52:20 +00:00
|
|
|
result.Enabled = b.Enabled
|
2016-08-02 17:32:54 +00:00
|
|
|
return &result
|
|
|
|
}
|
|
|
|
|
|
|
|
// ApiConfig() returns a usable Vault config that can be passed directly to
|
2016-08-02 21:28:39 +00:00
|
|
|
// hashicorp/vault/api. If readEnv is true, the environment is read for
|
|
|
|
// appropriate Vault variables.
|
|
|
|
func (c *VaultConfig) ApiConfig(readEnv bool) (*vault.Config, error) {
|
|
|
|
conf := vault.DefaultConfig()
|
|
|
|
if readEnv {
|
|
|
|
if err := conf.ReadEnvironment(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tlsConf := &vault.TLSConfig{
|
2016-08-08 22:16:40 +00:00
|
|
|
CACert: c.TLSCaFile,
|
|
|
|
CAPath: c.TLSCaPath,
|
|
|
|
ClientCert: c.TLSCertFile,
|
|
|
|
ClientKey: c.TLSKeyFile,
|
2016-08-02 21:28:39 +00:00
|
|
|
TLSServerName: c.TLSServerName,
|
2016-08-08 22:35:22 +00:00
|
|
|
Insecure: c.TLSSkipVerify,
|
2016-08-02 21:28:39 +00:00
|
|
|
}
|
|
|
|
if err := conf.ConfigureTLS(tlsConf); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return conf, nil
|
2016-08-02 17:32:54 +00:00
|
|
|
}
|
2016-08-09 22:00:50 +00:00
|
|
|
|
|
|
|
// Copy returns a copy of this Vault config.
|
|
|
|
func (c *VaultConfig) Copy() *VaultConfig {
|
|
|
|
if c == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
nc := new(VaultConfig)
|
|
|
|
*nc = *c
|
|
|
|
return nc
|
|
|
|
}
|
2016-08-10 03:15:13 +00:00
|
|
|
|
|
|
|
// GetWrappingFn returns an appropriate wrapping function for Nomad
|
|
|
|
func (c *VaultConfig) GetWrappingFn() func(operation, path string) string {
|
|
|
|
createPath := fmt.Sprintf("auth/token/create/%s", c.TokenRoleName)
|
|
|
|
return func(operation, path string) string {
|
|
|
|
// Only wrap the token create operation
|
|
|
|
if operation != "POST" || path != createPath {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return VaultTokenCreateTTL
|
|
|
|
}
|
|
|
|
}
|