From 358e6c8f6ae07ffe413648e605a50cd2b6821e9f Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Tue, 10 Jul 2018 12:13:51 -0400 Subject: [PATCH] Pass around an API Config object and convert to env vars for the managed proxy --- agent/agent.go | 7 +++++ agent/config/runtime.go | 59 +++++++++++++++++++++++++++++++++++++++++ agent/proxy/manager.go | 7 +++++ api/api.go | 21 +++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/agent/agent.go b/agent/agent.go index e56f3e29f..b6b18c4bf 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -380,6 +380,13 @@ func (a *Agent) Start() error { a.logger.Printf("[WARN] agent: error restoring proxy state: %s", err) } } + + acfg, err := a.config.APIConfig(true) + if err != nil { + return err + } + a.proxyManager.APIConfig = acfg + go a.proxyManager.Run() } diff --git a/agent/config/runtime.go b/agent/config/runtime.go index 9674d14d5..d1fc41a48 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -9,6 +9,7 @@ import ( "time" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/tlsutil" "github.com/hashicorp/consul/types" @@ -1187,6 +1188,64 @@ func (c *RuntimeConfig) IncomingHTTPSConfig() (*tls.Config, error) { return tc.IncomingTLSConfig() } +func (c *RuntimeConfig) apiAddresses(maxPerType int) (unixAddrs, httpAddrs, httpsAddrs []string) { + if len(c.HTTPSAddrs) > 0 { + for i, addr := range c.HTTPSAddrs { + if i < maxPerType { + httpsAddrs = append(httpsAddrs, addr.String()) + } else { + break + } + } + } + if len(c.HTTPAddrs) > 0 { + unix_count := 0 + http_count := 0 + for _, addr := range c.HTTPAddrs { + net := addr.Network() + if net == "unix" && unix_count < maxPerType { + unixAddrs = append(unixAddrs, addr.String()) + unix_count += 1 + } else if net != "unix" && http_count < maxPerType { + httpAddrs = append(httpAddrs, addr.String()) + http_count += 1 + } + } + } + + return +} + +func (c *RuntimeConfig) APIConfig(includeClientCerts bool) (*api.Config, error) { + cfg := &api.Config{ + Datacenter: c.Datacenter, + TLSConfig: api.TLSConfig{InsecureSkipVerify: true}, + } + + unixAddrs, httpAddrs, httpsAddrs := c.apiAddresses(1) + + if len(httpsAddrs) > 0 { + cfg.Address = httpsAddrs[0] + cfg.Scheme = "https" + cfg.TLSConfig.CAFile = c.CAFile + cfg.TLSConfig.CAPath = c.CAPath + if includeClientCerts { + cfg.TLSConfig.CertFile = c.CertFile + cfg.TLSConfig.KeyFile = c.KeyFile + } + } else if len(httpAddrs) > 0 { + cfg.Address = httpAddrs[0] + cfg.Scheme = "http" + } else if len(unixAddrs) > 0 { + cfg.Address = "unix://" + unixAddrs[0] + cfg.Scheme = "http" + } else { + return nil, fmt.Errorf("No suitable client address can be found") + } + + return cfg, nil +} + // Sanitized returns a JSON/HCL compatible representation of the runtime // configuration where all fields with potential secrets had their // values replaced by 'hidden'. In addition, network addresses and diff --git a/agent/proxy/manager.go b/agent/proxy/manager.go index 65ffff738..39f076961 100644 --- a/agent/proxy/manager.go +++ b/agent/proxy/manager.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/consul/agent/local" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/api" "github.com/hashicorp/go-multierror" ) @@ -69,6 +70,9 @@ type Manager struct { // DataDir string + // Configuration information to tell the proxy how to talk to us + APIConfig *api.Config + // SnapshotPeriod is the duration between snapshots. This can be set // relatively low to ensure accuracy, because if the new snapshot matches // the last snapshot taken, no file will be written. Therefore, setting @@ -435,6 +439,9 @@ func (m *Manager) newProxy(mp *local.ManagedProxy) (Proxy, error) { // Pass in the environmental variables for the proxy process cmd.Env = os.Environ() + if m.APIConfig != nil { + cmd.Env = append(cmd.Env, m.APIConfig.GenerateEnv()...) + } // Build the daemon structure proxy.Command = &cmd diff --git a/api/api.go b/api/api.go index 6b359fef2..8e30a9683 100644 --- a/api/api.go +++ b/api/api.go @@ -405,6 +405,27 @@ func SetupTLSConfig(tlsConfig *TLSConfig) (*tls.Config, error) { return tlsClientConfig, nil } +func (c *Config) GenerateEnv() []string { + env := make([]string, 10) + + env[0] = fmt.Sprintf("%s=%s", HTTPAddrEnvName, c.Address) + env[1] = fmt.Sprintf("%s=%s", HTTPTokenEnvName, c.Token) + if c.HttpAuth != nil { + env[2] = fmt.Sprintf("%s=%s:%s", HTTPAuthEnvName, c.HttpAuth.Username, c.HttpAuth.Password) + } else { + env[2] = fmt.Sprintf("%s=", HTTPAuthEnvName) + } + env[3] = fmt.Sprintf("%s=%t", HTTPSSLEnvName, c.Scheme == "https") + env[4] = fmt.Sprintf("%s=%s", HTTPCAFile, c.TLSConfig.CAFile) + env[5] = fmt.Sprintf("%s=%s", HTTPCAPath, c.TLSConfig.CAPath) + env[6] = fmt.Sprintf("%s=%s", HTTPClientCert, c.TLSConfig.CertFile) + env[7] = fmt.Sprintf("%s=%s", HTTPClientKey, c.TLSConfig.KeyFile) + env[8] = fmt.Sprintf("%s=%s", HTTPTLSServerName, c.TLSConfig.Address) + env[9] = fmt.Sprintf("%s=%t", HTTPSSLVerifyEnvName, !c.TLSConfig.InsecureSkipVerify) + + return env +} + // Client provides a client to the Consul API type Client struct { config Config