From 05c3ffde9d61a16fecebe6825d8f31afb34d627a Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Tue, 23 Feb 2021 15:08:39 -0600 Subject: [PATCH] consul/connect: correctly detect when connect tasks not updated This PR fixes a bug where tasks with Connect services could be triggered to destructively update (i.e. placed in a new alloc) when no update should be necessary. Fixes #10077 --- CHANGELOG.md | 1 + scheduler/util.go | 4 +-- scheduler/util_test.go | 74 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49227e8540b8..7fa3489dcdd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ BUG FIXES: * 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)] + * consul/connect: Fixed a bug where tasks with connect services might be updated when no update necessary. [[GH-10077](https://github.com/hashicorp/nomad/issues/10077)] * deployments: Fixed a bug where deployments with multiple task groups and manual promotion would fail if promoted after the progress deadline. [[GH-10042](https://github.com/hashicorp/nomad/issues/10042)] * 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)] diff --git a/scheduler/util.go b/scheduler/util.go index fa2c233f1b54..777c0e00f2b8 100644 --- a/scheduler/util.go +++ b/scheduler/util.go @@ -467,7 +467,7 @@ func connectServiceUpdated(servicesA, servicesB []*structs.Service) bool { // update. func connectUpdated(connectA, connectB *structs.ConsulConnect) bool { if connectA == nil || connectB == nil { - return connectA == connectB + return connectA != connectB } if connectA.Native != connectB.Native { @@ -492,7 +492,7 @@ func connectUpdated(connectA, connectB *structs.ConsulConnect) bool { func connectSidecarServiceUpdated(ssA, ssB *structs.ConsulSidecarService) bool { if ssA == nil || ssB == nil { - return ssA == ssB + return ssA != ssB } if ssA.Port != ssB.Port { diff --git a/scheduler/util_test.go b/scheduler/util_test.go index ccc60372eead..fba5e611a56a 100644 --- a/scheduler/util_test.go +++ b/scheduler/util_test.go @@ -1386,3 +1386,77 @@ func TestUtil_UpdateNonTerminalAllocsToLost(t *testing.T) { expected = []string{} require.True(t, reflect.DeepEqual(allocsLost, expected), "actual: %v, expected: %v", allocsLost, expected) } + +func TestUtil_connectUpdated(t *testing.T) { + t.Run("both nil", func(t *testing.T) { + require.False(t, connectUpdated(nil, nil)) + }) + + t.Run("one nil", func(t *testing.T) { + require.True(t, connectUpdated(nil, new(structs.ConsulConnect))) + }) + + t.Run("native differ", func(t *testing.T) { + a := &structs.ConsulConnect{Native: true} + b := &structs.ConsulConnect{Native: false} + require.True(t, connectUpdated(a, b)) + }) + + t.Run("gateway differ", func(t *testing.T) { + a := &structs.ConsulConnect{Gateway: &structs.ConsulGateway{ + Ingress: new(structs.ConsulIngressConfigEntry), + }} + b := &structs.ConsulConnect{Gateway: &structs.ConsulGateway{ + Terminating: new(structs.ConsulTerminatingConfigEntry), + }} + require.True(t, connectUpdated(a, b)) + }) + + t.Run("sidecar task differ", func(t *testing.T) { + a := &structs.ConsulConnect{SidecarTask: &structs.SidecarTask{ + Driver: "exec", + }} + b := &structs.ConsulConnect{SidecarTask: &structs.SidecarTask{ + Driver: "docker", + }} + require.True(t, connectUpdated(a, b)) + }) + + t.Run("sidecar service differ", func(t *testing.T) { + a := &structs.ConsulConnect{SidecarService: &structs.ConsulSidecarService{ + Port: "1111", + }} + b := &structs.ConsulConnect{SidecarService: &structs.ConsulSidecarService{ + Port: "2222", + }} + require.True(t, connectUpdated(a, b)) + }) + + t.Run("same", func(t *testing.T) { + a := new(structs.ConsulConnect) + b := new(structs.ConsulConnect) + require.False(t, connectUpdated(a, b)) + }) +} + +func TestUtil_connectSidecarServiceUpdated(t *testing.T) { + t.Run("both nil", func(t *testing.T) { + require.False(t, connectSidecarServiceUpdated(nil, nil)) + }) + + t.Run("one nil", func(t *testing.T) { + require.True(t, connectSidecarServiceUpdated(nil, new(structs.ConsulSidecarService))) + }) + + t.Run("ports differ", func(t *testing.T) { + a := &structs.ConsulSidecarService{Port: "1111"} + b := &structs.ConsulSidecarService{Port: "2222"} + require.True(t, connectSidecarServiceUpdated(a, b)) + }) + + t.Run("same", func(t *testing.T) { + a := &structs.ConsulSidecarService{Port: "1111"} + b := &structs.ConsulSidecarService{Port: "1111"} + require.False(t, connectSidecarServiceUpdated(a, b)) + }) +}