Skip to content

Commit

Permalink
Consul hook: resolve port placeholders in tags
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinFalkowski authored and tomez committed Jul 11, 2019
1 parent e4c59bf commit ff8224d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
27 changes: 26 additions & 1 deletion hook/consul/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
consulNameLabelKey = "consul"
consulTagValue = "tag"
serviceHost = "127.0.0.1"
portPlaceholder = "{port:%s}"
)

// instance represents a service in consul
Expand Down Expand Up @@ -92,6 +93,7 @@ func (h *Hook) RegisterIntoConsul(taskInfo mesosutils.TaskInfo) error {
}

ports := taskInfo.GetPorts()
tagPlaceholders := getPlaceholders(ports)
globalTags := append(taskInfo.GetLabelKeysByValue(consulTagValue), h.config.ConsulGlobalTag)

var instancesToRegister []instance
Expand Down Expand Up @@ -133,7 +135,7 @@ func (h *Hook) RegisterIntoConsul(taskInfo mesosutils.TaskInfo) error {
serviceRegistration := api.AgentServiceRegistration{
ID: serviceData.consulServiceID,
Name: serviceData.consulServiceName,
Tags: serviceData.tags,
Tags: resolvePlaceholders(serviceData.tags, tagPlaceholders),
Port: int(serviceData.port),
Address: runenv.IP().String(),
EnableTagOverride: false,
Expand Down Expand Up @@ -172,6 +174,29 @@ func (h *Hook) DeregisterFromConsul(taskInfo mesosutils.TaskInfo) error {
return nil
}

func getPlaceholders(ports []mesos.Port) map[string]string {
placeholders := map[string]string{}
for _, port := range ports {
name := port.GetName()
if name != "" {
placeholder := fmt.Sprintf(portPlaceholder, name)
placeholders[placeholder] = fmt.Sprint(port.GetNumber())
}
}
return placeholders
}

func resolvePlaceholders(values []string, placeholders map[string]string) []string {
resolved := make([]string, 0, len(values))
for _, value := range values {
for placeholder, replacement := range placeholders {
value = strings.Replace(value, placeholder, replacement, -1)
}
resolved = append(resolved, value)
}
return resolved
}

func getServiceLabel(port mesos.Port) (string, error) {
label := mesosutils.FindLabel(port.GetLabels().GetLabels(), consulNameLabelKey)
if label == nil {
Expand Down
45 changes: 45 additions & 0 deletions hook/consul/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,51 @@ func TestIfServiceDeregisteredCorrectly(t *testing.T) {
require.NotContains(t, services, consulName)
}

func TestIfPlaceholdersAreResolved(t *testing.T) {

adminPortName := "admin"
servicePortName := "service"
consulName := "serviceName"
consulNameAdmin := "serviceName-admin"
tagValue := "tag"

// Create a test Consul server
config, server := createTestConsulServer(t)
client, _ := api.NewClient(config) // #nosec
defer stopConsul(server)

taskInfo := prepareTaskInfo("taskId", "taskName", "taskName", []string{"service-port:{port:service}"}, []mesos.Port{
{Number: 655, Name: &adminPortName, Labels: &mesos.Labels{Labels: []mesos.Label{
{Key: "consul", Value: &consulNameAdmin},
{Key: "admin", Value: &tagValue},
}}},
{Number: 766, Labels: &mesos.Labels{Labels: []mesos.Label{
{Key: "consul", Value: &consulName},
{Key: "admin-port:{port:admin}", Value: &tagValue},
{Key: "{port:unknown} is not replaced", Value: &tagValue},
}}},
{Number: 877, Name: &servicePortName},
})

expectedServiceTags := []string{"marathon", "service-port:877", "admin-port:655", "{port:unknown} is not replaced"}
expectedAdminTags := []string{"marathon", "admin", "service-port:877"}

h := &Hook{config: Config{ConsulGlobalTag: "marathon"}, client: client}

err := h.RegisterIntoConsul(taskInfo)

require.NoError(t, err)
require.Len(t, h.serviceInstances, 2)

opts := api.QueryOptions{}
services, _, err := client.Catalog().Services(&opts)

require.Contains(t, services, consulName)
requireEqualElements(t, expectedServiceTags, services[consulName])
require.Contains(t, services, consulNameAdmin)
requireEqualElements(t, expectedAdminTags, services[consulNameAdmin])
}

func TestIfErrorHandledOnNoConsul(t *testing.T) {
consulName := "consulName"
taskID := "taskID"
Expand Down

0 comments on commit ff8224d

Please sign in to comment.