github.com/bigcommerce/nomad@v0.9.3-bc/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  // Both the Agent and the executor need to be able to import ConsulConfig.
    21  type ConsulConfig struct {
    22  	// ServerServiceName is the name of the service that Nomad uses to register
    23  	// servers with Consul
    24  	ServerServiceName string `hcl:"server_service_name"`
    25  
    26  	// ServerHTTPCheckName is the name of the health check that Nomad uses
    27  	// to register the server HTTP health check with Consul
    28  	ServerHTTPCheckName string `hcl:"server_http_check_name"`
    29  
    30  	// ServerSerfCheckName is the name of the health check that Nomad uses
    31  	// to register the server Serf health check with Consul
    32  	ServerSerfCheckName string `hcl:"server_serf_check_name"`
    33  
    34  	// ServerRPCCheckName is the name of the health check that Nomad uses
    35  	// to register the server RPC health check with Consul
    36  	ServerRPCCheckName string `hcl:"server_rpc_check_name"`
    37  
    38  	// ClientServiceName is the name of the service that Nomad uses to register
    39  	// clients with Consul
    40  	ClientServiceName string `hcl:"client_service_name"`
    41  
    42  	// ClientHTTPCheckName is the name of the health check that Nomad uses
    43  	// to register the client HTTP health check with Consul
    44  	ClientHTTPCheckName string `hcl:"client_http_check_name"`
    45  
    46  	// AutoAdvertise determines if this Nomad Agent will advertise its
    47  	// services via Consul.  When true, Nomad Agent will register
    48  	// services with Consul.
    49  	AutoAdvertise *bool `hcl:"auto_advertise"`
    50  
    51  	// ChecksUseAdvertise specifies that Consul checks should use advertise
    52  	// address instead of bind address
    53  	ChecksUseAdvertise *bool `hcl:"checks_use_advertise"`
    54  
    55  	// Addr is the address of the local Consul agent
    56  	Addr string `hcl:"address"`
    57  
    58  	// Timeout is used by Consul HTTP Client
    59  	Timeout    time.Duration
    60  	TimeoutHCL string `hcl:"timeout" json:"-"`
    61  
    62  	// Token is used to provide a per-request ACL token. This options overrides
    63  	// the agent's default token
    64  	Token string `hcl:"token"`
    65  
    66  	// Auth is the information to use for http access to Consul agent
    67  	Auth string `hcl:"auth"`
    68  
    69  	// EnableSSL sets the transport scheme to talk to the Consul agent as https
    70  	EnableSSL *bool `hcl:"ssl"`
    71  
    72  	// VerifySSL enables or disables SSL verification when the transport scheme
    73  	// for the consul api client is https
    74  	VerifySSL *bool `hcl:"verify_ssl"`
    75  
    76  	// CAFile is the path to the ca certificate used for Consul communication
    77  	CAFile string `hcl:"ca_file"`
    78  
    79  	// CertFile is the path to the certificate for Consul communication
    80  	CertFile string `hcl:"cert_file"`
    81  
    82  	// KeyFile is the path to the private key for Consul communication
    83  	KeyFile string `hcl:"key_file"`
    84  
    85  	// ServerAutoJoin enables Nomad servers to find peers by querying Consul and
    86  	// joining them
    87  	ServerAutoJoin *bool `hcl:"server_auto_join"`
    88  
    89  	// ClientAutoJoin enables Nomad servers to find addresses of Nomad servers
    90  	// and register with them
    91  	ClientAutoJoin *bool `hcl:"client_auto_join"`
    92  
    93  	// ExtraKeysHCL is used by hcl to surface unexpected keys
    94  	ExtraKeysHCL []string `hcl:",unusedKeys" json:"-"`
    95  }
    96  
    97  // DefaultConsulConfig() returns the canonical defaults for the Nomad
    98  // `consul` configuration.
    99  func DefaultConsulConfig() *ConsulConfig {
   100  	return &ConsulConfig{
   101  		ServerServiceName:   "nomad",
   102  		ServerHTTPCheckName: "Nomad Server HTTP Check",
   103  		ServerSerfCheckName: "Nomad Server Serf Check",
   104  		ServerRPCCheckName:  "Nomad Server RPC Check",
   105  		ClientServiceName:   "nomad-client",
   106  		ClientHTTPCheckName: "Nomad Client HTTP Check",
   107  		AutoAdvertise:       helper.BoolToPtr(true),
   108  		ChecksUseAdvertise:  helper.BoolToPtr(false),
   109  		EnableSSL:           helper.BoolToPtr(false),
   110  		VerifySSL:           helper.BoolToPtr(true),
   111  		ServerAutoJoin:      helper.BoolToPtr(true),
   112  		ClientAutoJoin:      helper.BoolToPtr(true),
   113  		Timeout:             5 * time.Second,
   114  	}
   115  }
   116  
   117  // Merge merges two Consul Configurations together.
   118  func (a *ConsulConfig) Merge(b *ConsulConfig) *ConsulConfig {
   119  	result := a.Copy()
   120  
   121  	if b.ServerServiceName != "" {
   122  		result.ServerServiceName = b.ServerServiceName
   123  	}
   124  	if b.ServerHTTPCheckName != "" {
   125  		result.ServerHTTPCheckName = b.ServerHTTPCheckName
   126  	}
   127  	if b.ServerSerfCheckName != "" {
   128  		result.ServerSerfCheckName = b.ServerSerfCheckName
   129  	}
   130  	if b.ServerRPCCheckName != "" {
   131  		result.ServerRPCCheckName = b.ServerRPCCheckName
   132  	}
   133  	if b.ClientServiceName != "" {
   134  		result.ClientServiceName = b.ClientServiceName
   135  	}
   136  	if b.ClientHTTPCheckName != "" {
   137  		result.ClientHTTPCheckName = b.ClientHTTPCheckName
   138  	}
   139  	if b.AutoAdvertise != nil {
   140  		result.AutoAdvertise = helper.BoolToPtr(*b.AutoAdvertise)
   141  	}
   142  	if b.Addr != "" {
   143  		result.Addr = b.Addr
   144  	}
   145  	if b.Timeout != 0 {
   146  		result.Timeout = b.Timeout
   147  	}
   148  	if b.TimeoutHCL != "" {
   149  		result.TimeoutHCL = b.TimeoutHCL
   150  	}
   151  	if b.Token != "" {
   152  		result.Token = b.Token
   153  	}
   154  	if b.Auth != "" {
   155  		result.Auth = b.Auth
   156  	}
   157  	if b.EnableSSL != nil {
   158  		result.EnableSSL = helper.BoolToPtr(*b.EnableSSL)
   159  	}
   160  	if b.VerifySSL != nil {
   161  		result.VerifySSL = helper.BoolToPtr(*b.VerifySSL)
   162  	}
   163  	if b.CAFile != "" {
   164  		result.CAFile = b.CAFile
   165  	}
   166  	if b.CertFile != "" {
   167  		result.CertFile = b.CertFile
   168  	}
   169  	if b.KeyFile != "" {
   170  		result.KeyFile = b.KeyFile
   171  	}
   172  	if b.ServerAutoJoin != nil {
   173  		result.ServerAutoJoin = helper.BoolToPtr(*b.ServerAutoJoin)
   174  	}
   175  	if b.ClientAutoJoin != nil {
   176  		result.ClientAutoJoin = helper.BoolToPtr(*b.ClientAutoJoin)
   177  	}
   178  	if b.ChecksUseAdvertise != nil {
   179  		result.ChecksUseAdvertise = helper.BoolToPtr(*b.ChecksUseAdvertise)
   180  	}
   181  	return result
   182  }
   183  
   184  // ApiConfig returns a usable Consul config that can be passed directly to
   185  // hashicorp/consul/api.  NOTE: datacenter is not set
   186  func (c *ConsulConfig) ApiConfig() (*consul.Config, error) {
   187  	// Get the default config from consul to reuse things like the default
   188  	// http.Transport.
   189  	config := consul.DefaultConfig()
   190  	if c.Addr != "" {
   191  		config.Address = c.Addr
   192  	}
   193  	if c.Token != "" {
   194  		config.Token = c.Token
   195  	}
   196  	if c.Timeout != 0 {
   197  		// Create a custom Client to set the timeout
   198  		if config.HttpClient == nil {
   199  			config.HttpClient = &http.Client{}
   200  		}
   201  		config.HttpClient.Timeout = c.Timeout
   202  		config.HttpClient.Transport = config.Transport
   203  	}
   204  	if c.Auth != "" {
   205  		var username, password string
   206  		if strings.Contains(c.Auth, ":") {
   207  			split := strings.SplitN(c.Auth, ":", 2)
   208  			username = split[0]
   209  			password = split[1]
   210  		} else {
   211  			username = c.Auth
   212  		}
   213  
   214  		config.HttpAuth = &consul.HttpBasicAuth{
   215  			Username: username,
   216  			Password: password,
   217  		}
   218  	}
   219  	if c.EnableSSL != nil && *c.EnableSSL {
   220  		config.Scheme = "https"
   221  		config.TLSConfig = consul.TLSConfig{
   222  			Address:  config.Address,
   223  			CAFile:   c.CAFile,
   224  			CertFile: c.CertFile,
   225  			KeyFile:  c.KeyFile,
   226  		}
   227  		if c.VerifySSL != nil {
   228  			config.TLSConfig.InsecureSkipVerify = !*c.VerifySSL
   229  		}
   230  		tlsConfig, err := consul.SetupTLSConfig(&config.TLSConfig)
   231  		if err != nil {
   232  			return nil, err
   233  		}
   234  		config.Transport.TLSClientConfig = tlsConfig
   235  	}
   236  
   237  	return config, nil
   238  }
   239  
   240  // Copy returns a copy of this Consul config.
   241  func (c *ConsulConfig) Copy() *ConsulConfig {
   242  	if c == nil {
   243  		return nil
   244  	}
   245  
   246  	nc := new(ConsulConfig)
   247  	*nc = *c
   248  
   249  	// Copy the bools
   250  	if nc.AutoAdvertise != nil {
   251  		nc.AutoAdvertise = helper.BoolToPtr(*nc.AutoAdvertise)
   252  	}
   253  	if nc.ChecksUseAdvertise != nil {
   254  		nc.ChecksUseAdvertise = helper.BoolToPtr(*nc.ChecksUseAdvertise)
   255  	}
   256  	if nc.EnableSSL != nil {
   257  		nc.EnableSSL = helper.BoolToPtr(*nc.EnableSSL)
   258  	}
   259  	if nc.VerifySSL != nil {
   260  		nc.VerifySSL = helper.BoolToPtr(*nc.VerifySSL)
   261  	}
   262  	if nc.ServerAutoJoin != nil {
   263  		nc.ServerAutoJoin = helper.BoolToPtr(*nc.ServerAutoJoin)
   264  	}
   265  	if nc.ClientAutoJoin != nil {
   266  		nc.ClientAutoJoin = helper.BoolToPtr(*nc.ClientAutoJoin)
   267  	}
   268  
   269  	return nc
   270  }