github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/command/agent/consul/connect_proxies.go (about) 1 package consul 2 3 import ( 4 "errors" 5 ) 6 7 // ConnectProxies implements SupportedProxiesAPI by using the Consul Agent API. 8 type ConnectProxies struct { 9 agentAPI AgentAPI 10 } 11 12 func NewConnectProxiesClient(agentAPI AgentAPI) *ConnectProxies { 13 return &ConnectProxies{ 14 agentAPI: agentAPI, 15 } 16 } 17 18 // Proxies returns a map of the supported proxies. The proxies are sorted from 19 // Consul with the most preferred version as the 0th element. 20 // 21 // If Consul is of a version that does not support the API, a nil map is returned 22 // with no error. 23 // 24 // If Consul cannot be reached an error is returned. 25 func (c *ConnectProxies) Proxies() (map[string][]string, error) { 26 // Based on the Consul query: 27 // $ curl -s localhost:8500/v1/agent/self | jq .xDS 28 // { 29 // "SupportedProxies": { 30 // "envoy": [ 31 // "1.15.0", 32 // "1.14.4", 33 // "1.13.4", 34 // "1.12.6" 35 // ] 36 // } 37 // } 38 39 self, err := c.agentAPI.Self() 40 if err != nil { 41 // this should not fail as long as we can reach consul 42 return nil, err 43 } 44 45 // If consul does not return a map of the supported consul proxies, it 46 // must be a version from before when the API was added in versions 47 // 1.9.0, 1.8.3, 1.7.7. Earlier versions in the same point release as well 48 // as all of 1.6.X support Connect, but not the supported proxies API. 49 // For these cases, we can simply fallback to the old version of Envoy 50 // that Nomad defaulted to back then - but not in this logic. Instead, 51 // return nil so we can choose what to do at the caller. 52 53 xds, xdsExists := self["xDS"] 54 if !xdsExists { 55 return nil, nil 56 } 57 58 proxies, proxiesExists := xds["SupportedProxies"] 59 if !proxiesExists { 60 return nil, nil 61 } 62 63 // convert interface{} to map[string]interface{} 64 65 intermediate, ok := proxies.(map[string]interface{}) 66 if !ok { 67 return nil, errors.New("unexpected SupportedProxies response format from Consul") 68 } 69 70 // convert map[string]interface{} to map[string][]string 71 72 result := make(map[string][]string, len(intermediate)) 73 for k, v := range intermediate { 74 75 // convert interface{} to []interface{} 76 77 if si, ok := v.([]interface{}); ok { 78 ss := make([]string, 0, len(si)) 79 for _, z := range si { 80 81 // convert interface{} to string 82 83 if s, ok := z.(string); ok { 84 ss = append(ss, s) 85 } 86 } 87 result[k] = ss 88 } 89 } 90 91 return result, nil 92 }