diff --git a/envoy.jsonnet b/envoy.jsonnet index c2b8c15b..df348949 100644 --- a/envoy.jsonnet +++ b/envoy.jsonnet @@ -369,7 +369,7 @@ function(services=import 'testdata/services.json', }, }, }, - metadata: {}, + [if 'uid' in endpoint then 'metadata']: { filter_metadata: { mixer: { 'destination.uid': endpoint.uid } } }, } for endpoint in instances[service_name]], }] else [], } diff --git a/kube/controller.go b/kube/controller.go index 1b713f26..851e15ae 100644 --- a/kube/controller.go +++ b/kube/controller.go @@ -202,12 +202,16 @@ func (c *Controller) Instances() map[string][]model.Endpoint { for _, ss := range ep.Subsets { for _, ea := range ss.Addresses { for _, port := range ss.Ports { - key := svc + ":" + port.Name - out[key] = append(out[key], model.Endpoint{ + endpoint := model.Endpoint{ IP: ea.IP, Port: int(port.Port), - }) - + } + pod, exists := c.pods.getPodByIP(ea.IP) + if exists { + endpoint.UID = pod.Namespace + "/" + pod.Name + } + key := svc + ":" + port.Name + out[key] = append(out[key], endpoint) } } } diff --git a/model/service.go b/model/service.go index dd32c399..97942aa9 100644 --- a/model/service.go +++ b/model/service.go @@ -141,6 +141,9 @@ type Endpoint struct { IP string `json:"ip"` Port int `json:"port"` Protocol Protocol `json:"protocol"` + + // Used by EDS + UID string } // Instance is a workload descriptor @@ -238,89 +241,6 @@ func (s *Service) External() bool { return s.ExternalName != "" } -// Key generates a unique string referencing service instances for a given port and labels. -// The separator character must be exclusive to the regular expressions allowed in the -// service declaration. -func (s *Service) Key(port *Port, tag Labels) string { - // TODO: check port is non nil and membership of port in service - return ServiceKey(s.Hostname, PortList{port}, LabelsCollection{tag}) -} - -// ServiceKey generates a service key for a collection of ports and labels -func ServiceKey(hostname string, servicePorts PortList, labelsList LabelsCollection) string { - // example: name.namespace|http|env=prod;env=test,version=my-v1 - var buffer bytes.Buffer - buffer.WriteString(hostname) - np := len(servicePorts) - nt := len(labelsList) - - if nt == 1 && labelsList[0] == nil { - nt = 0 - } - - if np == 0 && nt == 0 { - return buffer.String() - } else if np == 1 && nt == 0 && servicePorts[0].Name == "" { - return buffer.String() - } else { - buffer.WriteString("|") - } - - if np > 0 { - ports := make([]string, np) - for i := 0; i < np; i++ { - ports[i] = servicePorts[i].Name - } - sort.Strings(ports) - for i := 0; i < np; i++ { - if i > 0 { - buffer.WriteString(",") - } - buffer.WriteString(ports[i]) - } - } - - if nt > 0 { - buffer.WriteString("|") - labels := make([]string, nt) - for i := 0; i < nt; i++ { - labels[i] = labelsList[i].String() - } - sort.Strings(labels) - for i := 0; i < nt; i++ { - if i > 0 { - buffer.WriteString(";") - } - buffer.WriteString(labels[i]) - } - } - return buffer.String() -} - -// ParseServiceKey is the inverse of the Service.String() method -func ParseServiceKey(s string) (hostname string, ports PortList, labels LabelsCollection) { - parts := strings.Split(s, "|") - hostname = parts[0] - - var names []string - if len(parts) > 1 { - names = strings.Split(parts[1], ",") - } else { - names = []string{""} - } - - for _, name := range names { - ports = append(ports, &Port{Name: name}) - } - - if len(parts) > 2 && len(parts[2]) > 0 { - for _, tag := range strings.Split(parts[2], ";") { - labels = append(labels, ParseLabelsString(tag)) - } - } - return -} - func (t Labels) String() string { labels := make([]string, 0, len(t)) for k, v := range t { diff --git a/testdata/instances.json b/testdata/instances.json index 82c5adb5..546f270a 100644 --- a/testdata/instances.json +++ b/testdata/instances.json @@ -2,7 +2,8 @@ "hello.default.svc.cluster.local:http": [ { "ip":"10.0.0.1", - "port": 8080 + "port": 8080, + "uid": "pod2.ns3" } ] }