Unverified Commit 20df5aea authored by Alex Dadgar's avatar Alex Dadgar Committed by Preetha Appan
Browse files

Canary tags structs

parent 8be599af
Showing with 132 additions and 13 deletions
+132 -13
...@@ -304,9 +304,10 @@ func TestJobs_Canonicalize(t *testing.T) { ...@@ -304,9 +304,10 @@ func TestJobs_Canonicalize(t *testing.T) {
}, },
Services: []*Service{ Services: []*Service{
{ {
Name: "redis-cache", Name: "redis-cache",
Tags: []string{"global", "cache"}, Tags: []string{"global", "cache"},
PortLabel: "db", CanaryTags: []string{"canary", "global", "cache"},
PortLabel: "db",
Checks: []ServiceCheck{ Checks: []ServiceCheck{
{ {
Name: "alive", Name: "alive",
...@@ -427,6 +428,7 @@ func TestJobs_Canonicalize(t *testing.T) { ...@@ -427,6 +428,7 @@ func TestJobs_Canonicalize(t *testing.T) {
{ {
Name: "redis-cache", Name: "redis-cache",
Tags: []string{"global", "cache"}, Tags: []string{"global", "cache"},
CanaryTags: []string{"canary", "global", "cache"},
PortLabel: "db", PortLabel: "db",
AddressMode: "auto", AddressMode: "auto",
Checks: []ServiceCheck{ Checks: []ServiceCheck{
......
...@@ -295,8 +295,9 @@ type Service struct { ...@@ -295,8 +295,9 @@ type Service struct {
Id string Id string
Name string Name string
Tags []string Tags []string
PortLabel string `mapstructure:"port"` CanaryTags []string `mapstructure:"canary_tags"`
AddressMode string `mapstructure:"address_mode"` PortLabel string `mapstructure:"port"`
AddressMode string `mapstructure:"address_mode"`
Checks []ServiceCheck Checks []ServiceCheck
CheckRestart *CheckRestart `mapstructure:"check_restart"` CheckRestart *CheckRestart `mapstructure:"check_restart"`
} }
......
...@@ -744,6 +744,7 @@ func ApiTaskToStructsTask(apiTask *api.Task, structsTask *structs.Task) { ...@@ -744,6 +744,7 @@ func ApiTaskToStructsTask(apiTask *api.Task, structsTask *structs.Task) {
Name: service.Name, Name: service.Name,
PortLabel: service.PortLabel, PortLabel: service.PortLabel,
Tags: service.Tags, Tags: service.Tags,
CanaryTags: service.CanaryTags,
AddressMode: service.AddressMode, AddressMode: service.AddressMode,
} }
......
...@@ -1255,10 +1255,11 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) { ...@@ -1255,10 +1255,11 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
Services: []*api.Service{ Services: []*api.Service{
{ {
Id: "id", Id: "id",
Name: "serviceA", Name: "serviceA",
Tags: []string{"1", "2"}, Tags: []string{"1", "2"},
PortLabel: "foo", CanaryTags: []string{"3", "4"},
PortLabel: "foo",
CheckRestart: &api.CheckRestart{ CheckRestart: &api.CheckRestart{
Limit: 4, Limit: 4,
Grace: helper.TimeToPtr(11 * time.Second), Grace: helper.TimeToPtr(11 * time.Second),
...@@ -1483,6 +1484,7 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) { ...@@ -1483,6 +1484,7 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
{ {
Name: "serviceA", Name: "serviceA",
Tags: []string{"1", "2"}, Tags: []string{"1", "2"},
CanaryTags: []string{"3", "4"},
PortLabel: "foo", PortLabel: "foo",
AddressMode: "auto", AddressMode: "auto",
Checks: []*structs.ServiceCheck{ Checks: []*structs.ServiceCheck{
......
...@@ -987,6 +987,7 @@ func parseServices(jobName string, taskGroupName string, task *api.Task, service ...@@ -987,6 +987,7 @@ func parseServices(jobName string, taskGroupName string, task *api.Task, service
valid := []string{ valid := []string{
"name", "name",
"tags", "tags",
"canary_tags",
"port", "port",
"check", "check",
"address_mode", "address_mode",
......
...@@ -133,8 +133,9 @@ func TestParse(t *testing.T) { ...@@ -133,8 +133,9 @@ func TestParse(t *testing.T) {
}, },
Services: []*api.Service{ Services: []*api.Service{
{ {
Tags: []string{"foo", "bar"}, Tags: []string{"foo", "bar"},
PortLabel: "http", CanaryTags: []string{"canary", "bam"},
PortLabel: "http",
Checks: []api.ServiceCheck{ Checks: []api.ServiceCheck{
{ {
Name: "check-name", Name: "check-name",
......
...@@ -101,6 +101,7 @@ job "binstore-storagelocker" { ...@@ -101,6 +101,7 @@ job "binstore-storagelocker" {
service { service {
tags = ["foo", "bar"] tags = ["foo", "bar"]
canary_tags = ["canary", "bam"]
port = "http" port = "http"
check { check {
......
...@@ -533,6 +533,15 @@ func serviceDiff(old, new *Service, contextual bool) *ObjectDiff { ...@@ -533,6 +533,15 @@ func serviceDiff(old, new *Service, contextual bool) *ObjectDiff {
// Diff the primitive fields. // Diff the primitive fields.
diff.Fields = fieldDiffs(oldPrimitiveFlat, newPrimitiveFlat, contextual) diff.Fields = fieldDiffs(oldPrimitiveFlat, newPrimitiveFlat, contextual)
if setDiff := stringSetDiff(old.CanaryTags, new.CanaryTags, "CanaryTags", contextual); setDiff != nil {
diff.Objects = append(diff.Objects, setDiff)
}
// Tag diffs
if setDiff := stringSetDiff(old.Tags, new.Tags, "Tags", contextual); setDiff != nil {
diff.Objects = append(diff.Objects, setDiff)
}
// Checks diffs // Checks diffs
if cDiffs := serviceCheckDiffs(old.Checks, new.Checks, contextual); cDiffs != nil { if cDiffs := serviceCheckDiffs(old.Checks, new.Checks, contextual); cDiffs != nil {
diff.Objects = append(diff.Objects, cDiffs...) diff.Objects = append(diff.Objects, cDiffs...)
......
...@@ -3456,6 +3456,99 @@ func TestTaskDiff(t *testing.T) { ...@@ -3456,6 +3456,99 @@ func TestTaskDiff(t *testing.T) {
}, },
}, },
}, },
{
Name: "Services tags edited (no checks) with context",
Contextual: true,
Old: &Task{
Services: []*Service{
{
Tags: []string{"foo", "bar"},
CanaryTags: []string{"foo", "bar"},
},
},
},
New: &Task{
Services: []*Service{
{
Tags: []string{"bar", "bam"},
CanaryTags: []string{"bar", "bam"},
},
},
},
Expected: &TaskDiff{
Type: DiffTypeEdited,
Objects: []*ObjectDiff{
{
Type: DiffTypeEdited,
Name: "Service",
Objects: []*ObjectDiff{
{
Type: DiffTypeEdited,
Name: "CanaryTags",
Fields: []*FieldDiff{
{
Type: DiffTypeAdded,
Name: "CanaryTags",
Old: "",
New: "bam",
},
{
Type: DiffTypeNone,
Name: "CanaryTags",
Old: "bar",
New: "bar",
},
{
Type: DiffTypeDeleted,
Name: "CanaryTags",
Old: "foo",
New: "",
},
},
},
{
Type: DiffTypeEdited,
Name: "Tags",
Fields: []*FieldDiff{
{
Type: DiffTypeAdded,
Name: "Tags",
Old: "",
New: "bam",
},
{
Type: DiffTypeNone,
Name: "Tags",
Old: "bar",
New: "bar",
},
{
Type: DiffTypeDeleted,
Name: "Tags",
Old: "foo",
New: "",
},
},
},
},
Fields: []*FieldDiff{
{
Type: DiffTypeNone,
Name: "AddressMode",
},
{
Type: DiffTypeNone,
Name: "Name",
},
{
Type: DiffTypeNone,
Name: "PortLabel",
},
},
},
},
},
},
{ {
Name: "Service Checks edited", Name: "Service Checks edited",
Old: &Task{ Old: &Task{
......
...@@ -3750,8 +3750,9 @@ type Service struct { ...@@ -3750,8 +3750,9 @@ type Service struct {
// this service. // this service.
AddressMode string AddressMode string
Tags []string // List of tags for the service Tags []string // List of tags for the service
Checks []*ServiceCheck // List of checks associated with the service CanaryTags []string // List of tags for the service when it is a canary
Checks []*ServiceCheck // List of checks associated with the service
} }
func (s *Service) Copy() *Service { func (s *Service) Copy() *Service {
...@@ -3761,6 +3762,7 @@ func (s *Service) Copy() *Service { ...@@ -3761,6 +3762,7 @@ func (s *Service) Copy() *Service {
ns := new(Service) ns := new(Service)
*ns = *s *ns = *s
ns.Tags = helper.CopySliceString(ns.Tags) ns.Tags = helper.CopySliceString(ns.Tags)
ns.CanaryTags = helper.CopySliceString(ns.CanaryTags)
if s.Checks != nil { if s.Checks != nil {
checks := make([]*ServiceCheck, len(ns.Checks)) checks := make([]*ServiceCheck, len(ns.Checks))
...@@ -3781,6 +3783,9 @@ func (s *Service) Canonicalize(job string, taskGroup string, task string) { ...@@ -3781,6 +3783,9 @@ func (s *Service) Canonicalize(job string, taskGroup string, task string) {
if len(s.Tags) == 0 { if len(s.Tags) == 0 {
s.Tags = nil s.Tags = nil
} }
if len(s.CanaryTags) == 0 {
s.CanaryTags = nil
}
if len(s.Checks) == 0 { if len(s.Checks) == 0 {
s.Checks = nil s.Checks = nil
} }
...@@ -3858,6 +3863,9 @@ func (s *Service) Hash(allocID, taskName string) string { ...@@ -3858,6 +3863,9 @@ func (s *Service) Hash(allocID, taskName string) string {
for _, tag := range s.Tags { for _, tag := range s.Tags {
io.WriteString(h, tag) io.WriteString(h, tag)
} }
for _, tag := range s.CanaryTags {
io.WriteString(h, tag)
}
// Base32 is used for encoding the hash as sha1 hashes can always be // Base32 is used for encoding the hash as sha1 hashes can always be
// encoded without padding, only 4 bytes larger than base64, and saves // encoded without padding, only 4 bytes larger than base64, and saves
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment