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