Files
nomad/command/agent/consul/connect_proxies.go
Tim Gross ac56855f07 consul: add multi-cluster support to client constructors (#18624)
When agents start, they create a shared Consul client that is then wrapped as
various interfaces for testability, and used in constructing the Nomad client
and server. The interfaces that support workload services (rather than the Nomad
agent itself) need to support multiple Consul clusters for Nomad
Enterprise. Update these interfaces to be factory functions that return the
Consul client for a given cluster name. Update the `ServiceClient` to split
workload updates between clusters by creating a wrapper around all the clients
that delegates to the cluster-specific `ServiceClient`.

Ref: https://github.com/hashicorp/team-nomad/issues/404
2023-10-17 13:46:49 -04:00

97 lines
2.4 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package consul
import (
"errors"
)
// ConnectProxies implements the client/consul.SupportedProxiesAPI interface by
// using the Consul Agent API.
type ConnectProxies struct {
agentAPI AgentAPI
}
func NewConnectProxiesClient(agentAPI AgentAPI) *ConnectProxies {
return &ConnectProxies{
agentAPI: agentAPI,
}
}
// Proxies returns a map of the supported proxies. The proxies are sorted from
// Consul with the most preferred version as the 0th element.
//
// If Consul is of a version that does not support the API, a nil map is returned
// with no error.
//
// If Consul cannot be reached an error is returned.
func (c *ConnectProxies) Proxies() (map[string][]string, error) {
// Based on the Consul query:
// $ curl -s localhost:8500/v1/agent/self | jq .xDS
// {
// "SupportedProxies": {
// "envoy": [
// "1.15.0",
// "1.14.4",
// "1.13.4",
// "1.12.6"
// ]
// }
// }
self, err := c.agentAPI.Self()
if err != nil {
// this should not fail as long as we can reach consul
return nil, err
}
// If consul does not return a map of the supported consul proxies, it
// must be a version from before when the API was added in versions
// 1.9.0, 1.8.3, 1.7.7. Earlier versions in the same point release as well
// as all of 1.6.X support Connect, but not the supported proxies API.
// For these cases, we can simply fallback to the old version of Envoy
// that Nomad defaulted to back then - but not in this logic. Instead,
// return nil so we can choose what to do at the caller.
xds, xdsExists := self["xDS"]
if !xdsExists {
return nil, nil
}
proxies, proxiesExists := xds["SupportedProxies"]
if !proxiesExists {
return nil, nil
}
// convert interface{} to map[string]interface{}
intermediate, ok := proxies.(map[string]interface{})
if !ok {
return nil, errors.New("unexpected SupportedProxies response format from Consul")
}
// convert map[string]interface{} to map[string][]string
result := make(map[string][]string, len(intermediate))
for k, v := range intermediate {
// convert interface{} to []interface{}
if si, ok := v.([]interface{}); ok {
ss := make([]string, 0, len(si))
for _, z := range si {
// convert interface{} to string
if s, ok := z.(string); ok {
ss = append(ss, s)
}
}
result[k] = ss
}
}
return result, nil
}