From 6a4beb63c5d1acaaf2b6b77318a12c1979197cf7 Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Thu, 25 Apr 2019 15:53:58 -0700 Subject: [PATCH] Service aliases This commit makes it possible for a given container to advertise multiple services using aliases. For example, the following config: ``` SERVICE_NAME=a SERVICE_ALIASES=b,c ``` will result in 3 services being registered: a, b, and c. All three pointing to the same container. Those changes should be compatible with ports, and tags. --- bridge/bridge.go | 156 ++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 69 deletions(-) diff --git a/bridge/bridge.go b/bridge/bridge.go index f02ca99c9..0b1b2a281 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -229,24 +229,26 @@ func (b *Bridge) add(containerId string, quiet bool) { isGroup := len(servicePorts) > 1 for _, port := range servicePorts { - service := b.newService(port, isGroup) - if service == nil { + services := b.newService(port, isGroup) + if services == nil { if !quiet { log.Println("ignored:", container.ID[:12], "service on port", port.ExposedPort) } continue } - err := b.registry.Register(service) - if err != nil { - log.Println("register failed:", service, err) - continue + for _, service := range services { + err := b.registry.Register(service) + if err != nil { + log.Println("register failed:", service, err) + continue + } + b.services[container.ID] = append(b.services[container.ID], service) + log.Println("added:", container.ID[:12], service.ID) } - b.services[container.ID] = append(b.services[container.ID], service) - log.Println("added:", container.ID[:12], service.ID) } } -func (b *Bridge) newService(port ServicePort, isgroup bool) *Service { +func (b *Bridge) newService(port ServicePort, isgroup bool) []*Service { container := port.container defaultName := strings.Split(path.Base(container.Config.Image), ":")[0] @@ -273,86 +275,102 @@ func (b *Bridge) newService(port ServicePort, isgroup bool) *Service { return nil } - serviceName := mapDefault(metadata, "name", "") - if serviceName == "" { + mainServiceName := mapDefault(metadata, "name", "") + if mainServiceName == "" { if b.config.Explicit { return nil } - serviceName = defaultName + mainServiceName = defaultName } - service := new(Service) - service.Origin = port - service.ID = hostname + ":" + container.Name[1:] + ":" + port.ExposedPort - service.Name = serviceName - if isgroup && !metadataFromPort["name"] { - service.Name += "-" + port.ExposedPort - } - var p int - - if b.config.Internal == true { - service.IP = port.ExposedIP - p, _ = strconv.Atoi(port.ExposedPort) - } else { - service.IP = port.HostIP - p, _ = strconv.Atoi(port.HostPort) + serviceNames := []string{mainServiceName} + + aliasesValue := mapDefault(metadata, "aliases", "") + aliases := strings.Split(aliasesValue, ",") + for _, alias := range aliases { + if len(alias) > 0 { + serviceNames = append(serviceNames, alias) + } } - service.Port = p - - if b.config.UseIpFromLabel != "" { - containerIp := container.Config.Labels[b.config.UseIpFromLabel] - if containerIp != "" { - slashIndex := strings.LastIndex(containerIp, "/") - if slashIndex > -1 { - service.IP = containerIp[:slashIndex] + + services := make([]*Service, len(serviceNames)) + + for i, serviceName := range serviceNames { + service := new(Service) + service.Origin = port + service.ID = hostname + ":" + container.Name[1:] + "-" + serviceName + ":" + port.ExposedPort + service.Name = serviceName + if isgroup && !metadataFromPort["name"] { + service.Name += "-" + port.ExposedPort + } + var p int + + if b.config.Internal == true { + service.IP = port.ExposedIP + p, _ = strconv.Atoi(port.ExposedPort) + } else { + service.IP = port.HostIP + p, _ = strconv.Atoi(port.HostPort) + } + service.Port = p + + if b.config.UseIpFromLabel != "" { + containerIp := container.Config.Labels[b.config.UseIpFromLabel] + if containerIp != "" { + slashIndex := strings.LastIndex(containerIp, "/") + if slashIndex > -1 { + service.IP = containerIp[:slashIndex] + } else { + service.IP = containerIp + } + log.Println("using container IP " + service.IP + " from label '" + + b.config.UseIpFromLabel + "'") } else { - service.IP = containerIp + log.Println("Label '" + b.config.UseIpFromLabel + + "' not found in container configuration") } - log.Println("using container IP " + service.IP + " from label '" + - b.config.UseIpFromLabel + "'") - } else { - log.Println("Label '" + b.config.UseIpFromLabel + - "' not found in container configuration") } - } - // NetworkMode can point to another container (kuberenetes pods) - networkMode := container.HostConfig.NetworkMode - if networkMode != "" { - if strings.HasPrefix(networkMode, "container:") { - networkContainerId := strings.Split(networkMode, ":")[1] - log.Println(service.Name + ": detected container NetworkMode, linked to: " + networkContainerId[:12]) - networkContainer, err := b.docker.InspectContainer(networkContainerId) - if err != nil { - log.Println("unable to inspect network container:", networkContainerId[:12], err) - } else { - service.IP = networkContainer.NetworkSettings.IPAddress - log.Println(service.Name + ": using network container IP " + service.IP) + // NetworkMode can point to another container (kuberenetes pods) + networkMode := container.HostConfig.NetworkMode + if networkMode != "" { + if strings.HasPrefix(networkMode, "container:") { + networkContainerId := strings.Split(networkMode, ":")[1] + log.Println(service.Name + ": detected container NetworkMode, linked to: " + networkContainerId[:12]) + networkContainer, err := b.docker.InspectContainer(networkContainerId) + if err != nil { + log.Println("unable to inspect network container:", networkContainerId[:12], err) + } else { + service.IP = networkContainer.NetworkSettings.IPAddress + log.Println(service.Name + ": using network container IP " + service.IP) + } } } - } - if port.PortType == "udp" { - service.Tags = combineTags( - mapDefault(metadata, "tags", ""), b.config.ForceTags, "udp") - service.ID = service.ID + ":udp" - } else { - service.Tags = combineTags( - mapDefault(metadata, "tags", ""), b.config.ForceTags) - } + if port.PortType == "udp" { + service.Tags = combineTags( + mapDefault(metadata, "tags", ""), b.config.ForceTags, "udp") + service.ID = service.ID + ":udp" + } else { + service.Tags = combineTags( + mapDefault(metadata, "tags", ""), b.config.ForceTags) + } + + id := mapDefault(metadata, "id", "") + if id != "" { + service.ID = id + } - id := mapDefault(metadata, "id", "") - if id != "" { - service.ID = id + service.Attrs = metadata + service.TTL = b.config.RefreshTtl + services[i] = service } delete(metadata, "id") delete(metadata, "tags") delete(metadata, "name") - service.Attrs = metadata - service.TTL = b.config.RefreshTtl - return service + return services } func (b *Bridge) remove(containerId string, deregister bool) {