github.com/sl1pm4t/consul@v1.4.5-0.20190325224627-74c31c540f9c/agent/config/runtime.go (about)

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