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  }