93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
|
package consul
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
)
|
||
|
|
||
|
// ConnectProxies implements SupportedProxiesAPI 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
|
||
|
}
|