github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/structs/config/vault.go (about) 1 package config 2 3 import ( 4 "time" 5 6 "github.com/hashicorp/nomad/helper/pointer" 7 vault "github.com/hashicorp/vault/api" 8 ) 9 10 const ( 11 // DefaultVaultConnectRetryIntv is the retry interval between trying to 12 // connect to Vault 13 DefaultVaultConnectRetryIntv = 30 * time.Second 14 ) 15 16 // VaultConfig contains the configuration information necessary to 17 // communicate with Vault in order to: 18 // 19 // - Renew Vault tokens/leases. 20 // 21 // - Pass a token for the Nomad Server to derive sub-tokens. 22 // 23 // - Create child tokens with policy subsets of the Server's token. 24 type VaultConfig struct { 25 26 // Enabled enables or disables Vault support. 27 Enabled *bool `hcl:"enabled"` 28 29 // Token is the Vault token given to Nomad such that it can 30 // derive child tokens. Nomad will renew this token at half its lease 31 // lifetime. 32 Token string `hcl:"token"` 33 34 // Role sets the role in which to create tokens from. The Token given to 35 // Nomad does not have to be created from this role but must have "update" 36 // capability on "auth/token/create/<create_from_role>". If this value is 37 // unset and the token is created from a role, the value is defaulted to the 38 // role the token is from. 39 Role string `hcl:"create_from_role"` 40 41 // Namespace sets the Vault namespace used for all calls against the 42 // Vault API. If this is unset, then Nomad does not use Vault namespaces. 43 Namespace string `mapstructure:"namespace"` 44 45 // AllowUnauthenticated allows users to submit jobs requiring Vault tokens 46 // without providing a Vault token proving they have access to these 47 // policies. 48 AllowUnauthenticated *bool `hcl:"allow_unauthenticated"` 49 50 // TaskTokenTTL is the TTL of the tokens created by Nomad Servers and used 51 // by the client. There should be a minimum time value such that the client 52 // does not have to renew with Vault at a very high frequency 53 TaskTokenTTL string `hcl:"task_token_ttl"` 54 55 // Addr is the address of the local Vault agent. This should be a complete 56 // URL such as "http://vault.example.com" 57 Addr string `hcl:"address"` 58 59 // ConnectionRetryIntv is the interval to wait before re-attempting to 60 // connect to Vault. 61 ConnectionRetryIntv time.Duration 62 63 // TLSCaFile is the path to a PEM-encoded CA cert file to use to verify the 64 // Vault server SSL certificate. 65 TLSCaFile string `hcl:"ca_file"` 66 67 // TLSCaFile is the path to a directory of PEM-encoded CA cert files to 68 // verify the Vault server SSL certificate. 69 TLSCaPath string `hcl:"ca_path"` 70 71 // TLSCertFile is the path to the certificate for Vault communication 72 TLSCertFile string `hcl:"cert_file"` 73 74 // TLSKeyFile is the path to the private key for Vault communication 75 TLSKeyFile string `hcl:"key_file"` 76 77 // TLSSkipVerify enables or disables SSL verification 78 TLSSkipVerify *bool `hcl:"tls_skip_verify"` 79 80 // TLSServerName, if set, is used to set the SNI host when connecting via TLS. 81 TLSServerName string `hcl:"tls_server_name"` 82 } 83 84 // DefaultVaultConfig returns the canonical defaults for the Nomad 85 // `vault` configuration. 86 func DefaultVaultConfig() *VaultConfig { 87 return &VaultConfig{ 88 Addr: "https://vault.service.consul:8200", 89 ConnectionRetryIntv: DefaultVaultConnectRetryIntv, 90 AllowUnauthenticated: pointer.Of(true), 91 } 92 } 93 94 // IsEnabled returns whether the config enables Vault integration 95 func (c *VaultConfig) IsEnabled() bool { 96 return c.Enabled != nil && *c.Enabled 97 } 98 99 // AllowsUnauthenticated returns whether the config allows unauthenticated 100 // access to Vault 101 func (c *VaultConfig) AllowsUnauthenticated() bool { 102 return c.AllowUnauthenticated != nil && *c.AllowUnauthenticated 103 } 104 105 // Merge merges two Vault configurations together. 106 func (c *VaultConfig) Merge(b *VaultConfig) *VaultConfig { 107 result := *c 108 109 if b.Enabled != nil { 110 result.Enabled = b.Enabled 111 } 112 if b.Token != "" { 113 result.Token = b.Token 114 } 115 if b.Role != "" { 116 result.Role = b.Role 117 } 118 if b.Namespace != "" { 119 result.Namespace = b.Namespace 120 } 121 if b.AllowUnauthenticated != nil { 122 result.AllowUnauthenticated = b.AllowUnauthenticated 123 } 124 if b.TaskTokenTTL != "" { 125 result.TaskTokenTTL = b.TaskTokenTTL 126 } 127 if b.Addr != "" { 128 result.Addr = b.Addr 129 } 130 if b.ConnectionRetryIntv.Nanoseconds() != 0 { 131 result.ConnectionRetryIntv = b.ConnectionRetryIntv 132 } 133 if b.TLSCaFile != "" { 134 result.TLSCaFile = b.TLSCaFile 135 } 136 if b.TLSCaPath != "" { 137 result.TLSCaPath = b.TLSCaPath 138 } 139 if b.TLSCertFile != "" { 140 result.TLSCertFile = b.TLSCertFile 141 } 142 if b.TLSKeyFile != "" { 143 result.TLSKeyFile = b.TLSKeyFile 144 } 145 if b.TLSSkipVerify != nil { 146 result.TLSSkipVerify = b.TLSSkipVerify 147 } 148 if b.TLSServerName != "" { 149 result.TLSServerName = b.TLSServerName 150 } 151 152 return &result 153 } 154 155 // ApiConfig returns a usable Vault config that can be passed directly to 156 // hashicorp/vault/api. 157 func (c *VaultConfig) ApiConfig() (*vault.Config, error) { 158 conf := vault.DefaultConfig() 159 tlsConf := &vault.TLSConfig{ 160 CACert: c.TLSCaFile, 161 CAPath: c.TLSCaPath, 162 ClientCert: c.TLSCertFile, 163 ClientKey: c.TLSKeyFile, 164 TLSServerName: c.TLSServerName, 165 } 166 if c.TLSSkipVerify != nil { 167 tlsConf.Insecure = *c.TLSSkipVerify 168 } else { 169 tlsConf.Insecure = false 170 } 171 172 if err := conf.ConfigureTLS(tlsConf); err != nil { 173 return nil, err 174 } 175 176 conf.Address = c.Addr 177 return conf, nil 178 } 179 180 // Copy returns a copy of this Vault config. 181 func (c *VaultConfig) Copy() *VaultConfig { 182 if c == nil { 183 return nil 184 } 185 186 nc := new(VaultConfig) 187 *nc = *c 188 return nc 189 } 190 191 // Equal compares two Vault configurations and returns a boolean indicating 192 // if they are equal. 193 func (c *VaultConfig) Equal(b *VaultConfig) bool { 194 if c == nil && b != nil { 195 return false 196 } 197 if c != nil && b == nil { 198 return false 199 } 200 201 if c.Enabled == nil || b.Enabled == nil { 202 if c.Enabled != b.Enabled { 203 return false 204 } 205 } else if *c.Enabled != *b.Enabled { 206 return false 207 } 208 209 if c.Token != b.Token { 210 return false 211 } 212 if c.Role != b.Role { 213 return false 214 } 215 if c.Namespace != b.Namespace { 216 return false 217 } 218 219 if c.AllowUnauthenticated == nil || b.AllowUnauthenticated == nil { 220 if c.AllowUnauthenticated != b.AllowUnauthenticated { 221 return false 222 } 223 } else if *c.AllowUnauthenticated != *b.AllowUnauthenticated { 224 return false 225 } 226 227 if c.TaskTokenTTL != b.TaskTokenTTL { 228 return false 229 } 230 if c.Addr != b.Addr { 231 return false 232 } 233 if c.ConnectionRetryIntv.Nanoseconds() != b.ConnectionRetryIntv.Nanoseconds() { 234 return false 235 } 236 if c.TLSCaFile != b.TLSCaFile { 237 return false 238 } 239 if c.TLSCaPath != b.TLSCaPath { 240 return false 241 } 242 if c.TLSCertFile != b.TLSCertFile { 243 return false 244 } 245 if c.TLSKeyFile != b.TLSKeyFile { 246 return false 247 } 248 249 if c.TLSSkipVerify == nil || b.TLSSkipVerify == nil { 250 if c.TLSSkipVerify != b.TLSSkipVerify { 251 return false 252 } 253 } else if *c.TLSSkipVerify != *b.TLSSkipVerify { 254 return false 255 } 256 257 if c.TLSServerName != b.TLSServerName { 258 return false 259 } 260 261 return true 262 }