1package config
2
3import (
4	"fmt"
5	"strconv"
6
7	"github.com/hashicorp/consul/agent/checks"
8	"github.com/hashicorp/consul/agent/consul"
9	"github.com/hashicorp/consul/version"
10	"github.com/hashicorp/raft"
11)
12
13// DefaultSource is the default agent configuration.
14// This needs to be merged first in the head.
15// todo(fs): The values are sourced from multiple sources.
16// todo(fs): IMO, this should be the definitive default for all configurable values
17// todo(fs): and whatever is in here should clobber every default value. Hence, no sourcing.
18func DefaultSource() Source {
19	cfg := consul.DefaultConfig()
20	serfLAN := cfg.SerfLANConfig.MemberlistConfig
21	serfWAN := cfg.SerfWANConfig.MemberlistConfig
22
23	// DEPRECATED (ACL-Legacy-Compat) - when legacy ACL support is removed these defaults
24	//   the acl_* config entries here should be transitioned to their counterparts in the
25	//   acl stanza for now we need to be able to detect the new entries not being set (not
26	//   just set to the defaults here) so that we can use the old entries. So the true
27	//   default still needs to reside in the original config values
28	return Source{
29		Name:   "default",
30		Format: "hcl",
31		Data: `
32		acl_default_policy = "allow"
33		acl_down_policy = "extend-cache"
34		acl_ttl = "30s"
35		acl = {
36			policy_ttl = "30s"
37		}
38		bind_addr = "0.0.0.0"
39		bootstrap = false
40		bootstrap_expect = 0
41		check_output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
42		check_update_interval = "5m"
43		client_addr = "127.0.0.1"
44		datacenter = "` + consul.DefaultDC + `"
45		default_query_time = "300s"
46		disable_coordinates = false
47		disable_host_node_id = true
48		disable_remote_exec = true
49		domain = "consul."
50		encrypt_verify_incoming = true
51		encrypt_verify_outgoing = true
52		log_level = "INFO"
53		max_query_time = "600s"
54		primary_gateways_interval = "30s"
55		protocol = ` + strconv.Itoa(consul.DefaultRPCProtocol) + `
56		retry_interval = "30s"
57		retry_interval_wan = "30s"
58		server = false
59		syslog_facility = "LOCAL0"
60		tls_min_version = "tls12"
61
62		// TODO (slackpad) - Until #3744 is done, we need to keep these
63		// in sync with agent/consul/config.go.
64		autopilot = {
65			cleanup_dead_servers = true
66			last_contact_threshold = "200ms"
67			max_trailing_logs = 250
68			server_stabilization_time = "10s"
69		}
70		gossip_lan = {
71			gossip_interval = "` + serfLAN.GossipInterval.String() + `"
72			gossip_nodes = ` + strconv.Itoa(serfLAN.GossipNodes) + `
73			retransmit_mult = ` + strconv.Itoa(serfLAN.RetransmitMult) + `
74			probe_interval = "` + serfLAN.ProbeInterval.String() + `"
75			probe_timeout = "` + serfLAN.ProbeTimeout.String() + `"
76			suspicion_mult = ` + strconv.Itoa(serfLAN.SuspicionMult) + `
77		}
78		gossip_wan = {
79			gossip_interval = "` + serfWAN.GossipInterval.String() + `"
80			gossip_nodes = ` + strconv.Itoa(serfLAN.GossipNodes) + `
81			retransmit_mult = ` + strconv.Itoa(serfLAN.RetransmitMult) + `
82			probe_interval = "` + serfWAN.ProbeInterval.String() + `"
83			probe_timeout = "` + serfWAN.ProbeTimeout.String() + `"
84			suspicion_mult = ` + strconv.Itoa(serfWAN.SuspicionMult) + `
85		}
86		dns_config = {
87			allow_stale = true
88			a_record_limit = 0
89			udp_answer_limit = 3
90			max_stale = "87600h"
91			recursor_timeout = "2s"
92		}
93		limits = {
94			http_max_conns_per_client = 200
95			https_handshake_timeout = "5s"
96			rpc_handshake_timeout = "5s"
97			rpc_rate = -1
98			rpc_max_burst = 1000
99			rpc_max_conns_per_client = 100
100			kv_max_value_size = ` + strconv.FormatInt(raft.SuggestedMaxDataSize, 10) + `
101			txn_max_req_len = ` + strconv.FormatInt(raft.SuggestedMaxDataSize, 10) + `
102		}
103		performance = {
104			leave_drain_time = "5s"
105			raft_multiplier = ` + strconv.Itoa(int(consul.DefaultRaftMultiplier)) + `
106			rpc_hold_timeout = "7s"
107		}
108		ports = {
109			dns = 8600
110			http = 8500
111			https = -1
112			grpc = -1
113			serf_lan = ` + strconv.Itoa(consul.DefaultLANSerfPort) + `
114			serf_wan = ` + strconv.Itoa(consul.DefaultWANSerfPort) + `
115			server = ` + strconv.Itoa(consul.DefaultRPCPort) + `
116			proxy_min_port = 20000
117			proxy_max_port = 20255
118			sidecar_min_port = 21000
119			sidecar_max_port = 21255
120			expose_min_port = 21500
121			expose_max_port = 21755
122		}
123		telemetry = {
124			metrics_prefix = "consul"
125			filter_default = true
126		}
127
128	`,
129	}
130}
131
132// DevSource is the additional default configuration for dev mode.
133// This should be merged in the head after the default configuration.
134func DevSource() Source {
135	return Source{
136		Name:   "dev",
137		Format: "hcl",
138		Data: `
139		bind_addr = "127.0.0.1"
140		disable_anonymous_signature = true
141		disable_keyring_file = true
142		enable_debug = true
143		ui = true
144		log_level = "DEBUG"
145		server = true
146
147		gossip_lan = {
148			gossip_interval = "100ms"
149			probe_interval = "100ms"
150			probe_timeout = "100ms"
151			suspicion_mult = 3
152		}
153		gossip_wan = {
154			gossip_interval = "100ms"
155			probe_interval = "100ms"
156			probe_timeout = "100ms"
157			suspicion_mult = 3
158		}
159		connect = {
160			enabled = true
161		}
162		performance = {
163			raft_multiplier = 1
164		}
165		ports = {
166			grpc = 8502
167		}
168	`,
169	}
170}
171
172// NonUserSource contains the values the user cannot configure.
173// This needs to be merged in the tail.
174func NonUserSource() Source {
175	return Source{
176		Name:   "non-user",
177		Format: "hcl",
178		Data: `
179		acl = {
180			disabled_ttl = "120s"
181		}
182		check_deregister_interval_min = "1m"
183		check_reap_interval = "30s"
184		ae_interval = "1m"
185		sync_coordinate_rate_target = 64
186		sync_coordinate_interval_min = "15s"
187
188		# segment_limit is the maximum number of network segments that may be declared.
189		segment_limit = 64
190
191		# SegmentNameLimit is the maximum segment name length.
192		segment_name_limit = 64
193
194		connect = {
195			# 0s causes the value to be ignored and operate without capping
196			# the max time before leaf certs can be generated after a roots change.
197			test_ca_leaf_root_change_spread = "0s"
198		}
199	`,
200	}
201}
202
203// VersionSource creates a config source for the version parameters.
204// This should be merged in the tail since these values are not
205// user configurable.
206func VersionSource(rev, ver, verPre string) Source {
207	return Source{
208		Name:   "version",
209		Format: "hcl",
210		Data:   fmt.Sprintf(`revision = %q version = %q version_prerelease = %q`, rev, ver, verPre),
211	}
212}
213
214// DefaultVersionSource returns the version config source for the embedded
215// version numbers.
216func DefaultVersionSource() Source {
217	return VersionSource(version.GitCommit, version.Version, version.VersionPrerelease)
218}
219
220// DefaultConsulSource returns the default configuration for the consul agent.
221// This should be merged in the tail since these values are not user configurable.
222func DefaultConsulSource() Source {
223	cfg := consul.DefaultConfig()
224	raft := cfg.RaftConfig
225	return Source{
226		Name:   "consul",
227		Format: "hcl",
228		Data: `
229		consul = {
230			coordinate = {
231				update_batch_size = ` + strconv.Itoa(cfg.CoordinateUpdateBatchSize) + `
232				update_max_batches = ` + strconv.Itoa(cfg.CoordinateUpdateMaxBatches) + `
233				update_period = "` + cfg.CoordinateUpdatePeriod.String() + `"
234			}
235			raft = {
236				election_timeout = "` + raft.ElectionTimeout.String() + `"
237				heartbeat_timeout = "` + raft.HeartbeatTimeout.String() + `"
238				leader_lease_timeout = "` + raft.LeaderLeaseTimeout.String() + `"
239			}
240			server = {
241				health_interval = "` + cfg.ServerHealthInterval.String() + `"
242			}
243		}
244	`,
245	}
246}
247
248// DevConsulSource returns the consul agent configuration for the dev mode.
249// This should be merged in the tail after the DefaultConsulSource.
250func DevConsulSource() Source {
251	return Source{
252		Name:   "consul-dev",
253		Format: "hcl",
254		Data: `
255		consul = {
256			coordinate = {
257				update_period = "100ms"
258			}
259			raft = {
260				election_timeout = "52ms"
261				heartbeat_timeout = "35ms"
262				leader_lease_timeout = "20ms"
263			}
264			server = {
265				health_interval = "10ms"
266			}
267		}
268	`,
269	}
270}
271
272func DefaultRuntimeConfig(hcl string) *RuntimeConfig {
273	b, err := NewBuilder(BuilderOpts{HCL: []string{hcl}})
274	if err != nil {
275		panic(err)
276	}
277	rt, err := b.BuildAndValidate()
278	if err != nil {
279		panic(err)
280	}
281	return &rt
282}
283