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  }