From 05631730eaac50351cd1591092c6312968ac41e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Burzy=C5=84ski?= Date: Wed, 14 Jun 2023 14:07:30 +0200 Subject: [PATCH] fix: handle missing service and route names detecting duplicates --- tests/integration/sync_test.go | 44 +++++++++++++++++++ .../after.yaml | 12 +++++ .../before.yaml | 10 +++++ types/route.go | 5 +++ types/service.go | 5 +++ 5 files changed, 76 insertions(+) create mode 100644 tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/after.yaml create mode 100644 tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/before.yaml diff --git a/tests/integration/sync_test.go b/tests/integration/sync_test.go index cd0404140..598266d7e 100644 --- a/tests/integration/sync_test.go +++ b/tests/integration/sync_test.go @@ -3414,3 +3414,47 @@ func Test_Sync_UpdateWithExplicitIDs(t *testing.T) { }, }, ignoreFieldsIrrelevantForIDsTests) } + +// test scope: +// - 3.0.0+ +// - konnect +func Test_Sync_UpdateWithExplicitIDsWithNoNames(t *testing.T) { + runWhenKongOrKonnect(t, ">=3.0.0") + + client, err := getTestClient() + if err != nil { + t.Errorf(err.Error()) + } + + const ( + beforeConfig = "testdata/sync/022-update-with-explicit-ids-with-no-names/before.yaml" + afterConfig = "testdata/sync/022-update-with-explicit-ids-with-no-names/after.yaml" + ) + + // First, create entities with IDs assigned explicitly. + err = sync(beforeConfig) + require.NoError(t, err) + + // Then, sync again, adding tags to every entity just to trigger an update. + err = sync(afterConfig) + require.NoError(t, err) + + // Finally, verify that the update was successful. + testKongState(t, client, false, utils.KongRawState{ + Services: []*kong.Service{ + { + ID: kong.String("c75a775b-3a32-4b73-8e05-f68169c23941"), + Tags: kong.StringSlice("after"), + }, + }, + Routes: []*kong.Route{ + { + ID: kong.String("97b6a97e-f3f7-4c47-857a-7464cb9e202b"), + Tags: kong.StringSlice("after"), + Service: &kong.Service{ + ID: kong.String("c75a775b-3a32-4b73-8e05-f68169c23941"), + }, + }, + }, + }, ignoreFieldsIrrelevantForIDsTests) +} diff --git a/tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/after.yaml b/tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/after.yaml new file mode 100644 index 000000000..f823fde3e --- /dev/null +++ b/tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/after.yaml @@ -0,0 +1,12 @@ +_format_version: "3.0" +services: + - enabled: true + host: mockbin.org + id: c75a775b-3a32-4b73-8e05-f68169c23941 # Leaving ID + port: 80 + tags: [after] + routes: + - id: 97b6a97e-f3f7-4c47-857a-7464cb9e202b # Leaving ID + paths: + - /r1 + tags: [after] diff --git a/tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/before.yaml b/tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/before.yaml new file mode 100644 index 000000000..413ecb4d4 --- /dev/null +++ b/tests/integration/testdata/sync/022-update-with-explicit-ids-with-no-names/before.yaml @@ -0,0 +1,10 @@ +_format_version: "3.0" +services: + - enabled: true + host: mockbin.org + id: c75a775b-3a32-4b73-8e05-f68169c23941 # Leaving ID + port: 80 + routes: + - id: 97b6a97e-f3f7-4c47-857a-7464cb9e202b # Leaving ID + paths: + - /r1 diff --git a/types/route.go b/types/route.go index 97d493dc7..e7ce4ad9d 100644 --- a/types/route.go +++ b/types/route.go @@ -188,6 +188,11 @@ func (d *routeDiffer) DuplicatesDeletes() ([]crud.Event, error) { } func (d *routeDiffer) deleteDuplicateRoute(targetRoute *state.Route) (*crud.Event, error) { + if targetRoute == nil || targetRoute.Name == nil { + // Nothing to do, cannot be a duplicate with no name. + return nil, nil + } + currentRoute, err := d.currentState.Routes.Get(*targetRoute.Name) if errors.Is(err, state.ErrNotFound) { return nil, nil diff --git a/types/service.go b/types/service.go index 5eea70833..a71515243 100644 --- a/types/service.go +++ b/types/service.go @@ -177,6 +177,11 @@ func (d *serviceDiffer) DuplicatesDeletes() ([]crud.Event, error) { } func (d *serviceDiffer) deleteDuplicateService(targetService *state.Service) ([]crud.Event, error) { + if targetService == nil || targetService.Name == nil { + // Nothing to do, cannot be a duplicate with no name. + return nil, nil + } + currentService, err := d.currentState.Services.Get(*targetService.Name) if errors.Is(err, state.ErrNotFound) { return nil, nil