Skip to content

Commit

Permalink
Merge pull request #10059 from hashicorp/b-cc-service-tags
Browse files Browse the repository at this point in the history
consul/connect: Fix bug where connect sidecar services would be unnecessarily re-registered
  • Loading branch information
shoenig committed Feb 22, 2021
2 parents a4d99a8 + e3af469 commit fcf81ab
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ BUG FIXES:
* consul: Fixed a bug where failing tasks with group services would only cause the allocation to restart once instead of respecting the `restart` field. [[GH-9869](https://github.com/hashicorp/nomad/issues/9869)]
* consul/connect: Fixed a bug where gateway proxy connection default timeout not set [[GH-9851](https://github.com/hashicorp/nomad/pull/9851)]
* consul/connect: Fixed a bug preventing more than one connect gateway per Nomad client [[GH-9849](https://github.com/hashicorp/nomad/pull/9849)]
* consul/connect: Fixed a bug where connect sidecar services would be re-registered unnecessarily. [[GH-10059](https://github.com/hashicorp/nomad/pull/10059)]
* consul/connect: Fixed a bug where the sidecar health checks would fail if `host_network` was defined. [[GH-9975](https://github.com/hashicorp/nomad/issues/9975)]
* drivers/docker: Fixed a bug preventing multiple ports to be mapped to the same container port [[GH-9951](https://github.com/hashicorp/nomad/issues/9951)]
* driver/qemu: Fixed a bug where network namespaces were not supported for QEMU workloads [[GH-9861](https://github.com/hashicorp/nomad/pull/9861)]
Expand Down
26 changes: 20 additions & 6 deletions command/agent/consul/service_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ func maybeTweakTags(wanted *api.AgentServiceRegistration, existing *api.AgentSer
// (cached) state of the service registration reported by Consul. If any of the
// critical fields are not deeply equal, they considered different.
func different(wanted *api.AgentServiceRegistration, existing *api.AgentService, sidecar *api.AgentService) bool {

switch {
case wanted.Kind != existing.Kind:
return true
Expand All @@ -205,12 +204,11 @@ func different(wanted *api.AgentServiceRegistration, existing *api.AgentService,
return true
case !reflect.DeepEqual(wanted.Meta, existing.Meta):
return true
case !reflect.DeepEqual(wanted.Tags, existing.Tags):
case tagsDifferent(wanted.Tags, existing.Tags):
return true
case connectSidecarDifferent(wanted, sidecar):
return true
}

return false
}

Expand All @@ -228,20 +226,36 @@ func tagsDifferent(a, b []string) bool {
return false
}

// sidecarTagsDifferent includes the special logic for comparing sidecar tags
// from Nomad vs. Consul perspective. Because Consul forces the sidecar tags
// to inherit the parent service tags if the sidecar tags are unset, we need to
// take that into consideration when Nomad's sidecar tags are unset by instead
// comparing them to the parent service tags.
func sidecarTagsDifferent(parent, wanted, sidecar []string) bool {
if len(wanted) == 0 {
return tagsDifferent(parent, sidecar)
}
return tagsDifferent(wanted, sidecar)
}

// connectSidecarDifferent returns true if Nomad expects there to be a sidecar
// hanging off the desired parent service definition on the Consul side, and does
// not match with what Consul has.
func connectSidecarDifferent(wanted *api.AgentServiceRegistration, sidecar *api.AgentService) bool {
if wanted.Connect != nil && wanted.Connect.SidecarService != nil {
if sidecar == nil {
// consul lost our sidecar (?)
return true
}
if tagsDifferent(wanted.Connect.SidecarService.Tags, sidecar.Tags) {

if sidecarTagsDifferent(wanted.Tags, wanted.Connect.SidecarService.Tags, sidecar.Tags) {
// tags on the nomad definition have been modified
return true
}
}

// There is no connect sidecar the nomad side; let consul anti-entropy worry
// about any registration on the consul side.
// Either Nomad does not expect there to be a sidecar_service, or there is
// no actionable difference from the Consul sidecar_service definition.
return false
}

Expand Down
26 changes: 26 additions & 0 deletions command/agent/consul/service_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,32 @@ func TestSyncLogic_tagsDifferent(t *testing.T) {
})
}

func TestSyncLogic_sidecarTagsDifferent(t *testing.T) {
type tc struct {
parent, wanted, sidecar []string
expect bool
}

try := func(t *testing.T, test tc) {
result := sidecarTagsDifferent(test.parent, test.wanted, test.sidecar)
require.Equal(t, test.expect, result)
}

try(t, tc{parent: nil, wanted: nil, sidecar: nil, expect: false})

// wanted is nil, compare sidecar to parent
try(t, tc{parent: []string{"foo"}, wanted: nil, sidecar: nil, expect: true})
try(t, tc{parent: []string{"foo"}, wanted: nil, sidecar: []string{"foo"}, expect: false})
try(t, tc{parent: []string{"foo"}, wanted: nil, sidecar: []string{"bar"}, expect: true})
try(t, tc{parent: nil, wanted: nil, sidecar: []string{"foo"}, expect: true})

// wanted is non-nil, compare sidecar to wanted
try(t, tc{parent: nil, wanted: []string{"foo"}, sidecar: nil, expect: true})
try(t, tc{parent: nil, wanted: []string{"foo"}, sidecar: []string{"foo"}, expect: false})
try(t, tc{parent: nil, wanted: []string{"foo"}, sidecar: []string{"bar"}, expect: true})
try(t, tc{parent: []string{"foo"}, wanted: []string{"foo"}, sidecar: []string{"bar"}, expect: true})
}

func TestSyncLogic_maybeTweakTags(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit fcf81ab

Please sign in to comment.