github.com/uchennaokeke444/nomad@v0.11.8/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  	// AllowUnauthenticated allows users to submit jobs requiring Consul
    76  	// Service Identity tokens without providing a Consul token proving they
    77  	// have access to such policies.
    78  	AllowUnauthenticated *bool `hcl:"allow_unauthenticated"`
    79  
    80  	// Auth is the information to use for http access to Consul agent
    81  	Auth string `hcl:"auth"`
    82  
    83  	// EnableSSL sets the transport scheme to talk to the Consul agent as https
    84  	//
    85  	// Uses Consul's default and env var.
    86  	EnableSSL *bool `hcl:"ssl"`
    87  
    88  	// VerifySSL enables or disables SSL verification when the transport scheme
    89  	// for the consul api client is https
    90  	//
    91  	// Uses Consul's default and env var.
    92  	VerifySSL *bool `hcl:"verify_ssl"`
    93  
    94  	// CAFile is the path to the ca certificate used for Consul communication.
    95  	//
    96  	// Uses Consul's default and env var.
    97  	CAFile string `hcl:"ca_file"`
    98  
    99  	// CertFile is the path to the certificate for Consul communication
   100  	CertFile string `hcl:"cert_file"`
   101  
   102  	// KeyFile is the path to the private key for Consul communication
   103  	KeyFile string `hcl:"key_file"`
   104  
   105  	// ServerAutoJoin enables Nomad servers to find peers by querying Consul and
   106  	// joining them
   107  	ServerAutoJoin *bool `hcl:"server_auto_join"`
   108  
   109  	// ClientAutoJoin enables Nomad servers to find addresses of Nomad servers
   110  	// and register with them
   111  	ClientAutoJoin *bool `hcl:"client_auto_join"`
   112  
   113  	// ExtraKeysHCL is used by hcl to surface unexpected keys
   114  	ExtraKeysHCL []string `hcl:",unusedKeys" json:"-"`
   115  }
   116  
   117  // DefaultConsulConfig() returns the canonical defaults for the Nomad
   118  // `consul` configuration. Uses Consul's default configuration which reads
   119  // environment variables.
   120  func DefaultConsulConfig() *ConsulConfig {
   121  	def := consul.DefaultConfig()
   122  	return &ConsulConfig{
   123  		ServerServiceName:    "nomad",
   124  		ServerHTTPCheckName:  "Nomad Server HTTP Check",
   125  		ServerSerfCheckName:  "Nomad Server Serf Check",
   126  		ServerRPCCheckName:   "Nomad Server RPC Check",
   127  		ClientServiceName:    "nomad-client",
   128  		ClientHTTPCheckName:  "Nomad Client HTTP Check",
   129  		AutoAdvertise:        helper.BoolToPtr(true),
   130  		ChecksUseAdvertise:   helper.BoolToPtr(false),
   131  		ServerAutoJoin:       helper.BoolToPtr(true),
   132  		ClientAutoJoin:       helper.BoolToPtr(true),
   133  		AllowUnauthenticated: helper.BoolToPtr(true),
   134  		Timeout:              5 * time.Second,
   135  
   136  		// From Consul api package defaults
   137  		Addr:      def.Address,
   138  		EnableSSL: helper.BoolToPtr(def.Scheme == "https"),
   139  		VerifySSL: helper.BoolToPtr(!def.TLSConfig.InsecureSkipVerify),
   140  		CAFile:    def.TLSConfig.CAFile,
   141  	}
   142  }
   143  
   144  // AllowsUnauthenticated returns whether the config allows unauthenticated
   145  // creation of Consul Service Identity tokens for Consul Connect enabled Tasks.
   146  //
   147  // If allow_unauthenticated is false, the operator must provide a token on
   148  // job submission (i.e. -consul-token or $CONSUL_HTTP_TOKEN).
   149  func (c *ConsulConfig) AllowsUnauthenticated() bool {
   150  	return c.AllowUnauthenticated != nil && *c.AllowUnauthenticated
   151  }
   152  
   153  // Merge merges two Consul Configurations together.
   154  func (c *ConsulConfig) Merge(b *ConsulConfig) *ConsulConfig {
   155  	result := c.Copy()
   156  
   157  	if b.ServerServiceName != "" {
   158  		result.ServerServiceName = b.ServerServiceName
   159  	}
   160  	if b.ServerHTTPCheckName != "" {
   161  		result.ServerHTTPCheckName = b.ServerHTTPCheckName
   162  	}
   163  	if b.ServerSerfCheckName != "" {
   164  		result.ServerSerfCheckName = b.ServerSerfCheckName
   165  	}
   166  	if b.ServerRPCCheckName != "" {
   167  		result.ServerRPCCheckName = b.ServerRPCCheckName
   168  	}
   169  	if b.ClientServiceName != "" {
   170  		result.ClientServiceName = b.ClientServiceName
   171  	}
   172  	if b.ClientHTTPCheckName != "" {
   173  		result.ClientHTTPCheckName = b.ClientHTTPCheckName
   174  	}
   175  	result.Tags = append(result.Tags, b.Tags...)
   176  	if b.AutoAdvertise != nil {
   177  		result.AutoAdvertise = helper.BoolToPtr(*b.AutoAdvertise)
   178  	}
   179  	if b.Addr != "" {
   180  		result.Addr = b.Addr
   181  	}
   182  	if b.GRPCAddr != "" {
   183  		result.GRPCAddr = b.GRPCAddr
   184  	}
   185  	if b.Timeout != 0 {
   186  		result.Timeout = b.Timeout
   187  	}
   188  	if b.TimeoutHCL != "" {
   189  		result.TimeoutHCL = b.TimeoutHCL
   190  	}
   191  	if b.Token != "" {
   192  		result.Token = b.Token
   193  	}
   194  	if b.Auth != "" {
   195  		result.Auth = b.Auth
   196  	}
   197  	if b.EnableSSL != nil {
   198  		result.EnableSSL = helper.BoolToPtr(*b.EnableSSL)
   199  	}
   200  	if b.VerifySSL != nil {
   201  		result.VerifySSL = helper.BoolToPtr(*b.VerifySSL)
   202  	}
   203  	if b.CAFile != "" {
   204  		result.CAFile = b.CAFile
   205  	}
   206  	if b.CertFile != "" {
   207  		result.CertFile = b.CertFile
   208  	}
   209  	if b.KeyFile != "" {
   210  		result.KeyFile = b.KeyFile
   211  	}
   212  	if b.ServerAutoJoin != nil {
   213  		result.ServerAutoJoin = helper.BoolToPtr(*b.ServerAutoJoin)
   214  	}
   215  	if b.ClientAutoJoin != nil {
   216  		result.ClientAutoJoin = helper.BoolToPtr(*b.ClientAutoJoin)
   217  	}
   218  	if b.ChecksUseAdvertise != nil {
   219  		result.ChecksUseAdvertise = helper.BoolToPtr(*b.ChecksUseAdvertise)
   220  	}
   221  	if b.AllowUnauthenticated != nil {
   222  		result.AllowUnauthenticated = helper.BoolToPtr(*b.AllowUnauthenticated)
   223  	}
   224  	return result
   225  }
   226  
   227  // ApiConfig returns a usable Consul config that can be passed directly to
   228  // hashicorp/consul/api.  NOTE: datacenter is not set
   229  func (c *ConsulConfig) ApiConfig() (*consul.Config, error) {
   230  	// Get the default config from consul to reuse things like the default
   231  	// http.Transport.
   232  	config := consul.DefaultConfig()
   233  	if c.Addr != "" {
   234  		config.Address = c.Addr
   235  	}
   236  	if c.Token != "" {
   237  		config.Token = c.Token
   238  	}
   239  	if c.Timeout != 0 {
   240  		// Create a custom Client to set the timeout
   241  		if config.HttpClient == nil {
   242  			config.HttpClient = &http.Client{}
   243  		}
   244  		config.HttpClient.Timeout = c.Timeout
   245  		config.HttpClient.Transport = config.Transport
   246  	}
   247  	if c.Auth != "" {
   248  		var username, password string
   249  		if strings.Contains(c.Auth, ":") {
   250  			split := strings.SplitN(c.Auth, ":", 2)
   251  			username = split[0]
   252  			password = split[1]
   253  		} else {
   254  			username = c.Auth
   255  		}
   256  
   257  		config.HttpAuth = &consul.HttpBasicAuth{
   258  			Username: username,
   259  			Password: password,
   260  		}
   261  	}
   262  	if c.EnableSSL != nil && *c.EnableSSL {
   263  		config.Scheme = "https"
   264  		config.TLSConfig = consul.TLSConfig{
   265  			Address:  config.Address,
   266  			CAFile:   c.CAFile,
   267  			CertFile: c.CertFile,
   268  			KeyFile:  c.KeyFile,
   269  		}
   270  		if c.VerifySSL != nil {
   271  			config.TLSConfig.InsecureSkipVerify = !*c.VerifySSL
   272  		}
   273  		tlsConfig, err := consul.SetupTLSConfig(&config.TLSConfig)
   274  		if err != nil {
   275  			return nil, err
   276  		}
   277  		config.Transport.TLSClientConfig = tlsConfig
   278  	}
   279  	return config, nil
   280  }
   281  
   282  // Copy returns a copy of this Consul config.
   283  func (c *ConsulConfig) Copy() *ConsulConfig {
   284  	if c == nil {
   285  		return nil
   286  	}
   287  
   288  	nc := new(ConsulConfig)
   289  	*nc = *c
   290  
   291  	// Copy the bools
   292  	if nc.AutoAdvertise != nil {
   293  		nc.AutoAdvertise = helper.BoolToPtr(*nc.AutoAdvertise)
   294  	}
   295  	if nc.ChecksUseAdvertise != nil {
   296  		nc.ChecksUseAdvertise = helper.BoolToPtr(*nc.ChecksUseAdvertise)
   297  	}
   298  	if nc.EnableSSL != nil {
   299  		nc.EnableSSL = helper.BoolToPtr(*nc.EnableSSL)
   300  	}
   301  	if nc.VerifySSL != nil {
   302  		nc.VerifySSL = helper.BoolToPtr(*nc.VerifySSL)
   303  	}
   304  	if nc.ServerAutoJoin != nil {
   305  		nc.ServerAutoJoin = helper.BoolToPtr(*nc.ServerAutoJoin)
   306  	}
   307  	if nc.ClientAutoJoin != nil {
   308  		nc.ClientAutoJoin = helper.BoolToPtr(*nc.ClientAutoJoin)
   309  	}
   310  	if nc.AllowUnauthenticated != nil {
   311  		nc.AllowUnauthenticated = helper.BoolToPtr(*nc.AllowUnauthenticated)
   312  	}
   313  
   314  	return nc
   315  }