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