1package config
2
3import (
4	"crypto/tls"
5	"fmt"
6	"net"
7	"reflect"
8	"strings"
9	"time"
10
11	"github.com/hashicorp/consul/agent/structs"
12	"github.com/hashicorp/consul/api"
13	"github.com/hashicorp/consul/lib"
14	"github.com/hashicorp/consul/tlsutil"
15	"github.com/hashicorp/consul/types"
16	"golang.org/x/time/rate"
17)
18
19type RuntimeSOAConfig struct {
20	Refresh uint32 // 3600 by default
21	Retry   uint32 // 600
22	Expire  uint32 // 86400
23	Minttl  uint32 // 0,
24}
25
26// RuntimeConfig specifies the configuration the consul agent actually
27// uses. Is is derived from one or more Config structures which can come
28// from files, flags and/or environment variables.
29type RuntimeConfig struct {
30	// non-user configurable values
31	AEInterval time.Duration
32
33	CheckDeregisterIntervalMin time.Duration
34	CheckReapInterval          time.Duration
35	SegmentLimit               int
36	SegmentNameLimit           int
37	SyncCoordinateRateTarget   float64
38	SyncCoordinateIntervalMin  time.Duration
39	Revision                   string
40	Version                    string
41	VersionPrerelease          string
42
43	// consul config
44	ConsulCoordinateUpdateMaxBatches int
45	ConsulCoordinateUpdateBatchSize  int
46	ConsulCoordinateUpdatePeriod     time.Duration
47	ConsulRaftElectionTimeout        time.Duration
48	ConsulRaftHeartbeatTimeout       time.Duration
49	ConsulRaftLeaderLeaseTimeout     time.Duration
50	ConsulServerHealthInterval       time.Duration
51
52	// ACLDisabledTTL is used by agents to determine how long they will
53	// wait to check again with the servers if they discover ACLs are not
54	// enabled. (not user configurable)
55	//
56	// hcl: acl.disabled_ttl = "duration"
57	ACLDisabledTTL time.Duration
58
59	// ACLsEnabled is used to determine whether ACLs should be enabled
60	//
61	// hcl: acl.enabled = boolean
62	ACLsEnabled bool
63
64	// ACLAgentMasterToken is a special token that has full read and write
65	// privileges for this agent, and can be used to call agent endpoints
66	// when no servers are available.
67	//
68	// hcl: acl.tokens.agent_master = string
69	ACLAgentMasterToken string
70
71	// ACLAgentToken is the default token used to make requests for the agent
72	// itself, such as for registering itself with the catalog. If not
73	// configured, the 'acl_token' will be used.
74	//
75	// hcl: acl.tokens.agent = string
76	ACLAgentToken string
77
78	// ACLDatacenter is the central datacenter that holds authoritative
79	// ACL records. This must be the same for the entire cluster.
80	// If this is not set, ACLs are not enabled. Off by default.
81	//
82	// hcl: acl_datacenter = string
83	ACLDatacenter string
84
85	// ACLDefaultPolicy is used to control the ACL interaction when
86	// there is no defined policy. This can be "allow" which means
87	// ACLs are used to black-list, or "deny" which means ACLs are
88	// white-lists.
89	//
90	// hcl: acl.default_policy = ("allow"|"deny")
91	ACLDefaultPolicy string
92
93	// ACLDownPolicy is used to control the ACL interaction when we cannot
94	// reach the ACLDatacenter and the token is not in the cache.
95	// There are the following modes:
96	//   * allow - Allow all requests
97	//   * deny - Deny all requests
98	//   * extend-cache - Ignore the cache expiration, and allow cached
99	//                    ACL's to be used to service requests. This
100	//                    is the default. If the ACL is not in the cache,
101	//                    this acts like deny.
102	//   * async-cache - Same behaviour as extend-cache, but perform ACL
103	//                   Lookups asynchronously when cache TTL is expired.
104	//
105	// hcl: acl.down_policy = ("allow"|"deny"|"extend-cache"|"async-cache")
106	ACLDownPolicy string
107
108	// DEPRECATED (ACL-Legacy-Compat)
109	// ACLEnforceVersion8 is used to gate a set of ACL policy features that
110	// are opt-in prior to Consul 0.8 and opt-out in Consul 0.8 and later.
111	//
112	// hcl: acl_enforce_version_8 = (true|false)
113	ACLEnforceVersion8 bool
114
115	// ACLEnableKeyListPolicy is used to opt-in to the "list" policy added to
116	// KV ACLs in Consul 1.0.
117	//
118	// See https://www.consul.io/docs/guides/acl.html#list-policy-for-keys for
119	// more details.
120	//
121	// hcl: acl.enable_key_list_policy = (true|false)
122	ACLEnableKeyListPolicy bool
123
124	// ACLMasterToken is used to bootstrap the ACL system. It should be specified
125	// on the servers in the ACLDatacenter. When the leader comes online, it ensures
126	// that the Master token is available. This provides the initial token.
127	//
128	// hcl: acl.tokens.master = string
129	ACLMasterToken string
130
131	// ACLReplicationToken is used to fetch ACLs from the ACLDatacenter in
132	// order to replicate them locally. Setting this to a non-empty value
133	// also enables replication. Replication is only available in datacenters
134	// other than the ACLDatacenter.
135	//
136	// hcl: acl.tokens.replication = string
137	ACLReplicationToken string
138
139	// ACLtokenReplication is used to indicate that both tokens and policies
140	// should be replicated instead of just policies
141	//
142	// hcl: acl.token_replication = boolean
143	ACLTokenReplication bool
144
145	// ACLTokenTTL is used to control the time-to-live of cached ACL tokens. This has
146	// a major impact on performance. By default, it is set to 30 seconds.
147	//
148	// hcl: acl.policy_ttl = "duration"
149	ACLTokenTTL time.Duration
150
151	// ACLPolicyTTL is used to control the time-to-live of cached ACL policies. This has
152	// a major impact on performance. By default, it is set to 30 seconds.
153	//
154	// hcl: acl.token_ttl = "duration"
155	ACLPolicyTTL time.Duration
156
157	// ACLToken is the default token used to make requests if a per-request
158	// token is not provided. If not configured the 'anonymous' token is used.
159	//
160	// hcl: acl.tokens.default = string
161	ACLToken string
162
163	// AutopilotCleanupDeadServers enables the automatic cleanup of dead servers when new ones
164	// are added to the peer list. Defaults to true.
165	//
166	// hcl: autopilot { cleanup_dead_servers = (true|false) }
167	AutopilotCleanupDeadServers bool
168
169	// AutopilotDisableUpgradeMigration will disable Autopilot's upgrade migration
170	// strategy of waiting until enough newer-versioned servers have been added to the
171	// cluster before promoting them to voters. (Enterprise-only)
172	//
173	// hcl: autopilot { disable_upgrade_migration = (true|false)
174	AutopilotDisableUpgradeMigration bool
175
176	// AutopilotLastContactThreshold is the limit on the amount of time a server can go
177	// without leader contact before being considered unhealthy.
178	//
179	// hcl: autopilot { last_contact_threshold = "duration" }
180	AutopilotLastContactThreshold time.Duration
181
182	// AutopilotMaxTrailingLogs is the amount of entries in the Raft Log that a server can
183	// be behind before being considered unhealthy. The value must be positive.
184	//
185	// hcl: autopilot { max_trailing_logs = int }
186	AutopilotMaxTrailingLogs int
187
188	// AutopilotRedundancyZoneTag is the Meta tag to use for separating servers
189	// into zones for redundancy. If left blank, this feature will be disabled.
190	// (Enterprise-only)
191	//
192	// hcl: autopilot { redundancy_zone_tag = string }
193	AutopilotRedundancyZoneTag string
194
195	// AutopilotServerStabilizationTime is the minimum amount of time a server must be
196	// in a stable, healthy state before it can be added to the cluster. Only
197	// applicable with Raft protocol version 3 or higher.
198	//
199	// hcl: autopilot { server_stabilization_time = "duration" }
200	AutopilotServerStabilizationTime time.Duration
201
202	// AutopilotUpgradeVersionTag is the node tag to use for version info when
203	// performing upgrade migrations. If left blank, the Consul version will be used.
204	//
205	// (Enterprise-only)
206	//
207	// hcl: autopilot { upgrade_version_tag = string }
208	AutopilotUpgradeVersionTag string
209
210	// DNSAllowStale is used to enable lookups with stale
211	// data. This gives horizontal read scalability since
212	// any Consul server can service the query instead of
213	// only the leader.
214	//
215	// hcl: dns_config { allow_stale = (true|false) }
216	DNSAllowStale bool
217
218	// DNSARecordLimit is used to limit the maximum number of DNS Resource
219	// Records returned in the ANSWER section of a DNS response for A or AAAA
220	// records for both UDP and TCP queries.
221	//
222	// This is not normally useful and will be limited based on the querying
223	// protocol, however systems that implemented §6 Rule 9 in RFC3484
224	// may want to set this to `1` in order to subvert §6 Rule 9 and
225	// re-obtain the effect of randomized resource records (i.e. each
226	// answer contains only one IP, but the IP changes every request).
227	// RFC3484 sorts answers in a deterministic order, which defeats the
228	// purpose of randomized DNS responses.  This RFC has been obsoleted
229	// by RFC6724 and restores the desired behavior of randomized
230	// responses, however a large number of Linux hosts using glibc(3)
231	// implemented §6 Rule 9 and may need this option (e.g. CentOS 5-6,
232	// Debian Squeeze, etc).
233	//
234	// hcl: dns_config { a_record_limit = int }
235	DNSARecordLimit int
236
237	// DNSDisableCompression is used to control whether DNS responses are
238	// compressed. In Consul 0.7 this was turned on by default and this
239	// config was added as an opt-out.
240	//
241	// hcl: dns_config { disable_compression = (true|false) }
242	DNSDisableCompression bool
243
244	// DNSDomain is the DNS domain for the records. Should end with a dot.
245	// Defaults to "consul."
246	//
247	// hcl: domain = string
248	// flag: -domain string
249	DNSDomain string
250
251	// DNSEnableTruncate is used to enable setting the truncate
252	// flag for UDP DNS queries.  This allows unmodified
253	// clients to re-query the consul server using TCP
254	// when the total number of records exceeds the number
255	// returned by default for UDP.
256	//
257	// hcl: dns_config { enable_truncate = (true|false) }
258	DNSEnableTruncate bool
259
260	// DNSMaxStale is used to bound how stale of a result is
261	// accepted for a DNS lookup. This can be used with
262	// AllowStale to limit how old of a value is served up.
263	// If the stale result exceeds this, another non-stale
264	// stale read is performed.
265	//
266	// hcl: dns_config { max_stale = "duration" }
267	DNSMaxStale time.Duration
268
269	// DNSNodeTTL provides the TTL value for a node query.
270	//
271	// hcl: dns_config { node_ttl = "duration" }
272	DNSNodeTTL time.Duration
273
274	// DNSOnlyPassing is used to determine whether to filter nodes
275	// whose health checks are in any non-passing state. By
276	// default, only nodes in a critical state are excluded.
277	//
278	// hcl: dns_config { only_passing = "duration" }
279	DNSOnlyPassing bool
280
281	// DNSRecursorTimeout specifies the timeout in seconds
282	// for Consul's internal dns client used for recursion.
283	// This value is used for the connection, read and write timeout.
284	//
285	// hcl: dns_config { recursor_timeout = "duration" }
286	DNSRecursorTimeout time.Duration
287
288	// DNSServiceTTL provides the TTL value for a service
289	// query for given service. The "*" wildcard can be used
290	// to set a default for all services.
291	//
292	// hcl: dns_config { service_ttl = map[string]"duration" }
293	DNSServiceTTL map[string]time.Duration
294
295	// DNSUDPAnswerLimit is used to limit the maximum number of DNS Resource
296	// Records returned in the ANSWER section of a DNS response for UDP
297	// responses without EDNS support (limited to 512 bytes).
298	// This parameter is deprecated, if you want to limit the number of
299	// records returned by A or AAAA questions, please use DNSARecordLimit
300	// instead.
301	//
302	// hcl: dns_config { udp_answer_limit = int }
303	DNSUDPAnswerLimit int
304
305	// DNSNodeMetaTXT controls whether DNS queries will synthesize
306	// TXT records for the node metadata and add them when not specifically
307	// request (query type = TXT). If unset this will default to true
308	DNSNodeMetaTXT bool
309
310	// DNSRecursors can be set to allow the DNS servers to recursively
311	// resolve non-consul domains.
312	//
313	// hcl: recursors = []string
314	// flag: -recursor string [-recursor string]
315	DNSRecursors []string
316
317	// HTTPBlockEndpoints is a list of endpoint prefixes to block in the
318	// HTTP API. Any requests to these will get a 403 response.
319	//
320	// hcl: http_config { block_endpoints = []string }
321	HTTPBlockEndpoints []string
322
323	// AllowWriteHTTPFrom restricts the agent write endpoints to the given
324	// networks. Any request to a protected endpoint that is not mactched
325	// by one of these networks will get a 403 response.
326	// An empty slice means no restriction.
327	//
328	// hcl: http_config { allow_write_http_from = []string }
329	AllowWriteHTTPFrom []*net.IPNet
330
331	// HTTPResponseHeaders are used to add HTTP header response fields to the HTTP API responses.
332	//
333	// hcl: http_config { response_headers = map[string]string }
334	HTTPResponseHeaders map[string]string
335
336	// Embed Telemetry Config
337	Telemetry lib.TelemetryConfig
338
339	// Datacenter is the datacenter this node is in. Defaults to "dc1".
340	//
341	// Datacenter is exposed via /v1/agent/self from here and
342	// used in lots of places like CLI commands. Treat this as an interface
343	// that must be stable.
344	//
345	// hcl: datacenter = string
346	// flag: -datacenter string
347	Datacenter string
348
349	// Defines the maximum stale value for discovery path. Defauls to "0s".
350	// Discovery paths are /v1/heath/ paths
351	//
352	// If not set to 0, it will try to perform stale read and perform only a
353	// consistent read whenever the value is too old.
354	// hcl: discovery_max_stale = "duration"
355	DiscoveryMaxStale time.Duration
356
357	// Node name is the name we use to advertise. Defaults to hostname.
358	//
359	// NodeName is exposed via /v1/agent/self from here and
360	// used in lots of places like CLI commands. Treat this as an interface
361	// that must be stable.
362	//
363	// hcl: node_name = string
364	// flag: -node string
365	NodeName string
366
367	// AdvertiseAddrLAN is the address we use for advertising our Serf, and
368	// Consul RPC IP. The address can be specified as an ip address or as a
369	// go-sockaddr template which resolves to a single ip address. If not
370	// specified, the bind address is used.
371	//
372	// hcl: advertise_addr = string
373	AdvertiseAddrLAN *net.IPAddr
374
375	// AdvertiseAddrWAN is the address we use for advertising our Serf, and
376	// Consul RPC IP. The address can be specified as an ip address or as a
377	// go-sockaddr template which resolves to a single ip address. If not
378	// specified, the bind address is used.
379	//
380	// hcl: advertise_addr_wan = string
381	AdvertiseAddrWAN *net.IPAddr
382
383	// BindAddr is used to control the address we bind to.
384	// If not specified, the first private IP we find is used.
385	// This controls the address we use for cluster facing
386	// services (Gossip, Server RPC)
387	//
388	// The value can be either an ip address or a go-sockaddr
389	// template which resolves to a single ip address.
390	//
391	// hcl: bind_addr = string
392	// flag: -bind string
393	BindAddr *net.IPAddr
394
395	// Bootstrap is used to bring up the first Consul server, and
396	// permits that node to elect itself leader
397	//
398	// hcl: bootstrap = (true|false)
399	// flag: -bootstrap
400	Bootstrap bool
401
402	// BootstrapExpect tries to automatically bootstrap the Consul cluster, by
403	// having servers wait to bootstrap until enough servers join, and then
404	// performing the bootstrap process automatically. They will disable their
405	// automatic bootstrap process if they detect any servers that are part of
406	// an existing cluster, so it's safe to leave this set to a non-zero value.
407	//
408	// hcl: bootstrap_expect = int
409	// flag: -bootstrap-expect=int
410	BootstrapExpect int
411
412	// CAFile is a path to a certificate authority file. This is used with
413	// VerifyIncoming or VerifyOutgoing to verify the TLS connection.
414	//
415	// hcl: ca_file = string
416	CAFile string
417
418	// CAPath is a path to a directory of certificate authority files. This is
419	// used with VerifyIncoming or VerifyOutgoing to verify the TLS connection.
420	//
421	// hcl: ca_path = string
422	CAPath string
423
424	// CertFile is used to provide a TLS certificate that is used for serving
425	// TLS connections. Must be provided to serve TLS connections.
426	//
427	// hcl: cert_file = string
428	CertFile string
429
430	// CheckUpdateInterval controls the interval on which the output of a health check
431	// is updated if there is no change to the state. For example, a check in a steady
432	// state may run every 5 second generating a unique output (timestamp, etc), forcing
433	// constant writes. This allows Consul to defer the write for some period of time,
434	// reducing the write pressure when the state is steady.
435	//
436	// See also: DiscardCheckOutput
437	//
438	// hcl: check_update_interval = "duration"
439	CheckUpdateInterval time.Duration
440
441	// Checks contains the provided check definitions.
442	//
443	// hcl: checks = [
444	//   {
445	//     id = string
446	//     name = string
447	//     notes = string
448	//     service_id = string
449	//     token = string
450	//     status = string
451	//     script = string
452	//     args = string
453	//     http = string
454	//     header = map[string][]string
455	//     method = string
456	//     tcp = string
457	//     interval = string
458	//     docker_container_id = string
459	//     shell = string
460	//     tls_skip_verify = (true|false)
461	//     timeout = "duration"
462	//     ttl = "duration"
463	//     deregister_critical_service_after = "duration"
464	//   },
465	//   ...
466	// ]
467	Checks []*structs.CheckDefinition
468
469	// ClientAddrs contains the list of ip addresses the DNS, HTTP and HTTPS
470	// endpoints will bind to if the endpoints are enabled (ports > 0) and the
471	// addresses are not overwritten.
472	//
473	// The ip addresses must be provided as a space separated list of ip
474	// addresses and go-sockaddr templates.
475	//
476	// Client addresses cannot contain UNIX socket addresses since a socket
477	// cannot be shared across multiple endpoints (no ports). To use UNIX
478	// sockets configure it in 'addresses'.
479	//
480	// hcl: client_addr = string
481	// flag: -client string
482	ClientAddrs []*net.IPAddr
483
484	// ConnectEnabled opts the agent into connect. It should be set on all clients
485	// and servers in a cluster for correct connect operation.
486	ConnectEnabled bool
487
488	// ConnectProxyBindMinPort is the inclusive start of the range of ports
489	// allocated to the agent for starting proxy listeners on where no explicit
490	// port is specified.
491	ConnectProxyBindMinPort int
492
493	// ConnectProxyBindMaxPort is the inclusive end of the range of ports
494	// allocated to the agent for starting proxy listeners on where no explicit
495	// port is specified.
496	ConnectProxyBindMaxPort int
497
498	// ConnectSidecarMinPort is the inclusive start of the range of ports
499	// allocated to the agent for asigning to sidecar services where no port is
500	// specified.
501	ConnectSidecarMinPort int
502
503	// ConnectSidecarMaxPort is the inclusive end of the range of ports
504	// allocated to the agent for asigning to sidecar services where no port is
505	// specified
506	ConnectSidecarMaxPort int
507
508	// ConnectProxyAllowManagedRoot is true if Consul can execute managed
509	// proxies when running as root (EUID == 0).
510	ConnectProxyAllowManagedRoot bool
511
512	// ConnectProxyAllowManagedAPIRegistration enables managed proxy registration
513	// via the agent HTTP API. If this is false, only file configurations
514	// can be used.
515	ConnectProxyAllowManagedAPIRegistration bool
516
517	// ConnectProxyDefaultExecMode is used where a registration doesn't include an
518	// exec_mode. Defaults to daemon.
519	ConnectProxyDefaultExecMode string
520
521	// ConnectProxyDefaultDaemonCommand is used to start proxy in exec_mode =
522	// daemon if not specified at registration time.
523	ConnectProxyDefaultDaemonCommand []string
524
525	// ConnectProxyDefaultScriptCommand is used to start proxy in exec_mode =
526	// script if not specified at registration time.
527	ConnectProxyDefaultScriptCommand []string
528
529	// ConnectProxyDefaultConfig is merged with any config specified at
530	// registration time to allow global control of defaults.
531	ConnectProxyDefaultConfig map[string]interface{}
532
533	// ConnectCAProvider is the type of CA provider to use with Connect.
534	ConnectCAProvider string
535
536	// ConnectCAConfig is the config to use for the CA provider.
537	ConnectCAConfig map[string]interface{}
538
539	// ConnectReplicationToken is the ACL token used for replicating intentions.
540	ConnectReplicationToken string
541
542	// ConnectTestDisableManagedProxies is not exposed to public config but is
543	// used by TestAgent to prevent self-executing the test binary in the
544	// background if a managed proxy is created for a test. The only place we
545	// actually want to test processes really being spun up and managed is in
546	// `agent/proxy` and it does it at a lower level. Note that this still allows
547	// registering managed proxies via API and other methods, and still creates
548	// all the agent state for them, just doesn't actually start external
549	// processes up.
550	ConnectTestDisableManagedProxies bool
551
552	// ConnectTestCALeafRootChangeSpread is used to control how long the CA leaf
553	// cache with spread CSRs over when a root change occurs. For now we don't
554	// expose this in public config intentionally but could later with a rename.
555	// We only set this from during tests to effectively make CA rotation tests
556	// deterministic again.
557	ConnectTestCALeafRootChangeSpread time.Duration
558
559	// DNSAddrs contains the list of TCP and UDP addresses the DNS server will
560	// bind to. If the DNS endpoint is disabled (ports.dns <= 0) the list is
561	// empty.
562	//
563	// The ip addresses are taken from 'addresses.dns' which should contain a
564	// space separated list of ip addresses and/or go-sockaddr templates.
565	//
566	// If 'addresses.dns' was not provided the 'client_addr' addresses are
567	// used.
568	//
569	// The DNS server cannot be bound to UNIX sockets.
570	//
571	// hcl: client_addr = string addresses { dns = string } ports { dns = int }
572	DNSAddrs []net.Addr
573
574	// DNSPort is the port the DNS server listens on. The default is 8600.
575	// Setting this to a value <= 0 disables the endpoint.
576	//
577	// hcl: ports { dns = int }
578	// flags: -dns-port int
579	DNSPort int
580
581	// DNSSOA is the settings applied for DNS SOA
582	// hcl: soa {}
583	DNSSOA RuntimeSOAConfig
584
585	// DataDir is the path to the directory where the local state is stored.
586	//
587	// hcl: data_dir = string
588	// flag: -data-dir string
589	DataDir string
590
591	// DevMode enables a fast-path mode of operation to bring up an in-memory
592	// server with minimal configuration. Useful for developing Consul.
593	//
594	// flag: -dev
595	DevMode bool
596
597	// DisableAnonymousSignature is used to turn off the anonymous signature
598	// send with the update check. This is used to deduplicate messages.
599	//
600	// hcl: disable_anonymous_signature = (true|false)
601	DisableAnonymousSignature bool
602
603	// DisableCoordinates controls features related to network coordinates.
604	//
605	// hcl: disable_coordinates = (true|false)
606	DisableCoordinates bool
607
608	// DisableHostNodeID will prevent Consul from using information from the
609	// host to generate a node ID, and will cause Consul to generate a
610	// random ID instead.
611	//
612	// hcl: disable_host_node_id = (true|false)
613	// flag: -disable-host-node-id
614	DisableHostNodeID bool
615
616	// DisableHTTPUnprintableCharFilter will bypass the filter preventing HTTP
617	// URLs from containing unprintable chars. This filter was added in 1.0.3 as a
618	// response to a vulnerability report. Disabling this is never recommended in
619	// general however some users who have keys written in older versions of
620	// Consul may use this to temporarily disable the filter such that they can
621	// delete those keys again! We do not recommend leaving it disabled long term.
622	//
623	// hcl: disable_http_unprintable_char_filter
624	DisableHTTPUnprintableCharFilter bool
625
626	// DisableKeyringFile disables writing the keyring to a file.
627	//
628	// hcl: disable_keyring_file = (true|false)
629	// flag: -disable-keyring-file
630	DisableKeyringFile bool
631
632	// DisableRemoteExec is used to turn off the remote execution
633	// feature. This is for security to prevent unknown scripts from running.
634	//
635	// hcl: disable_remote_exec = (true|false)
636	DisableRemoteExec bool
637
638	// DisableUpdateCheck is used to turn off the automatic update and
639	// security bulletin checking.
640	//
641	// hcl: disable_update_check = (true|false)
642	DisableUpdateCheck bool
643
644	// DiscardCheckOutput is used to turn off storing and comparing the
645	// output of health checks. This reduces the write rate on the server
646	// for checks with highly volatile output. (reloadable)
647	//
648	// See also: CheckUpdateInterval
649	//
650	// hcl: discard_check_output = (true|false)
651	DiscardCheckOutput bool
652
653	// EnableAgentTLSForChecks is used to apply the agent's TLS settings in
654	// order to configure the HTTP client used for health checks. Enabling
655	// this allows HTTP checks to present a client certificate and verify
656	// the server using the same TLS configuration as the agent (CA, cert,
657	// and key).
658	EnableAgentTLSForChecks bool
659
660	// EnableDebug is used to enable various debugging features.
661	//
662	// hcl: enable_debug = (true|false)
663	EnableDebug bool
664
665	// EnableLocalScriptChecks controls whether health checks declared from the local
666	// config file which execute scripts are enabled. This includes regular script
667	// checks and Docker checks.
668	//
669	// hcl: (enable_script_checks|enable_local_script_checks) = (true|false)
670	// flag: -enable-script-checks, -enable-local-script-checks
671	EnableLocalScriptChecks bool
672
673	// EnableRemoeScriptChecks controls whether health checks declared from the http API
674	// which execute scripts are enabled. This includes regular script checks and Docker
675	// checks.
676	//
677	// hcl: enable_script_checks = (true|false)
678	// flag: -enable-script-checks
679	EnableRemoteScriptChecks bool
680
681	// EnableSyslog is used to also tee all the logs over to syslog. Only supported
682	// on linux and OSX. Other platforms will generate an error.
683	//
684	// hcl: enable_syslog = (true|false)
685	// flag: -syslog
686	EnableSyslog bool
687
688	// EnableUI enables the statically-compiled assets for the Consul web UI and
689	// serves them at the default /ui/ endpoint automatically.
690	//
691	// hcl: enable_ui = (true|false)
692	// flag: -ui
693	EnableUI bool
694
695	// EncryptKey contains the encryption key to use for the Serf communication.
696	//
697	// hcl: encrypt = string
698	// flag: -encrypt string
699	EncryptKey string
700
701	// EncryptVerifyIncoming enforces incoming gossip encryption and can be
702	// used to upshift to encrypted gossip on a running cluster.
703	//
704	// hcl: encrypt_verify_incoming = (true|false)
705	EncryptVerifyIncoming bool
706
707	// EncryptVerifyOutgoing enforces outgoing gossip encryption and can be
708	// used to upshift to encrypted gossip on a running cluster.
709	//
710	// hcl: encrypt_verify_outgoing = (true|false)
711	EncryptVerifyOutgoing bool
712
713	// GRPCPort is the port the gRPC server listens on. Currently this only
714	// exposes the xDS and ext_authz APIs for Envoy and it is disabled by default.
715	//
716	// hcl: ports { grpc = int }
717	// flags: -grpc-port int
718	GRPCPort int
719
720	// GRPCAddrs contains the list of TCP addresses and UNIX sockets the gRPC
721	// server will bind to. If the gRPC endpoint is disabled (ports.grpc <= 0)
722	// the list is empty.
723	//
724	// The addresses are taken from 'addresses.grpc' which should contain a
725	// space separated list of ip addresses, UNIX socket paths and/or
726	// go-sockaddr templates. UNIX socket paths must be written as
727	// 'unix://<full path>', e.g. 'unix:///var/run/consul-grpc.sock'.
728	//
729	// If 'addresses.grpc' was not provided the 'client_addr' addresses are
730	// used.
731	//
732	// hcl: client_addr = string addresses { grpc = string } ports { grpc = int }
733	GRPCAddrs []net.Addr
734
735	// HTTPAddrs contains the list of TCP addresses and UNIX sockets the HTTP
736	// server will bind to. If the HTTP endpoint is disabled (ports.http <= 0)
737	// the list is empty.
738	//
739	// The addresses are taken from 'addresses.http' which should contain a
740	// space separated list of ip addresses, UNIX socket paths and/or
741	// go-sockaddr templates. UNIX socket paths must be written as
742	// 'unix://<full path>', e.g. 'unix:///var/run/consul-http.sock'.
743	//
744	// If 'addresses.http' was not provided the 'client_addr' addresses are
745	// used.
746	//
747	// hcl: client_addr = string addresses { http = string } ports { http = int }
748	HTTPAddrs []net.Addr
749
750	// HTTPPort is the port the HTTP server listens on. The default is 8500.
751	// Setting this to a value <= 0 disables the endpoint.
752	//
753	// hcl: ports { http = int }
754	// flags: -http-port int
755	HTTPPort int
756
757	// HTTPSAddrs contains the list of TCP addresses and UNIX sockets the HTTPS
758	// server will bind to. If the HTTPS endpoint is disabled (ports.https <=
759	// 0) the list is empty.
760	//
761	// The addresses are taken from 'addresses.https' which should contain a
762	// space separated list of ip addresses, UNIX socket paths and/or
763	// go-sockaddr templates. UNIX socket paths must be written as
764	// 'unix://<full path>', e.g. 'unix:///var/run/consul-https.sock'.
765	//
766	// If 'addresses.https' was not provided the 'client_addr' addresses are
767	// used.
768	//
769	// hcl: client_addr = string addresses { https = string } ports { https = int }
770	HTTPSAddrs []net.Addr
771
772	// HTTPSPort is the port the HTTP server listens on. The default is -1.
773	// Setting this to a value <= 0 disables the endpoint.
774	//
775	// hcl: ports { https = int }
776	HTTPSPort int
777
778	// KeyFile is used to provide a TLS key that is used for serving TLS
779	// connections. Must be provided to serve TLS connections.
780	//
781	// hcl: key_file = string
782	KeyFile string
783
784	// LeaveDrainTime is used to wait after a server has left the LAN Serf
785	// pool for RPCs to drain and new requests to be sent to other servers.
786	//
787	// hcl: performance { leave_drain_time = "duration" }
788	LeaveDrainTime time.Duration
789
790	// LeaveOnTerm controls if Serf does a graceful leave when receiving
791	// the TERM signal. Defaults true on clients, false on servers. (reloadable)
792	//
793	// hcl: leave_on_terminate = (true|false)
794	LeaveOnTerm bool
795
796	// LogLevel is the level of the logs to write. Defaults to "INFO".
797	//
798	// hcl: log_level = string
799	LogLevel string
800
801	// LogFile is the path to the file where the logs get written to. Defaults to empty string.
802	//
803	// hcl: log_file = string
804	// flags: -log-file string
805	LogFile string
806
807	// LogRotateDuration is the time configured to rotate logs based on time
808	//
809	// hcl: log_rotate_duration = string
810	// flags: -log-rotate-duration string
811	LogRotateDuration time.Duration
812
813	// LogRotateBytes is the time configured to rotate logs based on bytes written
814	//
815	// hcl: log_rotate_bytes = int
816	// flags: -log-rotate-bytes int
817	LogRotateBytes int
818
819	// Node ID is a unique ID for this node across space and time. Defaults
820	// to a randomly-generated ID that persists in the data-dir.
821	//
822	// todo(fs): don't we have a requirement for this to be a UUID in a specific format?
823	//
824	// hcl: node_id = string
825	// flag: -node-id string
826	NodeID types.NodeID
827
828	// NodeMeta contains metadata key/value pairs. These are excluded from JSON output
829	// because they can be reloaded and might be stale when shown from the
830	// config instead of the local state.
831	// todo(fs): should the sanitizer omit them from output as well since they could be stale?
832	//
833	// hcl: node_meta = map[string]string
834	// flag: -node-meta "key:value" -node-meta "key:value" ...
835	NodeMeta map[string]string
836
837	// NonVotingServer is whether this server will act as a non-voting member
838	// of the cluster to help provide read scalability. (Enterprise-only)
839	//
840	// hcl: non_voting_server = (true|false)
841	// flag: -non-voting-server
842	NonVotingServer bool
843
844	// PidFile is the file to store our PID in.
845	//
846	// hcl: pid_file = string
847	PidFile string
848
849	// PrimaryDatacenter is the central datacenter that holds authoritative
850	// ACL records, replicates intentions and holds the root CA for Connect.
851	// This must be the same for the entire cluster. Off by default.
852	//
853	// hcl: primary_datacenter = string
854	PrimaryDatacenter string
855
856	// RPCAdvertiseAddr is the TCP address Consul advertises for its RPC endpoint.
857	// By default this is the bind address on the default RPC Server port. If the
858	// advertise address is specified then it is used.
859	//
860	// hcl: bind_addr = string advertise_addr = string ports { server = int }
861	RPCAdvertiseAddr *net.TCPAddr
862
863	// RPCBindAddr is the TCP address Consul will bind to for its RPC endpoint.
864	// By default this is the bind address on the default RPC Server port.
865	//
866	// hcl: bind_addr = string ports { server = int }
867	RPCBindAddr *net.TCPAddr
868
869	// RPCHoldTimeout is how long an RPC can be "held" before it is errored.
870	// This is used to paper over a loss of leadership by instead holding RPCs,
871	// so that the caller experiences a slow response rather than an error.
872	// This period is meant to be long enough for a leader election to take
873	// place, and a small jitter is applied to avoid a thundering herd.
874	//
875	// hcl: performance { rpc_hold_timeout = "duration" }
876	RPCHoldTimeout time.Duration
877
878	// RPCRateLimit and RPCMaxBurst control how frequently RPC calls are allowed
879	// to happen. In any large enough time interval, rate limiter limits the
880	// rate to RPCRate tokens per second, with a maximum burst size of
881	// RPCMaxBurst events. As a special case, if RPCRate == Inf (the infinite
882	// rate), RPCMaxBurst is ignored.
883	//
884	// See https://en.wikipedia.org/wiki/Token_bucket for more about token
885	// buckets.
886	//
887	// hcl: limit { rpc_rate = (float64|MaxFloat64) rpc_max_burst = int }
888	RPCRateLimit rate.Limit
889	RPCMaxBurst  int
890
891	// RPCProtocol is the Consul protocol version to use.
892	//
893	// hcl: protocol = int
894	RPCProtocol int
895
896	// RaftProtocol sets the Raft protocol version to use on this server.
897	// Defaults to 3.
898	//
899	// hcl: raft_protocol = int
900	RaftProtocol int
901
902	// RaftSnapshotThreshold sets the minimum threshold of raft commits after which
903	// a snapshot is created. Defaults to 8192
904	//
905	// hcl: raft_snapshot_threshold = int
906	RaftSnapshotThreshold int
907
908	// RaftSnapshotInterval sets the interval to use when checking whether to create
909	// a new snapshot. Defaults to 5 seconds.
910	// hcl: raft_snapshot_threshold = int
911	RaftSnapshotInterval time.Duration
912
913	// ReconnectTimeoutLAN specifies the amount of time to wait to reconnect with
914	// another agent before deciding it's permanently gone. This can be used to
915	// control the time it takes to reap failed nodes from the cluster.
916	//
917	// hcl: reconnect_timeout = "duration"
918	ReconnectTimeoutLAN time.Duration
919
920	// ReconnectTimeoutWAN specifies the amount of time to wait to reconnect with
921	// another agent before deciding it's permanently gone. This can be used to
922	// control the time it takes to reap failed nodes from the cluster.
923	//
924	// hcl: reconnect_timeout = "duration"
925	ReconnectTimeoutWAN time.Duration
926
927	// RejoinAfterLeave controls our interaction with the cluster after leave.
928	// When set to false (default), a leave causes Consul to not rejoin
929	// the cluster until an explicit join is received. If this is set to
930	// true, we ignore the leave, and rejoin the cluster on start.
931	//
932	// hcl: rejoin_after_leave = (true|false)
933	// flag: -rejoin
934	RejoinAfterLeave bool
935
936	// RetryJoinIntervalLAN specifies the amount of time to wait in between join
937	// attempts on agent start. The minimum allowed value is 1 second and
938	// the default is 30s.
939	//
940	// hcl: retry_join = "duration"
941	RetryJoinIntervalLAN time.Duration
942
943	// RetryJoinIntervalWAN specifies the amount of time to wait in between join
944	// attempts on agent start. The minimum allowed value is 1 second and
945	// the default is 30s.
946	//
947	// hcl: retry_join_wan = "duration"
948	RetryJoinIntervalWAN time.Duration
949
950	// RetryJoinLAN is a list of addresses and/or go-discover expressions to
951	// join with retry enabled. See
952	// https://www.consul.io/docs/agent/options.html#cloud-auto-joining for
953	// details.
954	//
955	// hcl: retry_join = []string
956	// flag: -retry-join string -retry-join string
957	RetryJoinLAN []string
958
959	// RetryJoinMaxAttemptsLAN specifies the maximum number of times to retry
960	// joining a host on startup. This is useful for cases where we know the
961	// node will be online eventually.
962	//
963	// hcl: retry_max = int
964	// flag: -retry-max int
965	RetryJoinMaxAttemptsLAN int
966
967	// RetryJoinMaxAttemptsWAN specifies the maximum number of times to retry
968	// joining a host on startup. This is useful for cases where we know the
969	// node will be online eventually.
970	//
971	// hcl: retry_max_wan = int
972	// flag: -retry-max-wan int
973	RetryJoinMaxAttemptsWAN int
974
975	// RetryJoinWAN is a list of addresses and/or go-discover expressions to
976	// join -wan with retry enabled. See
977	// https://www.consul.io/docs/agent/options.html#cloud-auto-joining for
978	// details.
979	//
980	// hcl: retry_join_wan = []string
981	// flag: -retry-join-wan string -retry-join-wan string
982	RetryJoinWAN []string
983
984	// SegmentName is the network segment for this client to join.
985	// (Enterprise-only)
986	//
987	// hcl: segment = string
988	SegmentName string
989
990	// Segments is the list of network segments for this server to
991	// initialize.
992	//
993	// hcl: segment = [
994	//   {
995	//     # name is the name of the segment
996	//     name = string
997	//
998	//     # bind is the bind ip address for this segment.
999	//     bind = string
1000	//
1001	//     # port is the bind port for this segment.
1002	//     port = int
1003	//
1004	//     # advertise is the advertise ip address for this segment.
1005	//     # Defaults to the bind address if not set.
1006	//     advertise = string
1007	//
1008	//     # rpc_listener controls whether or not to bind a separate
1009	//     # RPC listener to the bind address.
1010	//     rpc_listener = (true|false)
1011	//   },
1012	//   ...
1013	// ]
1014	Segments []structs.NetworkSegment
1015
1016	// SerfAdvertiseAddrLAN is the TCP address which is used for advertising
1017	// the LAN Gossip pool for both client and server. The address is the
1018	// combination of AdvertiseAddrLAN and the SerfPortLAN. If the advertise
1019	// address is not given the bind address is used.
1020	//
1021	// hcl: bind_addr = string advertise_addr = string ports { serf_lan = int }
1022	SerfAdvertiseAddrLAN *net.TCPAddr
1023
1024	// SerfAdvertiseAddrWAN is the TCP address which is used for advertising
1025	// the WAN Gossip pool on the server only. The address is the combination
1026	// of AdvertiseAddrWAN and the SerfPortWAN. If the advertise address is not
1027	// given the bind address is used.
1028	//
1029	// hcl: bind_addr = string advertise_addr_wan = string ports { serf_wan = int }
1030	SerfAdvertiseAddrWAN *net.TCPAddr
1031
1032	// SerfBindAddrLAN is the address to bind the Serf LAN TCP and UDP
1033	// listeners to. The ip address is either the default bind address or the
1034	// 'serf_lan' address which can be either an ip address or a go-sockaddr
1035	// template which resolves to a single ip address.
1036	//
1037	// hcl: bind_addr = string serf_lan = string ports { serf_lan = int }
1038	// flag: -serf-lan string
1039	SerfBindAddrLAN *net.TCPAddr
1040
1041	// SerfBindAddrWAN is the address to bind the Serf WAN TCP and UDP
1042	// listeners to. The ip address is either the default bind address or the
1043	// 'serf_wan' address which can be either an ip address or a go-sockaddr
1044	// template which resolves to a single ip address.
1045	//
1046	// hcl: bind_addr = string serf_wan = string ports { serf_wan = int }
1047	// flag: -serf-wan string
1048	SerfBindAddrWAN *net.TCPAddr
1049
1050	// SerfPortLAN is the port used for the LAN Gossip pool for both client and server.
1051	// The default is 8301.
1052	//
1053	// hcl: ports { serf_lan = int }
1054	SerfPortLAN int
1055
1056	// SerfPortWAN is the port used for the WAN Gossip pool for the server only.
1057	// The default is 8302.
1058	//
1059	// hcl: ports { serf_wan = int }
1060	SerfPortWAN int
1061
1062	// GossipLANGossipInterval is the interval between sending messages that need
1063	// to be gossiped that haven't been able to piggyback on probing messages.
1064	// If this is set to zero, non-piggyback gossip is disabled. By lowering
1065	// this value (more frequent) gossip messages are propagated across
1066	// the cluster more quickly at the expense of increased bandwidth. This
1067	// configuration only applies to LAN gossip communications
1068	//
1069	// The default is: 200ms
1070	//
1071	// hcl: gossip_lan { gossip_interval = duration}
1072	GossipLANGossipInterval time.Duration
1073
1074	// GossipLANGossipNodes is the number of random nodes to send gossip messages to
1075	// per GossipInterval. Increasing this number causes the gossip messages to
1076	// propagate across the cluster more quickly at the expense of increased
1077	// bandwidth. This configuration only applies to LAN gossip communications
1078	//
1079	// The default is: 3
1080	//
1081	// hcl: gossip_lan { gossip_nodes = int }
1082	GossipLANGossipNodes int
1083
1084	// GossipLANProbeInterval is the interval between random node probes. Setting
1085	// this lower (more frequent) will cause the memberlist cluster to detect
1086	// failed nodes more quickly at the expense of increased bandwidth usage.
1087	// This configuration only applies to LAN gossip communications
1088	//
1089	// The default is: 1s
1090	//
1091	// hcl: gossip_lan { probe_interval = duration }
1092	GossipLANProbeInterval time.Duration
1093
1094	// GossipLANProbeTimeout is the timeout to wait for an ack from a probed node
1095	// before assuming it is unhealthy. This should be set to 99-percentile
1096	// of RTT (round-trip time) on your network. This configuration
1097	// only applies to the LAN gossip communications
1098	//
1099	// The default is: 500ms
1100	//
1101	// hcl: gossip_lan { probe_timeout = duration }
1102	GossipLANProbeTimeout time.Duration
1103
1104	// GossipLANSuspicionMult is the multiplier for determining the time an
1105	// inaccessible node is considered suspect before declaring it dead. This
1106	// configuration only applies to LAN gossip communications
1107	//
1108	// The actual timeout is calculated using the formula:
1109	//
1110	//   SuspicionTimeout = SuspicionMult * log(N+1) * ProbeInterval
1111	//
1112	// This allows the timeout to scale properly with expected propagation
1113	// delay with a larger cluster size. The higher the multiplier, the longer
1114	// an inaccessible node is considered part of the cluster before declaring
1115	// it dead, giving that suspect node more time to refute if it is indeed
1116	// still alive.
1117	//
1118	// The default is: 4
1119	//
1120	// hcl: gossip_lan { suspicion_mult = int }
1121	GossipLANSuspicionMult int
1122
1123	// GossipLANRetransmitMult is the multiplier for the number of retransmissions
1124	// that are attempted for messages broadcasted over gossip. This
1125	// configuration only applies to LAN gossip communications. The actual
1126	// count of retransmissions is calculated using the formula:
1127	//
1128	//   Retransmits = RetransmitMult * log(N+1)
1129	//
1130	// This allows the retransmits to scale properly with cluster size. The
1131	// higher the multiplier, the more likely a failed broadcast is to converge
1132	// at the expense of increased bandwidth.
1133	//
1134	// The default is: 4
1135	//
1136	// hcl: gossip_lan { retransmit_mult = int }
1137	GossipLANRetransmitMult int
1138
1139	// GossipWANGossipInterval  is the interval between sending messages that need
1140	// to be gossiped that haven't been able to piggyback on probing messages.
1141	// If this is set to zero, non-piggyback gossip is disabled. By lowering
1142	// this value (more frequent) gossip messages are propagated across
1143	// the cluster more quickly at the expense of increased bandwidth. This
1144	// configuration only applies to WAN gossip communications
1145	//
1146	// The default is: 200ms
1147	//
1148	// hcl: gossip_wan { gossip_interval = duration}
1149	GossipWANGossipInterval time.Duration
1150
1151	// GossipWANGossipNodes is the number of random nodes to send gossip messages to
1152	// per GossipInterval. Increasing this number causes the gossip messages to
1153	// propagate across the cluster more quickly at the expense of increased
1154	// bandwidth. This configuration only applies to WAN gossip communications
1155	//
1156	// The default is: 3
1157	//
1158	// hcl: gossip_wan { gossip_nodes = int }
1159	GossipWANGossipNodes int
1160
1161	// GossipWANProbeInterval is the interval between random node probes. Setting
1162	// this lower (more frequent) will cause the memberlist cluster to detect
1163	// failed nodes more quickly at the expense of increased bandwidth usage.
1164	// This configuration only applies to WAN gossip communications
1165	//
1166	// The default is: 1s
1167	//
1168	// hcl: gossip_wan { probe_interval = duration }
1169	GossipWANProbeInterval time.Duration
1170
1171	// GossipWANProbeTimeout is the timeout to wait for an ack from a probed node
1172	// before assuming it is unhealthy. This should be set to 99-percentile
1173	// of RTT (round-trip time) on your network. This configuration
1174	// only applies to the WAN gossip communications
1175	//
1176	// The default is: 500ms
1177	//
1178	// hcl: gossip_wan { probe_timeout = duration }
1179	GossipWANProbeTimeout time.Duration
1180
1181	// GossipWANSuspicionMult is the multiplier for determining the time an
1182	// inaccessible node is considered suspect before declaring it dead. This
1183	// configuration only applies to WAN gossip communications
1184	//
1185	// The actual timeout is calculated using the formula:
1186	//
1187	//   SuspicionTimeout = SuspicionMult * log(N+1) * ProbeInterval
1188	//
1189	// This allows the timeout to scale properly with expected propagation
1190	// delay with a larger cluster size. The higher the multiplier, the longer
1191	// an inaccessible node is considered part of the cluster before declaring
1192	// it dead, giving that suspect node more time to refute if it is indeed
1193	// still alive.
1194	//
1195	// The default is: 4
1196	//
1197	// hcl: gossip_wan { suspicion_mult = int }
1198	GossipWANSuspicionMult int
1199
1200	// GossipWANRetransmitMult is the multiplier for the number of retransmissions
1201	// that are attempted for messages broadcasted over gossip. This
1202	// configuration only applies to WAN gossip communications. The actual
1203	// count of retransmissions is calculated using the formula:
1204	//
1205	//   Retransmits = RetransmitMult * log(N+1)
1206	//
1207	// This allows the retransmits to scale properly with cluster size. The
1208	// higher the multiplier, the more likely a failed broadcast is to converge
1209	// at the expense of increased bandwidth.
1210	//
1211	// The default is: 4
1212	//
1213	// hcl: gossip_wan { retransmit_mult = int }
1214	GossipWANRetransmitMult int
1215
1216	// ServerMode controls if this agent acts like a Consul server,
1217	// or merely as a client. Servers have more state, take part
1218	// in leader election, etc.
1219	//
1220	// hcl: server = (true|false)
1221	// flag: -server
1222	ServerMode bool
1223
1224	// ServerName is used with the TLS certificates to ensure the name we
1225	// provide matches the certificate.
1226	//
1227	// hcl: server_name = string
1228	ServerName string
1229
1230	// ServerPort is the port the RPC server will bind to.
1231	// The default is 8300.
1232	//
1233	// hcl: ports { server = int }
1234	ServerPort int
1235
1236	// Services contains the provided service definitions:
1237	//
1238	// hcl: services = [
1239	//   {
1240	//     id = string
1241	//     name = string
1242	//     tags = []string
1243	//     address = string
1244	//     check = { check definition }
1245	//     checks = [ { check definition}, ... ]
1246	//     token = string
1247	//     enable_tag_override = (true|false)
1248	//   },
1249	//   ...
1250	// ]
1251	Services []*structs.ServiceDefinition
1252
1253	// Minimum Session TTL.
1254	//
1255	// hcl: session_ttl_min = "duration"
1256	SessionTTLMin time.Duration
1257
1258	// SkipLeaveOnInt controls if Serf skips a graceful leave when
1259	// receiving the INT signal. Defaults false on clients, true on
1260	// servers. (reloadable)
1261	//
1262	// hcl: skip_leave_on_interrupt = (true|false)
1263	SkipLeaveOnInt bool
1264
1265	// StartJoinLAN is a list of addresses to attempt to join -wan when the
1266	// agent starts. If Serf is unable to communicate with any of these
1267	// addresses, then the agent will error and exit.
1268	//
1269	// hcl: start_join = []string
1270	// flag: -join string -join string
1271	StartJoinAddrsLAN []string
1272
1273	// StartJoinWAN is a list of addresses to attempt to join -wan when the
1274	// agent starts. If Serf is unable to communicate with any of these
1275	// addresses, then the agent will error and exit.
1276	//
1277	// hcl: start_join_wan = []string
1278	// flag: -join-wan string -join-wan string
1279	StartJoinAddrsWAN []string
1280
1281	// SyslogFacility is used to control where the syslog messages go
1282	// By default, goes to LOCAL0
1283	//
1284	// hcl: syslog_facility = string
1285	SyslogFacility string
1286
1287	// TLSCipherSuites is used to specify the list of supported ciphersuites.
1288	//
1289	// The values should be a list of the following values:
1290	//
1291	//   TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
1292	//   TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
1293	//   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
1294	//   TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
1295	//   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
1296	//   TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
1297	//   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
1298	//   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
1299	//   TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
1300	//   TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
1301	//   TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
1302	//   TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
1303	//   TLS_RSA_WITH_AES_128_GCM_SHA256
1304	//   TLS_RSA_WITH_AES_256_GCM_SHA384
1305	//   TLS_RSA_WITH_AES_128_CBC_SHA256
1306	//   TLS_RSA_WITH_AES_128_CBC_SHA
1307	//   TLS_RSA_WITH_AES_256_CBC_SHA
1308	//   TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
1309	//   TLS_RSA_WITH_3DES_EDE_CBC_SHA
1310	//   TLS_RSA_WITH_RC4_128_SHA
1311	//   TLS_ECDHE_RSA_WITH_RC4_128_SHA
1312	//   TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
1313	//
1314	// todo(fs): IMHO, we should also support the raw 0xNNNN values from
1315	// todo(fs): https://golang.org/pkg/crypto/tls/#pkg-constants
1316	// todo(fs): since they are standardized by IANA.
1317	//
1318	// hcl: tls_cipher_suites = []string
1319	TLSCipherSuites []uint16
1320
1321	// TLSMinVersion is used to set the minimum TLS version used for TLS
1322	// connections. Should be either "tls10", "tls11", or "tls12".
1323	//
1324	// hcl: tls_min_version = string
1325	TLSMinVersion string
1326
1327	// TLSPreferServerCipherSuites specifies whether to prefer the server's
1328	// cipher suite over the client cipher suites.
1329	//
1330	// hcl: tls_prefer_server_cipher_suites = (true|false)
1331	TLSPreferServerCipherSuites bool
1332
1333	// TaggedAddresses are used to publish a set of addresses for
1334	// for a node, which can be used by the remote agent. We currently
1335	// populate only the "wan" tag based on the SerfWan advertise address,
1336	// but this structure is here for possible future features with other
1337	// user-defined tags. The "wan" tag will be used by remote agents if
1338	// they are configured with TranslateWANAddrs set to true.
1339	//
1340	// hcl: tagged_addresses = map[string]string
1341	TaggedAddresses map[string]string
1342
1343	// TranslateWANAddrs controls whether or not Consul should prefer
1344	// the "wan" tagged address when doing lookups in remote datacenters.
1345	// See TaggedAddresses below for more details.
1346	//
1347	// hcl: translate_wan_addrs = (true|false)
1348	TranslateWANAddrs bool
1349
1350	// UIDir is the directory containing the Web UI resources.
1351	// If provided, the UI endpoints will be enabled.
1352	//
1353	// hcl: ui_dir = string
1354	// flag: -ui-dir string
1355	UIDir string
1356
1357	// UnixSocketGroup contains the group of the file permissions when
1358	// Consul binds to UNIX sockets.
1359	//
1360	// hcl: unix_sockets { group = string }
1361	UnixSocketGroup string
1362
1363	// UnixSocketMode contains the mode of the file permissions when
1364	// Consul binds to UNIX sockets.
1365	//
1366	// hcl: unix_sockets { mode = string }
1367	UnixSocketMode string
1368
1369	// UnixSocketUser contains the user of the file permissions when
1370	// Consul binds to UNIX sockets.
1371	//
1372	// hcl: unix_sockets { user = string }
1373	UnixSocketUser string
1374
1375	// VerifyIncoming is used to verify the authenticity of incoming
1376	// connections. This means that TCP requests are forbidden, only allowing
1377	// for TLS. TLS connections must match a provided certificate authority.
1378	// This can be used to force client auth.
1379	//
1380	// hcl: verify_incoming = (true|false)
1381	VerifyIncoming bool
1382
1383	// VerifyIncomingHTTPS is used to verify the authenticity of incoming HTTPS
1384	// connections. This means that TCP requests are forbidden, only allowing
1385	// for TLS. TLS connections must match a provided certificate authority.
1386	// This can be used to force client auth.
1387	//
1388	// hcl: verify_incoming_https = (true|false)
1389	VerifyIncomingHTTPS bool
1390
1391	// VerifyIncomingRPC is used to verify the authenticity of incoming RPC
1392	// connections. This means that TCP requests are forbidden, only allowing
1393	// for TLS. TLS connections must match a provided certificate authority.
1394	// This can be used to force client auth.
1395	//
1396	// hcl: verify_incoming_rpc = (true|false)
1397	VerifyIncomingRPC bool
1398
1399	// VerifyOutgoing is used to verify the authenticity of outgoing
1400	// connections. This means that TLS requests are used. TLS connections must
1401	// match a provided certificate authority. This is used to verify
1402	// authenticity of server nodes.
1403	//
1404	// hcl: verify_outgoing = (true|false)
1405	VerifyOutgoing bool
1406
1407	// VerifyServerHostname is used to enable hostname verification of servers.
1408	// This ensures that the certificate presented is valid for
1409	// server.<datacenter>.<domain>. This prevents a compromised client from
1410	// being restarted as a server, and then intercepting request traffic as
1411	// well as being added as a raft peer. This should be enabled by default
1412	// with VerifyOutgoing, but for legacy reasons we cannot break existing
1413	// clients.
1414	//
1415	// hcl: verify_server_hostname = (true|false)
1416	VerifyServerHostname bool
1417
1418	// Watches are used to monitor various endpoints and to invoke a
1419	// handler to act appropriately. These are managed entirely in the
1420	// agent layer using the standard APIs.
1421	//
1422	// See https://www.consul.io/docs/agent/watches.html for details.
1423	//
1424	// hcl: watches = [
1425	//   { type=string ... },
1426	//   { type=string ... },
1427	//   ...
1428	// ]
1429	//
1430	Watches []map[string]interface{}
1431}
1432
1433// IncomingHTTPSConfig returns the TLS configuration for HTTPS
1434// connections to consul.
1435func (c *RuntimeConfig) IncomingHTTPSConfig() (*tls.Config, error) {
1436	tc := &tlsutil.Config{
1437		VerifyIncoming:           c.VerifyIncoming || c.VerifyIncomingHTTPS,
1438		VerifyOutgoing:           c.VerifyOutgoing,
1439		CAFile:                   c.CAFile,
1440		CAPath:                   c.CAPath,
1441		CertFile:                 c.CertFile,
1442		KeyFile:                  c.KeyFile,
1443		NodeName:                 c.NodeName,
1444		ServerName:               c.ServerName,
1445		TLSMinVersion:            c.TLSMinVersion,
1446		CipherSuites:             c.TLSCipherSuites,
1447		PreferServerCipherSuites: c.TLSPreferServerCipherSuites,
1448	}
1449	return tc.IncomingTLSConfig()
1450}
1451
1452func (c *RuntimeConfig) apiAddresses(maxPerType int) (unixAddrs, httpAddrs, httpsAddrs []string) {
1453	if len(c.HTTPSAddrs) > 0 {
1454		for i, addr := range c.HTTPSAddrs {
1455			if maxPerType < 1 || i < maxPerType {
1456				httpsAddrs = append(httpsAddrs, addr.String())
1457			} else {
1458				break
1459			}
1460		}
1461	}
1462	if len(c.HTTPAddrs) > 0 {
1463		unix_count := 0
1464		http_count := 0
1465		for _, addr := range c.HTTPAddrs {
1466			switch addr.(type) {
1467			case *net.UnixAddr:
1468				if maxPerType < 1 || unix_count < maxPerType {
1469					unixAddrs = append(unixAddrs, addr.String())
1470					unix_count += 1
1471				}
1472			default:
1473				if maxPerType < 1 || http_count < maxPerType {
1474					httpAddrs = append(httpAddrs, addr.String())
1475					http_count += 1
1476				}
1477			}
1478		}
1479	}
1480
1481	return
1482}
1483
1484func (c *RuntimeConfig) ClientAddress() (unixAddr, httpAddr, httpsAddr string) {
1485	unixAddrs, httpAddrs, httpsAddrs := c.apiAddresses(0)
1486
1487	if len(unixAddrs) > 0 {
1488		unixAddr = "unix://" + unixAddrs[0]
1489	}
1490
1491	http_any := ""
1492	if len(httpAddrs) > 0 {
1493		for _, addr := range httpAddrs {
1494			host, port, err := net.SplitHostPort(addr)
1495			if err != nil {
1496				continue
1497			}
1498
1499			if host == "0.0.0.0" || host == "::" {
1500				if http_any == "" {
1501					if host == "0.0.0.0" {
1502						http_any = net.JoinHostPort("127.0.0.1", port)
1503					} else {
1504						http_any = net.JoinHostPort("::1", port)
1505					}
1506				}
1507				continue
1508			}
1509
1510			httpAddr = addr
1511			break
1512		}
1513
1514		if httpAddr == "" && http_any != "" {
1515			httpAddr = http_any
1516		}
1517	}
1518
1519	https_any := ""
1520	if len(httpsAddrs) > 0 {
1521		for _, addr := range httpsAddrs {
1522			host, port, err := net.SplitHostPort(addr)
1523			if err != nil {
1524				continue
1525			}
1526
1527			if host == "0.0.0.0" || host == "::" {
1528				if https_any == "" {
1529					if host == "0.0.0.0" {
1530						https_any = net.JoinHostPort("127.0.0.1", port)
1531					} else {
1532						https_any = net.JoinHostPort("::1", port)
1533					}
1534				}
1535				continue
1536			}
1537
1538			httpsAddr = addr
1539			break
1540		}
1541
1542		if httpsAddr == "" && https_any != "" {
1543			httpsAddr = https_any
1544		}
1545	}
1546
1547	return
1548}
1549
1550func (c *RuntimeConfig) APIConfig(includeClientCerts bool) (*api.Config, error) {
1551	cfg := &api.Config{
1552		Datacenter: c.Datacenter,
1553		TLSConfig:  api.TLSConfig{InsecureSkipVerify: !c.VerifyOutgoing},
1554	}
1555
1556	unixAddr, httpAddr, httpsAddr := c.ClientAddress()
1557
1558	if httpsAddr != "" {
1559		cfg.Address = httpsAddr
1560		cfg.Scheme = "https"
1561		cfg.TLSConfig.CAFile = c.CAFile
1562		cfg.TLSConfig.CAPath = c.CAPath
1563		if includeClientCerts {
1564			cfg.TLSConfig.CertFile = c.CertFile
1565			cfg.TLSConfig.KeyFile = c.KeyFile
1566		}
1567	} else if httpAddr != "" {
1568		cfg.Address = httpAddr
1569		cfg.Scheme = "http"
1570	} else if unixAddr != "" {
1571		cfg.Address = unixAddr
1572		// this should be ignored - however we are still talking http over a unix socket
1573		// so it makes sense to set it like this
1574		cfg.Scheme = "http"
1575	} else {
1576		return nil, fmt.Errorf("No suitable client address can be found")
1577	}
1578
1579	return cfg, nil
1580}
1581
1582// Sanitized returns a JSON/HCL compatible representation of the runtime
1583// configuration where all fields with potential secrets had their
1584// values replaced by 'hidden'. In addition, network addresses and
1585// time.Duration values are formatted to improve readability.
1586func (c *RuntimeConfig) Sanitized() map[string]interface{} {
1587	return sanitize("rt", reflect.ValueOf(c)).Interface().(map[string]interface{})
1588}
1589
1590// isSecret determines whether a field name represents a field which
1591// may contain a secret.
1592func isSecret(name string) bool {
1593	name = strings.ToLower(name)
1594	return strings.Contains(name, "key") || strings.Contains(name, "token") || strings.Contains(name, "secret")
1595}
1596
1597// cleanRetryJoin sanitizes the go-discover config strings key=val key=val...
1598// by scrubbing the individual key=val combinations.
1599func cleanRetryJoin(a string) string {
1600	var fields []string
1601	for _, f := range strings.Fields(a) {
1602		if isSecret(f) {
1603			kv := strings.SplitN(f, "=", 2)
1604			fields = append(fields, kv[0]+"=hidden")
1605		} else {
1606			fields = append(fields, f)
1607		}
1608	}
1609	return strings.Join(fields, " ")
1610}
1611
1612func sanitize(name string, v reflect.Value) reflect.Value {
1613	typ := v.Type()
1614	switch {
1615
1616	// check before isStruct and isPtr
1617	case isNetAddr(typ):
1618		if v.IsNil() {
1619			return reflect.ValueOf("")
1620		}
1621		switch x := v.Interface().(type) {
1622		case *net.TCPAddr:
1623			return reflect.ValueOf("tcp://" + x.String())
1624		case *net.UDPAddr:
1625			return reflect.ValueOf("udp://" + x.String())
1626		case *net.UnixAddr:
1627			return reflect.ValueOf("unix://" + x.String())
1628		case *net.IPAddr:
1629			return reflect.ValueOf(x.IP.String())
1630		default:
1631			return v
1632		}
1633
1634	// check before isNumber
1635	case isDuration(typ):
1636		x := v.Interface().(time.Duration)
1637		return reflect.ValueOf(x.String())
1638
1639	case isString(typ):
1640		if strings.HasPrefix(name, "RetryJoinLAN[") || strings.HasPrefix(name, "RetryJoinWAN[") {
1641			x := v.Interface().(string)
1642			return reflect.ValueOf(cleanRetryJoin(x))
1643		}
1644		if isSecret(name) {
1645			return reflect.ValueOf("hidden")
1646		}
1647		return v
1648
1649	case isNumber(typ) || isBool(typ):
1650		return v
1651
1652	case isPtr(typ):
1653		if v.IsNil() {
1654			return v
1655		}
1656		return sanitize(name, v.Elem())
1657
1658	case isStruct(typ):
1659		m := map[string]interface{}{}
1660		for i := 0; i < typ.NumField(); i++ {
1661			key := typ.Field(i).Name
1662			m[key] = sanitize(key, v.Field(i)).Interface()
1663		}
1664		return reflect.ValueOf(m)
1665
1666	case isArray(typ) || isSlice(typ):
1667		ma := make([]interface{}, 0)
1668		for i := 0; i < v.Len(); i++ {
1669			ma = append(ma, sanitize(fmt.Sprintf("%s[%d]", name, i), v.Index(i)).Interface())
1670		}
1671		return reflect.ValueOf(ma)
1672
1673	case isMap(typ):
1674		m := map[string]interface{}{}
1675		for _, k := range v.MapKeys() {
1676			key := k.String()
1677			m[key] = sanitize(key, v.MapIndex(k)).Interface()
1678		}
1679		return reflect.ValueOf(m)
1680
1681	default:
1682		return v
1683	}
1684}
1685
1686func isDuration(t reflect.Type) bool { return t == reflect.TypeOf(time.Second) }
1687func isMap(t reflect.Type) bool      { return t.Kind() == reflect.Map }
1688func isNetAddr(t reflect.Type) bool  { return t.Implements(reflect.TypeOf((*net.Addr)(nil)).Elem()) }
1689func isPtr(t reflect.Type) bool      { return t.Kind() == reflect.Ptr }
1690func isArray(t reflect.Type) bool    { return t.Kind() == reflect.Array }
1691func isSlice(t reflect.Type) bool    { return t.Kind() == reflect.Slice }
1692func isString(t reflect.Type) bool   { return t.Kind() == reflect.String }
1693func isStruct(t reflect.Type) bool   { return t.Kind() == reflect.Struct }
1694func isBool(t reflect.Type) bool     { return t.Kind() == reflect.Bool }
1695func isNumber(t reflect.Type) bool   { return isInt(t) || isUint(t) || isFloat(t) || isComplex(t) }
1696func isInt(t reflect.Type) bool {
1697	return t.Kind() == reflect.Int ||
1698		t.Kind() == reflect.Int8 ||
1699		t.Kind() == reflect.Int16 ||
1700		t.Kind() == reflect.Int32 ||
1701		t.Kind() == reflect.Int64
1702}
1703func isUint(t reflect.Type) bool {
1704	return t.Kind() == reflect.Uint ||
1705		t.Kind() == reflect.Uint8 ||
1706		t.Kind() == reflect.Uint16 ||
1707		t.Kind() == reflect.Uint32 ||
1708		t.Kind() == reflect.Uint64
1709}
1710func isFloat(t reflect.Type) bool { return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64 }
1711func isComplex(t reflect.Type) bool {
1712	return t.Kind() == reflect.Complex64 || t.Kind() == reflect.Complex128
1713}
1714