github.com/sl1pm4t/consul@v1.4.5-0.20190325224627-74c31c540f9c/agent/xds/endpoints.go (about) 1 package xds 2 3 import ( 4 "errors" 5 6 envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" 7 envoycore "github.com/envoyproxy/go-control-plane/envoy/api/v2/core" 8 envoyendpoint "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint" 9 "github.com/gogo/protobuf/proto" 10 11 "github.com/hashicorp/consul/agent/proxycfg" 12 "github.com/hashicorp/consul/agent/structs" 13 "github.com/hashicorp/consul/api" 14 ) 15 16 // endpointsFromSnapshot returns the xDS API representation of the "endpoints" 17 // (upstream instances) in the snapshot. 18 func endpointsFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) { 19 if cfgSnap == nil { 20 return nil, errors.New("nil config given") 21 } 22 resources := make([]proto.Message, 0, len(cfgSnap.UpstreamEndpoints)) 23 for id, endpoints := range cfgSnap.UpstreamEndpoints { 24 la := makeLoadAssignment(id, endpoints) 25 resources = append(resources, la) 26 } 27 return resources, nil 28 } 29 30 func makeEndpoint(clusterName, host string, port int) envoyendpoint.LbEndpoint { 31 return envoyendpoint.LbEndpoint{ 32 Endpoint: &envoyendpoint.Endpoint{ 33 Address: makeAddressPtr(host, port), 34 }, 35 } 36 } 37 38 func makeLoadAssignment(clusterName string, endpoints structs.CheckServiceNodes) *envoy.ClusterLoadAssignment { 39 es := make([]envoyendpoint.LbEndpoint, 0, len(endpoints)) 40 for _, ep := range endpoints { 41 addr := ep.Service.Address 42 if addr == "" { 43 addr = ep.Node.Address 44 } 45 healthStatus := envoycore.HealthStatus_HEALTHY 46 weight := 1 47 if ep.Service.Weights != nil { 48 weight = ep.Service.Weights.Passing 49 } 50 51 for _, chk := range ep.Checks { 52 if chk.Status == api.HealthCritical { 53 // This can't actually happen now because health always filters critical 54 // but in the future it may not so set this correctly! 55 healthStatus = envoycore.HealthStatus_UNHEALTHY 56 } 57 if chk.Status == api.HealthWarning && ep.Service.Weights != nil { 58 weight = ep.Service.Weights.Warning 59 } 60 } 61 // Make weights fit Envoy's limits. A zero weight means that either Warning 62 // (likely) or Passing (weirdly) weight has been set to 0 effectively making 63 // this instance unhealthy and should not be sent traffic. 64 if weight < 1 { 65 healthStatus = envoycore.HealthStatus_UNHEALTHY 66 weight = 1 67 } 68 if weight > 128 { 69 weight = 128 70 } 71 es = append(es, envoyendpoint.LbEndpoint{ 72 Endpoint: &envoyendpoint.Endpoint{ 73 Address: makeAddressPtr(addr, ep.Service.Port), 74 }, 75 HealthStatus: healthStatus, 76 LoadBalancingWeight: makeUint32Value(weight), 77 }) 78 } 79 return &envoy.ClusterLoadAssignment{ 80 ClusterName: clusterName, 81 Endpoints: []envoyendpoint.LocalityLbEndpoints{{ 82 LbEndpoints: es, 83 }}, 84 } 85 }