Skip to content

Commit f76bdcc

Browse files
authored
NET-59: Generate bootstrap config and run Envoy (#2)
This is a minimum viable implementation of the consul-dataplane process that configures and runs an Envoy proxy. It has a few major limitations: 1. Only static ACL tokens (i.e. not auth-methods) are supported. 2. In lieu of the ADS proxy we will eventually provide, Envoy is configured to connect directly to the Consul server. 3. If Envoy crashes `consul-dataplane` will exit too rather than attempting to restart it. The envoy package implements a simple wrapper around the Envoy process. It writes the given configuration to a FIFO pipe (a pattern established in hashicorp/consul#5964), starts the process, and notifies callers via the `Exited` channel if the process exits unexpectedly. This is unit tested using a dummy program called fake-envoy which writes its received arguments and configuration to disk for the Go tests to verify. As there's a fair amount of complex logic, regexes, etc. in our bootstrap configuration already implemented by the `consul connect envoy` command, we're borrowing the relevant files from Consul repo (see the copy-bootstrap-config make target). Eventually, this command will be removed from Consul and these files will only belong in this repository. We're unit(ish?) testing this using a combination of golden files and checking the configuration is valid by running Envoy in "validate mode" (on demand when you run the tests with the -validate flag). As ingress gateways may have no listeners configured, `consul connect envoy` creates one with a /ready HTTP endpoint that can be used by checks - it does this based on the -address flag. In consul-dataplane you can opt-in to this behavior by passing the -envoy-ready-bind-address and -envoy-ready-bind-port flags. This works regardless of the service kind.
1 parent 165f52a commit f76bdcc

File tree

23 files changed

+4414
-119
lines changed

23 files changed

+4414
-119
lines changed

Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
BOOTSTRAP_PACKAGE_DIR=internal/bootstrap
2+
3+
.PHONY: copy-bootstrap-config
4+
5+
# Our Envoy bootstrap config generation contains a fair amount of logic that
6+
# was already implemented for the `consul connect envoy` command. Eventually,
7+
# this command will go away and be replaced by consul-dataplane, but for now
8+
# we copy the files from the Consul repo, and do a small amount of processing
9+
# to rename the package and remove a dependency on the Consul api module.
10+
copy-bootstrap-config:
11+
for file in bootstrap_config.go bootstrap_config_test.go bootstrap_tpl.go; do \
12+
curl --fail https://raw.githubusercontent.com/hashicorp/consul/main/command/connect/envoy/$$file | \
13+
sed 's/package envoy/package bootstrap/' | \
14+
sed '/github.com\/hashicorp\/consul\/api/d' | \
15+
sed 's/api.IntentionDefaultNamespace/"default"/g' | \
16+
sed '1s:^:// Code generated by make copy-bootstrap-config. DO NOT EDIT.\n:' | \
17+
gofmt \
18+
> $(BOOTSTRAP_PACKAGE_DIR)/$$file; \
19+
done

cmd/consul-dataplane/main.go

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"flag"
66
"log"
7+
"os"
8+
"os/signal"
79
"strings"
810

911
"github.com/hashicorp/consul-dataplane/pkg/consuldp"
@@ -12,8 +14,24 @@ import (
1214
var (
1315
addresses string
1416
grpcPort int
15-
logLevel string
16-
logJSON bool
17+
18+
logLevel string
19+
logJSON bool
20+
21+
nodeName string
22+
nodeID string
23+
serviceID string
24+
namespace string
25+
partition string
26+
27+
token string
28+
29+
useCentralTelemetryConfig bool
30+
31+
adminBindAddr string
32+
adminBindPort int
33+
readyBindAddr string
34+
readyBindPort int
1735
)
1836

1937
func init() {
@@ -24,12 +42,27 @@ func init() {
2442
" b) on failure - exit with a non-zero code and optionally print an error message of upto 1024 bytes to stderr.\n"+
2543
" Refer to https://github.com/hashicorp/go-netaddrs#summary for more details and examples.")
2644

27-
flag.IntVar(&grpcPort, "grpc-port", 8502, "gRPC port on Consul servers")
45+
flag.IntVar(&grpcPort, "grpc-port", 8502, "gRPC port on Consul servers.")
2846

2947
flag.StringVar(&logLevel, "log-level", "info", "Log level of the messages to print. "+
3048
"Available log levels are \"trace\", \"debug\", \"info\", \"warn\", and \"error\".")
3149

3250
flag.BoolVar(&logJSON, "log-json", false, "Controls consul-dataplane logging in JSON format. By default this is false.")
51+
52+
flag.StringVar(&nodeName, "service-node-name", "", "The name of the node to which the proxy service instance is registered.")
53+
flag.StringVar(&nodeID, "service-node-id", "", "The ID of the node to which the proxy service instance is registered.")
54+
flag.StringVar(&serviceID, "proxy-service-id", "", "The proxy service instance's ID.")
55+
flag.StringVar(&namespace, "service-namespace", "", "The Consul Enterprise namespace in which the proxy service instance is registered.")
56+
flag.StringVar(&partition, "service-partition", "", "The Consul Enterprise partition in which the proxy service instance is registered.")
57+
58+
flag.StringVar(&token, "static-token", "", "The ACL token used to authenticate requests to Consul servers (when -login-method is set to static).")
59+
60+
flag.BoolVar(&useCentralTelemetryConfig, "telemetry-use-central-config", true, "Controls whether the proxy will apply the central telemetry configuration.")
61+
62+
flag.StringVar(&adminBindAddr, "envoy-admin-bind-address", "127.0.0.1", "The address on which the Envoy admin server will be available.")
63+
flag.IntVar(&adminBindPort, "envoy-admin-bind-port", 19000, "The port on which the Envoy admin server will be available.")
64+
flag.StringVar(&readyBindAddr, "envoy-ready-bind-address", "", "The address on which Envoy's readiness probe will be available.")
65+
flag.IntVar(&readyBindPort, "envoy-ready-bind-port", 0, "The port on which Envoy's readiness probe will be available.")
3366
}
3467

3568
// validateFlags performs semantic validation of the flag values
@@ -48,19 +81,53 @@ func main() {
4881
validateFlags()
4982

5083
consuldpCfg := &consuldp.Config{
51-
Consul: &consuldp.ConsulConfig{Addresses: addresses, GRPCPort: grpcPort},
84+
Consul: &consuldp.ConsulConfig{
85+
Addresses: addresses,
86+
GRPCPort: grpcPort,
87+
Credentials: &consuldp.CredentialsConfig{
88+
Static: &consuldp.StaticCredentialsConfig{
89+
Token: token,
90+
},
91+
},
92+
},
93+
Service: &consuldp.ServiceConfig{
94+
NodeName: nodeName,
95+
NodeID: nodeID,
96+
ServiceID: serviceID,
97+
Namespace: namespace,
98+
Partition: partition,
99+
},
52100
Logging: &consuldp.LoggingConfig{
53101
Name: "consul-dataplane",
54102
LogLevel: strings.ToUpper(logLevel),
55103
LogJSON: logJSON,
56104
},
105+
Telemetry: &consuldp.TelemetryConfig{
106+
UseCentralConfig: useCentralTelemetryConfig,
107+
},
108+
Envoy: &consuldp.EnvoyConfig{
109+
AdminBindAddress: adminBindAddr,
110+
AdminBindPort: adminBindPort,
111+
ReadyBindAddress: readyBindAddr,
112+
ReadyBindPort: readyBindPort,
113+
},
57114
}
58115
consuldpInstance, err := consuldp.NewConsulDP(consuldpCfg)
59116
if err != nil {
60117
log.Fatal(err)
61118
}
62-
// TODO: Pass cancellable context
63-
err = consuldpInstance.Run(context.Background())
119+
120+
ctx, cancel := context.WithCancel(context.Background())
121+
122+
sigCh := make(chan os.Signal, 1)
123+
signal.Notify(sigCh, os.Interrupt)
124+
125+
go func() {
126+
<-sigCh
127+
cancel()
128+
}()
129+
130+
err = consuldpInstance.Run(ctx)
64131
if err != nil {
65132
log.Fatal(err)
66133
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.18
55
require (
66
github.com/hashicorp/go-hclog v1.2.2
77
github.com/hashicorp/go-netaddrs v0.0.0-20220509001840-90ed9d26ec46
8+
github.com/mitchellh/mapstructure v1.5.0
89
github.com/stretchr/testify v1.8.0
910
google.golang.org/grpc v1.48.0
1011
google.golang.org/protobuf v1.28.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb
6060
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
6161
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
6262
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
63+
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
64+
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
6365
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6466
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6567
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=

0 commit comments

Comments
 (0)