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