1package envoy
2
3// BootstrapTplArgs is the set of arguments that may be interpolated into the
4// Envoy bootstrap template.
5type BootstrapTplArgs struct {
6	GRPC
7
8	// ProxyCluster is the cluster name for the the Envoy `node` specification and
9	// is typically the same as the ProxyID.
10	ProxyCluster string
11
12	// ProxyID is the ID of the proxy service instance as registered with the
13	// local Consul agent. This must be used as the Envoy `node.id` in order for
14	// the agent to deliver the correct configuration.
15	ProxyID string
16
17	// AgentCAPEM is the CA to use to verify the local agent gRPC service if
18	// TLS is enabled.
19	AgentCAPEM string
20
21	// AdminAccessLogPath The path to write the access log for the
22	// administration server. If no access log is desired specify
23	// "/dev/null". By default it will use "/dev/null".
24	AdminAccessLogPath string
25
26	// AdminBindAddress is the address the Envoy admin server should bind to.
27	AdminBindAddress string
28
29	// AdminBindPort is the port the Envoy admin server should bind to.
30	AdminBindPort string
31
32	// LocalAgentClusterName is the name reserved for the local Consul agent gRPC
33	// service and is expected to be used for that purpose.
34	LocalAgentClusterName string
35
36	// Token is the Consul ACL token provided which is required to make gRPC
37	// discovery requests. If non-empty, this must be configured as the gRPC
38	// service "initial_metadata" with the key "x-consul-token" in order to
39	// authorize the discovery streaming RPCs.
40	Token string
41
42	// StaticClustersJSON is JSON string, each is expected to be a valid Cluster
43	// definition. They are appended to the "static_resources.clusters" list. Note
44	// that cluster names should be chosen in such a way that they won't collide
45	// with service names since we use plain service names as cluster names in xDS
46	// to make metrics population simpler and cluster names mush be unique. See
47	// https://www.envoyproxy.io/docs/envoy/v1.9.0/api-v2/api/v2/cds.proto.
48	StaticClustersJSON string
49
50	// StaticListenersJSON is a JSON string containing zero or more Listener
51	// definitions. They are appended to the "static_resources.listeners" list. A
52	// single listener should be given as a plain object, if more than one is to
53	// be added, they should be separated by a comma suitable for direct injection
54	// into a JSON array.
55	// See https://www.envoyproxy.io/docs/envoy/v1.9.0/api-v2/api/v2/lds.proto.
56	StaticListenersJSON string
57
58	// StatsSinksJSON is a JSON string containing an array in the right format
59	// to be rendered as the body of the `stats_sinks` field at the top level of
60	// the bootstrap config. It's format may vary based on Envoy version used. See
61	// https://www.envoyproxy.io/docs/envoy/v1.9.0/api-v2/config/metrics/v2/stats.proto#config-metrics-v2-statssink.
62	StatsSinksJSON string
63
64	// StatsConfigJSON is a JSON string containing an object in the right format
65	// to be rendered as the body of the `stats_config` field at the top level of
66	// the bootstrap config. It's format may vary based on Envoy version used. See
67	// https://www.envoyproxy.io/docs/envoy/v1.9.0/api-v2/config/metrics/v2/stats.proto#envoy-api-msg-config-metrics-v2-statsconfig.
68	StatsConfigJSON string
69
70	// StatsFlushInterval is the time duration between Envoy stats flushes. It is
71	// in proto3 "duration" string format for example "1.12s" See
72	// https://developers.google.com/protocol-buffers/docs/proto3#json and
73	// https://www.envoyproxy.io/docs/envoy/v1.9.0/api-v2/config/bootstrap/v2/bootstrap.proto#bootstrap
74	StatsFlushInterval string
75
76	// TracingConfigJSON is a JSON string containing an object in the right format
77	// to be rendered as the body of the `tracing` field at the top level of
78	// the bootstrap config. It's format may vary based on Envoy version used.
79	// See https://www.envoyproxy.io/docs/envoy/v1.9.0/api-v2/config/trace/v2/trace.proto.
80	TracingConfigJSON string
81
82	// Namespace is the Consul Enterprise Namespace of the proxy service instance as
83	// registered with the Consul agent.
84	Namespace string
85
86	// EnvoyVersion is the envoy version, which is necessary to generate the
87	// correct configuration.
88	EnvoyVersion string
89}
90
91// GRPC settings used in the bootstrap template.
92type GRPC struct {
93	// AgentAddress is the IP address of the local agent where the proxy instance
94	// is registered.
95	AgentAddress string
96
97	// AgentPort is the gRPC port exposed on the local agent.
98	AgentPort string
99
100	// AgentTLS is true if the local agent gRPC service should be accessed over
101	// TLS.
102	AgentTLS bool
103
104	// AgentSocket is the path to a Unix Socket for communicating with the
105	// local agent's gRPC endpoint. Disabled if the empty (the default),
106	// but overrides AgentAddress and AgentPort if set.
107	AgentSocket string
108}
109
110const bootstrapTemplate = `{
111  "admin": {
112    "access_log_path": "{{ .AdminAccessLogPath }}",
113    "address": {
114      "socket_address": {
115        "address": "{{ .AdminBindAddress }}",
116        "port_value": {{ .AdminBindPort }}
117      }
118    }
119  },
120  "node": {
121    "cluster": "{{ .ProxyCluster }}",
122    "id": "{{ .ProxyID }}",
123    "metadata": {
124      "namespace": "{{if ne .Namespace ""}}{{ .Namespace }}{{else}}default{{end}}",
125      "envoy_version": "{{ .EnvoyVersion }}"
126    }
127  },
128  "static_resources": {
129    "clusters": [
130      {
131        "name": "{{ .LocalAgentClusterName }}",
132        "connect_timeout": "1s",
133        "type": "STATIC",
134        {{- if .AgentTLS -}}
135        "tls_context": {
136          "common_tls_context": {
137            "validation_context": {
138              "trusted_ca": {
139                "inline_string": "{{ .AgentCAPEM }}"
140              }
141            }
142          }
143        },
144        {{- end }}
145        "http2_protocol_options": {},
146        "hosts": [
147	  {{- if .AgentSocket -}}
148          {
149            "pipe": {
150              "path": "{{ .AgentSocket }}"
151            }
152          }
153	  {{- else -}}
154          {
155            "socket_address": {
156              "address": "{{ .AgentAddress }}",
157              "port_value": {{ .AgentPort }}
158            }
159          }
160	  {{- end -}}
161        ]
162      }
163      {{- if .StaticClustersJSON -}}
164      ,
165      {{ .StaticClustersJSON }}
166      {{- end }}
167    ]{{- if .StaticListenersJSON -}}
168    ,
169    "listeners": [
170      {{ .StaticListenersJSON }}
171    ]
172    {{- end }}
173  },
174  {{- if .StatsSinksJSON }}
175  "stats_sinks": {{ .StatsSinksJSON }},
176  {{- end }}
177  {{- if .StatsConfigJSON }}
178  "stats_config": {{ .StatsConfigJSON }},
179  {{- end }}
180  {{- if .StatsFlushInterval }}
181  "stats_flush_interval": "{{ .StatsFlushInterval }}",
182  {{- end }}
183  {{- if .TracingConfigJSON }}
184  "tracing": {{ .TracingConfigJSON }},
185  {{- end }}
186  "dynamic_resources": {
187    "lds_config": { "ads": {} },
188    "cds_config": { "ads": {} },
189    "ads_config": {
190      "api_type": "GRPC",
191      "set_node_on_first_message_only": true,
192      "grpc_services": {
193        "initial_metadata": [
194          {
195            "key": "x-consul-token",
196            "value": "{{ .Token }}"
197          }
198        ],
199        "envoy_grpc": {
200          "cluster_name": "{{ .LocalAgentClusterName }}"
201        }
202      }
203    }
204  {{- if ne .EnvoyVersion "1.10.0"}}
205  },
206  "layered_runtime":{
207    "layers": [
208      {
209        "name": "static_layer",
210        "static_layer": {
211          "envoy.deprecated_features:envoy.api.v2.Cluster.tls_context": true,
212          "envoy.deprecated_features:envoy.config.trace.v2.ZipkinConfig.HTTP_JSON_V1": true,
213          "envoy.deprecated_features:envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager.Tracing.operation_name": true
214        }
215      }
216    ]
217  {{- end }}
218  }
219}
220`
221