github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/nomad/structs/config/consul.go (about) 1 package config 2 3 import ( 4 "net/http" 5 "strings" 6 "time" 7 8 consul "github.com/hashicorp/consul/api" 9 "github.com/hashicorp/nomad/helper" 10 ) 11 12 // ConsulConfig contains the configuration information necessary to 13 // communicate with a Consul Agent in order to: 14 // 15 // - Register services and their checks with Consul 16 // 17 // - Bootstrap this Nomad Client with the list of Nomad Servers registered 18 // with Consul 19 // 20 // - Establish how this Nomad Client will resolve Envoy Connect Sidecar 21 // images. 22 // 23 // Both the Agent and the executor need to be able to import ConsulConfig. 24 type ConsulConfig struct { 25 // ServerServiceName is the name of the service that Nomad uses to register 26 // servers with Consul 27 ServerServiceName string `hcl:"server_service_name"` 28 29 // ServerHTTPCheckName is the name of the health check that Nomad uses 30 // to register the server HTTP health check with Consul 31 ServerHTTPCheckName string `hcl:"server_http_check_name"` 32 33 // ServerSerfCheckName is the name of the health check that Nomad uses 34 // to register the server Serf health check with Consul 35 ServerSerfCheckName string `hcl:"server_serf_check_name"` 36 37 // ServerRPCCheckName is the name of the health check that Nomad uses 38 // to register the server RPC health check with Consul 39 ServerRPCCheckName string `hcl:"server_rpc_check_name"` 40 41 // ClientServiceName is the name of the service that Nomad uses to register 42 // clients with Consul 43 ClientServiceName string `hcl:"client_service_name"` 44 45 // ClientHTTPCheckName is the name of the health check that Nomad uses 46 // to register the client HTTP health check with Consul 47 ClientHTTPCheckName string `hcl:"client_http_check_name"` 48 49 // Tags are optional service tags that get registered with the service 50 // in Consul 51 Tags []string `hcl:"tags"` 52 53 // AutoAdvertise determines if this Nomad Agent will advertise its 54 // services via Consul. When true, Nomad Agent will register 55 // services with Consul. 56 AutoAdvertise *bool `hcl:"auto_advertise"` 57 58 // ChecksUseAdvertise specifies that Consul checks should use advertise 59 // address instead of bind address 60 ChecksUseAdvertise *bool `hcl:"checks_use_advertise"` 61 62 // Addr is the HTTP endpoint address of the local Consul agent 63 // 64 // Uses Consul's default and env var. 65 Addr string `hcl:"address"` 66 67 // GRPCAddr is the gRPC endpoint address of the local Consul agent 68 GRPCAddr string `hcl:"grpc_address"` 69 70 // Timeout is used by Consul HTTP Client 71 Timeout time.Duration `hcl:"-"` 72 TimeoutHCL string `hcl:"timeout" json:"-"` 73 74 // Token is used to provide a per-request ACL token. This options overrides 75 // the agent's default token 76 Token string `hcl:"token"` 77 78 // AllowUnauthenticated allows users to submit jobs requiring Consul 79 // Service Identity tokens without providing a Consul token proving they 80 // have access to such policies. 81 AllowUnauthenticated *bool `hcl:"allow_unauthenticated"` 82 83 // Auth is the information to use for http access to Consul agent 84 Auth string `hcl:"auth"` 85 86 // EnableSSL sets the transport scheme to talk to the Consul agent as https 87 // 88 // Uses Consul's default and env var. 89 EnableSSL *bool `hcl:"ssl"` 90 91 // ShareSSL enables Consul Connect Native applications to use the TLS 92 // configuration of the Nomad Client for establishing connections to Consul. 93 // 94 // Does not include sharing of ACL tokens. 95 ShareSSL *bool `hcl:"share_ssl"` 96 97 // VerifySSL enables or disables SSL verification when the transport scheme 98 // for the consul api client is https 99 // 100 // Uses Consul's default and env var. 101 VerifySSL *bool `hcl:"verify_ssl"` 102 103 // CAFile is the path to the ca certificate used for Consul communication. 104 // 105 // Uses Consul's default and env var. 106 CAFile string `hcl:"ca_file"` 107 108 // CertFile is the path to the certificate for Consul communication 109 CertFile string `hcl:"cert_file"` 110 111 // KeyFile is the path to the private key for Consul communication 112 KeyFile string `hcl:"key_file"` 113 114 // ServerAutoJoin enables Nomad servers to find peers by querying Consul and 115 // joining them 116 ServerAutoJoin *bool `hcl:"server_auto_join"` 117 118 // ClientAutoJoin enables Nomad servers to find addresses of Nomad servers 119 // and register with them 120 ClientAutoJoin *bool `hcl:"client_auto_join"` 121 122 // ExtraKeysHCL is used by hcl to surface unexpected keys 123 ExtraKeysHCL []string `hcl:",unusedKeys" json:"-"` 124 125 // Namespace sets the Consul namespace used for all calls against the 126 // Consul API. If this is unset, then Nomad does not specify a consul namespace. 127 Namespace string `hcl:"namespace"` 128 } 129 130 // DefaultConsulConfig() returns the canonical defaults for the Nomad 131 // `consul` configuration. Uses Consul's default configuration which reads 132 // environment variables. 133 func DefaultConsulConfig() *ConsulConfig { 134 def := consul.DefaultConfig() 135 return &ConsulConfig{ 136 ServerServiceName: "nomad", 137 ServerHTTPCheckName: "Nomad Server HTTP Check", 138 ServerSerfCheckName: "Nomad Server Serf Check", 139 ServerRPCCheckName: "Nomad Server RPC Check", 140 ClientServiceName: "nomad-client", 141 ClientHTTPCheckName: "Nomad Client HTTP Check", 142 AutoAdvertise: helper.BoolToPtr(true), 143 ChecksUseAdvertise: helper.BoolToPtr(false), 144 ServerAutoJoin: helper.BoolToPtr(true), 145 ClientAutoJoin: helper.BoolToPtr(true), 146 AllowUnauthenticated: helper.BoolToPtr(true), 147 Timeout: 5 * time.Second, 148 149 // From Consul api package defaults 150 Addr: def.Address, 151 EnableSSL: helper.BoolToPtr(def.Scheme == "https"), 152 VerifySSL: helper.BoolToPtr(!def.TLSConfig.InsecureSkipVerify), 153 CAFile: def.TLSConfig.CAFile, 154 Namespace: def.Namespace, 155 } 156 } 157 158 // AllowsUnauthenticated returns whether the config allows unauthenticated 159 // creation of Consul Service Identity tokens for Consul Connect enabled Tasks. 160 // 161 // If allow_unauthenticated is false, the operator must provide a token on 162 // job submission (i.e. -consul-token or $CONSUL_HTTP_TOKEN). 163 func (c *ConsulConfig) AllowsUnauthenticated() bool { 164 return c.AllowUnauthenticated != nil && *c.AllowUnauthenticated 165 } 166 167 // Merge merges two Consul Configurations together. 168 func (c *ConsulConfig) Merge(b *ConsulConfig) *ConsulConfig { 169 result := c.Copy() 170 171 if b.ServerServiceName != "" { 172 result.ServerServiceName = b.ServerServiceName 173 } 174 if b.ServerHTTPCheckName != "" { 175 result.ServerHTTPCheckName = b.ServerHTTPCheckName 176 } 177 if b.ServerSerfCheckName != "" { 178 result.ServerSerfCheckName = b.ServerSerfCheckName 179 } 180 if b.ServerRPCCheckName != "" { 181 result.ServerRPCCheckName = b.ServerRPCCheckName 182 } 183 if b.ClientServiceName != "" { 184 result.ClientServiceName = b.ClientServiceName 185 } 186 if b.ClientHTTPCheckName != "" { 187 result.ClientHTTPCheckName = b.ClientHTTPCheckName 188 } 189 result.Tags = append(result.Tags, b.Tags...) 190 if b.AutoAdvertise != nil { 191 result.AutoAdvertise = helper.BoolToPtr(*b.AutoAdvertise) 192 } 193 if b.Addr != "" { 194 result.Addr = b.Addr 195 } 196 if b.GRPCAddr != "" { 197 result.GRPCAddr = b.GRPCAddr 198 } 199 if b.Timeout != 0 { 200 result.Timeout = b.Timeout 201 } 202 if b.TimeoutHCL != "" { 203 result.TimeoutHCL = b.TimeoutHCL 204 } 205 if b.Token != "" { 206 result.Token = b.Token 207 } 208 if b.Auth != "" { 209 result.Auth = b.Auth 210 } 211 if b.EnableSSL != nil { 212 result.EnableSSL = helper.BoolToPtr(*b.EnableSSL) 213 } 214 if b.VerifySSL != nil { 215 result.VerifySSL = helper.BoolToPtr(*b.VerifySSL) 216 } 217 if b.ShareSSL != nil { 218 result.ShareSSL = helper.BoolToPtr(*b.ShareSSL) 219 } 220 if b.CAFile != "" { 221 result.CAFile = b.CAFile 222 } 223 if b.CertFile != "" { 224 result.CertFile = b.CertFile 225 } 226 if b.KeyFile != "" { 227 result.KeyFile = b.KeyFile 228 } 229 if b.ServerAutoJoin != nil { 230 result.ServerAutoJoin = helper.BoolToPtr(*b.ServerAutoJoin) 231 } 232 if b.ClientAutoJoin != nil { 233 result.ClientAutoJoin = helper.BoolToPtr(*b.ClientAutoJoin) 234 } 235 if b.ChecksUseAdvertise != nil { 236 result.ChecksUseAdvertise = helper.BoolToPtr(*b.ChecksUseAdvertise) 237 } 238 if b.AllowUnauthenticated != nil { 239 result.AllowUnauthenticated = helper.BoolToPtr(*b.AllowUnauthenticated) 240 } 241 if b.Namespace != "" { 242 result.Namespace = b.Namespace 243 } 244 return result 245 } 246 247 // ApiConfig returns a usable Consul config that can be passed directly to 248 // hashicorp/consul/api. NOTE: datacenter is not set 249 func (c *ConsulConfig) ApiConfig() (*consul.Config, error) { 250 // Get the default config from consul to reuse things like the default 251 // http.Transport. 252 config := consul.DefaultConfig() 253 if c.Addr != "" { 254 config.Address = c.Addr 255 } 256 if c.Token != "" { 257 config.Token = c.Token 258 } 259 if c.Timeout != 0 { 260 // Create a custom Client to set the timeout 261 if config.HttpClient == nil { 262 config.HttpClient = &http.Client{} 263 } 264 config.HttpClient.Timeout = c.Timeout 265 config.HttpClient.Transport = config.Transport 266 } 267 if c.Auth != "" { 268 var username, password string 269 if strings.Contains(c.Auth, ":") { 270 split := strings.SplitN(c.Auth, ":", 2) 271 username = split[0] 272 password = split[1] 273 } else { 274 username = c.Auth 275 } 276 277 config.HttpAuth = &consul.HttpBasicAuth{ 278 Username: username, 279 Password: password, 280 } 281 } 282 if c.EnableSSL != nil && *c.EnableSSL { 283 config.Scheme = "https" 284 config.TLSConfig = consul.TLSConfig{ 285 Address: config.Address, 286 CAFile: c.CAFile, 287 CertFile: c.CertFile, 288 KeyFile: c.KeyFile, 289 } 290 if c.VerifySSL != nil { 291 config.TLSConfig.InsecureSkipVerify = !*c.VerifySSL 292 } 293 tlsConfig, err := consul.SetupTLSConfig(&config.TLSConfig) 294 if err != nil { 295 return nil, err 296 } 297 config.Transport.TLSClientConfig = tlsConfig 298 } 299 if c.Namespace != "" { 300 config.Namespace = c.Namespace 301 } 302 return config, nil 303 } 304 305 // Copy returns a copy of this Consul config. 306 func (c *ConsulConfig) Copy() *ConsulConfig { 307 if c == nil { 308 return nil 309 } 310 311 nc := new(ConsulConfig) 312 *nc = *c 313 314 // Copy the bools 315 if nc.AutoAdvertise != nil { 316 nc.AutoAdvertise = helper.BoolToPtr(*nc.AutoAdvertise) 317 } 318 if nc.ChecksUseAdvertise != nil { 319 nc.ChecksUseAdvertise = helper.BoolToPtr(*nc.ChecksUseAdvertise) 320 } 321 if nc.EnableSSL != nil { 322 nc.EnableSSL = helper.BoolToPtr(*nc.EnableSSL) 323 } 324 if nc.VerifySSL != nil { 325 nc.VerifySSL = helper.BoolToPtr(*nc.VerifySSL) 326 } 327 if nc.ShareSSL != nil { 328 nc.ShareSSL = helper.BoolToPtr(*nc.ShareSSL) 329 } 330 if nc.ServerAutoJoin != nil { 331 nc.ServerAutoJoin = helper.BoolToPtr(*nc.ServerAutoJoin) 332 } 333 if nc.ClientAutoJoin != nil { 334 nc.ClientAutoJoin = helper.BoolToPtr(*nc.ClientAutoJoin) 335 } 336 if nc.AllowUnauthenticated != nil { 337 nc.AllowUnauthenticated = helper.BoolToPtr(*nc.AllowUnauthenticated) 338 } 339 340 return nc 341 }