Skip to content

Commit 5b46edc

Browse files
fix select tag mismatch leading to replacement of entity with ID (#1572)
* tests: add integration tests to avoid overwrite unexpected of entity when ID is present in input with select-tag * tests: merge tests for different entities into one suite for konnect * chore: bump go-kong and go-database-reconciler versions * tests: reduce duplication
1 parent 048a7dd commit 5b46edc

37 files changed

+901
-6
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ require (
1313
github.com/fatih/color v1.18.0
1414
github.com/google/go-cmp v0.7.0
1515
github.com/kong/go-apiops v0.1.41
16-
github.com/kong/go-database-reconciler v1.22.0
17-
github.com/kong/go-kong v0.64.1
16+
github.com/kong/go-database-reconciler v1.22.1
17+
github.com/kong/go-kong v0.65.0
1818
github.com/mitchellh/go-homedir v1.1.0
1919
github.com/spf13/cobra v1.8.1
2020
github.com/spf13/pflag v1.0.6

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,10 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q
246246
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
247247
github.com/kong/go-apiops v0.1.41 h1:1KXbQqyhO2E4nEnXJNqUDmHZU/LQ1U7Zoi+MAlcM2P0=
248248
github.com/kong/go-apiops v0.1.41/go.mod h1:sATq9Tz+ivzHKZU+tDXkRtEZnf64xroU3lgv3yXqP4I=
249-
github.com/kong/go-database-reconciler v1.22.0 h1:xkcGFqjk1QattePNXHI2PYtQ4qh6Ibhkj+8aMBPQLZs=
250-
github.com/kong/go-database-reconciler v1.22.0/go.mod h1:emf04E6FSd5y9OKCMB+kNQ0NCTauSaEeCUNRCUgymSY=
251-
github.com/kong/go-kong v0.64.1 h1:HQssErFchbyYoDVQL7kR8x2naaY9mFgmDu/dXF0NZSo=
252-
github.com/kong/go-kong v0.64.1/go.mod h1:sqdysTKrXIJ6mpxHwTwjgZhLW7jR1/puczTXHLUwJaE=
249+
github.com/kong/go-database-reconciler v1.22.1 h1:m3H8j9pGsR4+CSTTvBuTcSYWGL8i62tOimjzxqjQUqc=
250+
github.com/kong/go-database-reconciler v1.22.1/go.mod h1:Jlo4eEe0/PHd2dIkWTH9tFfShydRwRxY09dZvKZBelU=
251+
github.com/kong/go-kong v0.65.0 h1:dZT+hiMhy7CQsrc9W5nHv3cFJGBGTrwlZhC5MLuf9H8=
252+
github.com/kong/go-kong v0.65.0/go.mod h1:sqdysTKrXIJ6mpxHwTwjgZhLW7jR1/puczTXHLUwJaE=
253253
github.com/kong/go-slugify v1.0.0 h1:vCFAyf2sdoSlBtLcrmDWUFn0ohlpKiKvQfXZkO5vSKY=
254254
github.com/kong/go-slugify v1.0.0/go.mod h1:dbR2h3J2QKXQ1k0aww6cN7o4cIcwlWflr6RKRdcoaiw=
255255
github.com/kong/kubernetes-configuration v1.1.0 h1:zCj7QlOiZgwQ2wSNlVNR0K6Z+plXTalfihtDzLXQWzs=

tests/integration/sync_test.go

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7917,3 +7917,301 @@ func Test_Sync_Consumers_Default_Lookup_Tag(t *testing.T) {
79177917
require.NoError(t, err)
79187918
})
79197919
}
7920+
7921+
// test scope:
7922+
//
7923+
// - >=2.8.0
7924+
// - konnect
7925+
func Test_Sync_Avoid_Overwrite_On_Select_Tag_Mismatch_With_ID(t *testing.T) {
7926+
runWhenKongOrKonnect(t, ">=2.8.0")
7927+
setup(t)
7928+
7929+
ctx := context.Background()
7930+
7931+
tests := []struct {
7932+
name string
7933+
initialStateFile string
7934+
targetStateFile string
7935+
errorExpected string
7936+
}{
7937+
{
7938+
name: "ACL group",
7939+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/acl-group-initial.yaml",
7940+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/acl-group-final.yaml",
7941+
errorExpected: "error: ACL group with ID f2be545c-45c5-46e2-8acf-00ff2d899073 already exists",
7942+
},
7943+
{
7944+
name: "basic-auth",
7945+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/basic-auth-initial.yaml",
7946+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/basic-auth-final.yaml",
7947+
errorExpected: "error: basic-auth credential with ID 7dd67c9c-f591-4216-9718-b320174193bb already exists",
7948+
},
7949+
{
7950+
name: "hmac-auth",
7951+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/hmac-auth-initial.yaml",
7952+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/hmac-auth-final.yaml",
7953+
errorExpected: "error: hmac-auth credential with ID 172e4a82-5446-4b91-ab9f-5173478ed241 already exists",
7954+
},
7955+
{
7956+
name: "jwt",
7957+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/jwt-initial.yaml",
7958+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/jwt-final.yaml",
7959+
errorExpected: "error: jwt-auth credential with ID 955382ce-98b0-4719-98ba-40ecd2db06de already exists",
7960+
},
7961+
{
7962+
name: "key-auth",
7963+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/key-auth-initial.yaml",
7964+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/key-auth-final.yaml",
7965+
errorExpected: "error: key-auth credential with ID 6307cfb6-a9d9-4968-95ce-3937fcdd2359 already exists",
7966+
},
7967+
{
7968+
name: "certificate",
7969+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/certificate-initial.yaml",
7970+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/certificate-final.yaml",
7971+
errorExpected: "error: certificate with ID 13c562a1-191c-4464-9b18-e5222b46035a already exists",
7972+
},
7973+
{
7974+
name: "ca-certificate",
7975+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/ca-certificate-initial.yaml", //nolint:lll
7976+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/ca-certificate-final.yaml",
7977+
errorExpected: "error: CA certificate with ID b824e7c0-d116-4c03-9e27-de05c5d30083 already exists",
7978+
},
7979+
{
7980+
name: "consumer",
7981+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/consumer-initial.yaml",
7982+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/consumer-final.yaml",
7983+
errorExpected: "error: consumer with ID 5a1e49a8-2536-41fa-a4e9-605bf218a4fa already exists",
7984+
},
7985+
{
7986+
name: "plugin",
7987+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/plugin-initial.yaml",
7988+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/plugin-final.yaml",
7989+
errorExpected: "error: plugin with ID 5a1e49a8-2536-41fa-a4e9-605bf218a4fa already exists",
7990+
},
7991+
{
7992+
name: "route",
7993+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/route-initial.yaml",
7994+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/route-final.yaml",
7995+
errorExpected: "error: route with ID 87b6a97e-f3f7-4c47-857a-7464cb9e202b already exists",
7996+
},
7997+
{
7998+
name: "service",
7999+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/service-initial.yaml",
8000+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/service-final.yaml",
8001+
errorExpected: "error: service with ID 58076db2-28b6-423b-ba39-a797193017f7 already exists",
8002+
},
8003+
{
8004+
name: "sni",
8005+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/sni-initial.yaml",
8006+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/sni-final.yaml",
8007+
errorExpected: "error: SNI with ID 87b6a97e-f3f7-4c47-857a-7464cb9e202b already exists",
8008+
},
8009+
{
8010+
name: "upstream",
8011+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/upstream-initial.yaml",
8012+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/upstream-final.yaml",
8013+
errorExpected: "error: upstream with ID 87b6a97e-f3f7-4c47-857a-7464cb9e202b already exists",
8014+
},
8015+
}
8016+
8017+
for _, tc := range tests {
8018+
t.Run(tc.name, func(t *testing.T) {
8019+
reset(t)
8020+
err := sync(ctx, tc.initialStateFile)
8021+
require.NoError(t, err)
8022+
8023+
err = sync(ctx, tc.targetStateFile, "--select-tag", "after")
8024+
require.Error(t, err)
8025+
assert.ErrorContains(t, err, tc.errorExpected)
8026+
})
8027+
}
8028+
}
8029+
8030+
// test scope:
8031+
//
8032+
// - >=2.8.0
8033+
//
8034+
// Separated since oauth is not supported in konnect
8035+
func Test_Sync_Avoid_Oauth_Overwrite_On_Select_Tag_Mismatch_With_ID(t *testing.T) {
8036+
runWhen(t, "kong", ">=2.8.0")
8037+
setup(t)
8038+
8039+
ctx := context.Background()
8040+
8041+
tests := []struct {
8042+
name string
8043+
initialStateFile string
8044+
targetStateFile string
8045+
errorExpected string
8046+
}{
8047+
{
8048+
name: "oauth",
8049+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/oauth-initial.yaml",
8050+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/oauth-final.yaml",
8051+
errorExpected: "error: oauth2 credential with ID f3c51133-2e0c-4049-b45d-fd9309dcba9a already exists",
8052+
},
8053+
}
8054+
8055+
for _, tc := range tests {
8056+
t.Run(tc.name, func(t *testing.T) {
8057+
reset(t)
8058+
err := sync(ctx, tc.initialStateFile)
8059+
require.NoError(t, err)
8060+
8061+
err = sync(ctx, tc.targetStateFile, "--select-tag", "after")
8062+
require.Error(t, err)
8063+
assert.ErrorContains(t, err, tc.errorExpected)
8064+
})
8065+
}
8066+
}
8067+
8068+
// test scope:
8069+
// - konnect
8070+
func Test_Sync_Avoid_Overwrite_On_Select_Tag_Mismatch_With_ID_Konnect(t *testing.T) {
8071+
runWhenKonnect(t)
8072+
setup(t)
8073+
8074+
ctx := context.Background()
8075+
8076+
tests := []struct {
8077+
name string
8078+
initialStateFile string
8079+
targetStateFile string
8080+
errorExpected string
8081+
}{
8082+
{
8083+
name: "partial",
8084+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/partial-initial.yaml",
8085+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/partial-final.yaml",
8086+
errorExpected: "error: partial with ID 13dc230d-d65e-439a-9f05-9fd71abfee4d already exists",
8087+
},
8088+
{
8089+
name: "consumer-group",
8090+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/consumer-group-initial.yaml", //nolint:lll
8091+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/consumer-group-final.yaml",
8092+
errorExpected: "error: consumer-group with ID 5a1e49a8-2536-41fa-a4e9-605bf218a4fa already exists",
8093+
},
8094+
}
8095+
8096+
for _, tc := range tests {
8097+
t.Run(tc.name, func(t *testing.T) {
8098+
reset(t)
8099+
err := sync(ctx, tc.initialStateFile)
8100+
require.NoError(t, err)
8101+
8102+
err = sync(ctx, tc.targetStateFile, "--select-tag", "after")
8103+
require.Error(t, err)
8104+
assert.ErrorContains(t, err, tc.errorExpected)
8105+
})
8106+
}
8107+
}
8108+
8109+
// test scope:
8110+
//
8111+
// - >=3.0.0
8112+
//
8113+
// This is necessary since vault was in beta till v3.0.0
8114+
func Test_Sync_Avoid_Vault_Overwrite_On_Select_Tag_Mismatch_With_ID(t *testing.T) {
8115+
runWhenKongOrKonnect(t, ">=3.0.0")
8116+
setup(t)
8117+
8118+
ctx := context.Background()
8119+
8120+
tests := []struct {
8121+
name string
8122+
initialStateFile string
8123+
targetStateFile string
8124+
errorExpected string
8125+
}{
8126+
{
8127+
name: "vault",
8128+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/vault-initial.yaml",
8129+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/vault-final.yaml",
8130+
errorExpected: "error: vault with ID 87b6a97e-f3f7-4c47-857a-7464cb9e202b already exists",
8131+
},
8132+
}
8133+
8134+
for _, tc := range tests {
8135+
t.Run(tc.name, func(t *testing.T) {
8136+
reset(t)
8137+
err := sync(ctx, tc.initialStateFile)
8138+
require.NoError(t, err)
8139+
8140+
err = sync(ctx, tc.targetStateFile, "--select-tag", "after")
8141+
require.Error(t, err)
8142+
assert.ErrorContains(t, err, tc.errorExpected)
8143+
})
8144+
}
8145+
}
8146+
8147+
// test scope:
8148+
//
8149+
// - >=3.10.0+enterprise
8150+
func Test_Sync_Avoid_Overwrite_for_Partial_On_Select_Tag_Mismatch_With_ID_Enterprise(t *testing.T) {
8151+
runWhen(t, "enterprise", ">=3.10.0")
8152+
setup(t)
8153+
8154+
ctx := context.Background()
8155+
8156+
tests := []struct {
8157+
name string
8158+
initialStateFile string
8159+
targetStateFile string
8160+
errorExpected string
8161+
}{
8162+
{
8163+
name: "partial",
8164+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/partial-initial.yaml",
8165+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/partial-final.yaml",
8166+
errorExpected: "error: partial with ID 13dc230d-d65e-439a-9f05-9fd71abfee4d already exists",
8167+
},
8168+
}
8169+
8170+
for _, tc := range tests {
8171+
t.Run(tc.name, func(t *testing.T) {
8172+
reset(t)
8173+
err := sync(ctx, tc.initialStateFile)
8174+
require.NoError(t, err)
8175+
8176+
err = sync(ctx, tc.targetStateFile, "--select-tag", "after")
8177+
require.Error(t, err)
8178+
assert.ErrorContains(t, err, tc.errorExpected)
8179+
})
8180+
}
8181+
}
8182+
8183+
// test scope:
8184+
//
8185+
// - >=2.8.0+enterprise
8186+
func Test_Sync_Avoid_Consumer_Group_Overwrite_On_Select_Tag_Mismatch_With_ID_Enterprise(t *testing.T) {
8187+
runWhen(t, "enterprise", ">=2.8.0")
8188+
setup(t)
8189+
8190+
ctx := context.Background()
8191+
8192+
tests := []struct {
8193+
name string
8194+
initialStateFile string
8195+
targetStateFile string
8196+
errorExpected string
8197+
}{
8198+
{
8199+
name: "consumer-group",
8200+
initialStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/consumer-group-initial.yaml", //nolint:lll
8201+
targetStateFile: "testdata/sync/040-avoid-entity-rewrite-with-id-on-select-tag-mismatch/consumer-group-final.yaml",
8202+
errorExpected: "error: consumer-group with ID 5a1e49a8-2536-41fa-a4e9-605bf218a4fa already exists",
8203+
},
8204+
}
8205+
8206+
for _, tc := range tests {
8207+
t.Run(tc.name, func(t *testing.T) {
8208+
reset(t)
8209+
err := sync(ctx, tc.initialStateFile)
8210+
require.NoError(t, err)
8211+
8212+
err = sync(ctx, tc.targetStateFile, "--select-tag", "after")
8213+
require.Error(t, err)
8214+
assert.ErrorContains(t, err, tc.errorExpected)
8215+
})
8216+
}
8217+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
_format_version: "3.0"
2+
consumers:
3+
- acls:
4+
- group: second consumers ACL
5+
id: f2be545c-45c5-46e2-8acf-00ff2d899073
6+
tags:
7+
- after
8+
custom_id: custom_id_2
9+
id: 17d847fb-7aeb-4cb7-adb5-eccdd0ff1d43
10+
username: consumer2
11+
tags:
12+
- after
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
_format_version: "3.0"
2+
consumers:
3+
- acls:
4+
- group: consumers ACL
5+
id: f2be545c-45c5-46e2-8acf-00ff2d899073
6+
tags:
7+
- before
8+
custom_id: custom_id_1
9+
id: 27d847fb-7aeb-4cb7-adb5-eccdd0ff1d42
10+
username: consumer1
11+
tags:
12+
- before
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
_format_version: "3.0"
2+
consumers:
3+
- basicauth_credentials:
4+
- id: 7dd67c9c-f591-4216-9718-b320174193bb
5+
password: 22c435b847bb2114d21b02022c796e708acefe31
6+
tags:
7+
- after
8+
username: user2
9+
custom_id: consumer-2
10+
id: c4f969ef-a249-4ffb-9d2e-9c511cfa9f68
11+
username: consumer2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
_format_version: "3.0"
2+
consumers:
3+
- basicauth_credentials:
4+
- id: 7dd67c9c-f591-4216-9718-b320174193bb
5+
password: 22c435b847bb2114d21b02022c796e708acefe31
6+
tags:
7+
- before
8+
username: user1
9+
custom_id: consumer-1
10+
id: c4f969ef-a249-4ffb-9d2e-9c511cfa9f67
11+
username: consumer1

0 commit comments

Comments
 (0)