consul: add support for canary meta

This commit is contained in:
Nick Ethier
2019-11-12 22:27:54 -05:00
parent 9fdc9dea4e
commit 64f4e9e691
11 changed files with 135 additions and 6 deletions

View File

@@ -5,6 +5,7 @@ import (
"sync"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/helper"
"github.com/hashicorp/consul/api"
)
@@ -111,6 +112,7 @@ func (c *MockAgent) Services() (map[string]*api.AgentService, error) {
ID: v.ID,
Service: v.Name,
Tags: make([]string, len(v.Tags)),
Meta: helper.CopyMapStringString(v.Meta),
Port: v.Port,
Address: v.Address,
EnableTagOverride: v.EnableTagOverride,

View File

@@ -99,7 +99,8 @@ func agentServiceUpdateRequired(reg *api.AgentServiceRegistration, svc *api.Agen
reg.Port == svc.Port &&
reg.Address == svc.Address &&
reg.Name == svc.Service &&
reflect.DeepEqual(reg.Tags, svc.Tags))
reflect.DeepEqual(reg.Tags, svc.Tags) &&
reflect.DeepEqual(reg.Meta, svc.Meta))
}
// operations are submitted to the main loop via commit() for synchronizing
@@ -713,9 +714,17 @@ func (c *ServiceClient) serviceRegs(ops *operations, service *structs.Service, w
return nil, fmt.Errorf("invalid Consul Connect configuration for service %q: %v", service.Name, err)
}
meta := make(map[string]string, len(service.Meta))
for k, v := range service.Meta {
meta[k] = v
var meta map[string]string
if task.Canary && len(service.CanaryMeta) > 0 {
meta = make(map[string]string, len(service.CanaryMeta)+1)
for k, v := range service.CanaryMeta {
meta[k] = v
}
} else {
meta = make(map[string]string, len(service.Meta)+1)
for k, v := range service.Meta {
meta[k] = v
}
}
// This enables the consul UI to show that Nomad registered this service

View File

@@ -35,6 +35,7 @@ func testWorkload() *WorkloadServices {
Name: "taskname-service",
PortLabel: "x",
Tags: []string{"tag1", "tag2"},
Meta: map[string]string{"meta1": "foo"},
},
},
Networks: []*structs.NetworkResource{
@@ -1077,6 +1078,73 @@ func TestConsul_CanaryTags_NoTags(t *testing.T) {
require.Len(ctx.FakeConsul.services, 0)
}
// TestConsul_CanaryMeta asserts CanaryMeta are used when Canary=true
func TestConsul_CanaryMeta(t *testing.T) {
t.Parallel()
require := require.New(t)
ctx := setupFake(t)
canaryMeta := map[string]string{"meta1": "canary"}
canaryMeta["external-source"] = "nomad"
ctx.Task.Canary = true
ctx.Task.Services[0].CanaryMeta = canaryMeta
require.NoError(ctx.ServiceClient.RegisterTask(ctx.Task))
require.NoError(ctx.syncOnce())
require.Len(ctx.FakeConsul.services, 1)
for _, service := range ctx.FakeConsul.services {
require.Equal(canaryMeta, service.Meta)
}
// Disable canary and assert meta are not the canary meta
origTask := ctx.Task.Copy()
ctx.Task.Canary = false
require.NoError(ctx.ServiceClient.UpdateTask(origTask, ctx.Task))
require.NoError(ctx.syncOnce())
require.Len(ctx.FakeConsul.services, 1)
for _, service := range ctx.FakeConsul.services {
require.NotEqual(canaryMeta, service.Meta)
}
ctx.ServiceClient.RemoveTask(ctx.Task)
require.NoError(ctx.syncOnce())
require.Len(ctx.FakeConsul.services, 0)
}
// TestConsul_CanaryMeta_NoMeta asserts Meta are used when Canary=true and there
// are no specified canary meta
func TestConsul_CanaryMeta_NoMeta(t *testing.T) {
t.Parallel()
require := require.New(t)
ctx := setupFake(t)
meta := map[string]string{"meta1": "foo"}
meta["external-source"] = "nomad"
ctx.Task.Canary = true
ctx.Task.Services[0].Meta = meta
require.NoError(ctx.ServiceClient.RegisterTask(ctx.Task))
require.NoError(ctx.syncOnce())
require.Len(ctx.FakeConsul.services, 1)
for _, service := range ctx.FakeConsul.services {
require.Equal(meta, service.Meta)
}
// Disable canary and assert meta dont change
origTask := ctx.Task.Copy()
ctx.Task.Canary = false
require.NoError(ctx.ServiceClient.UpdateTask(origTask, ctx.Task))
require.NoError(ctx.syncOnce())
require.Len(ctx.FakeConsul.services, 1)
for _, service := range ctx.FakeConsul.services {
require.Equal(meta, service.Meta)
}
ctx.ServiceClient.RemoveTask(ctx.Task)
require.NoError(ctx.syncOnce())
require.Len(ctx.FakeConsul.services, 0)
}
// TestConsul_PeriodicSync asserts that Nomad periodically reconciles with
// Consul.
func TestConsul_PeriodicSync(t *testing.T) {

View File

@@ -834,6 +834,7 @@ func ApiTaskToStructsTask(apiTask *api.Task, structsTask *structs.Task) {
CanaryTags: service.CanaryTags,
AddressMode: service.AddressMode,
Meta: helper.CopyMapStringString(service.Meta),
CanaryMeta: helper.CopyMapStringString(service.CanaryMeta),
}
if l := len(service.Checks); l != 0 {
@@ -1012,6 +1013,7 @@ func ApiServicesToStructs(in []*api.Service) []*structs.Service {
CanaryTags: s.CanaryTags,
AddressMode: s.AddressMode,
Meta: helper.CopyMapStringString(s.Meta),
CanaryMeta: helper.CopyMapStringString(s.CanaryMeta),
}
if l := len(s.Checks); l != 0 {