From 15cad639256366a50d70022cae0b58e32200ae2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Burzy=C5=84ski?= Date: Wed, 19 Jul 2023 13:44:18 +0200 Subject: [PATCH 1/2] feat: handle certificates:snis relation for Konnect --- tests/integration/sync_test.go | 61 +++++++++++++++++++ .../initial.yaml | 55 +++++++++++++++++ .../update.yaml | 55 +++++++++++++++++ types/certificate.go | 42 +++++++++---- types/core.go | 4 +- 5 files changed, 204 insertions(+), 13 deletions(-) create mode 100644 tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/initial.yaml create mode 100644 tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/update.yaml diff --git a/tests/integration/sync_test.go b/tests/integration/sync_test.go index 598266d7e..2c769953a 100644 --- a/tests/integration/sync_test.go +++ b/tests/integration/sync_test.go @@ -3458,3 +3458,64 @@ func Test_Sync_UpdateWithExplicitIDsWithNoNames(t *testing.T) { }, }, ignoreFieldsIrrelevantForIDsTests) } + +// test scope: +// - 3.0.0+ +// - konnect +func Test_Sync_CreateCertificateWithSNIs(t *testing.T) { + runWhenKongOrKonnect(t, ">=3.0.0") + + client, err := getTestClient() + if err != nil { + t.Errorf(err.Error()) + } + + err = sync("testdata/sync/023-create-and-update-certificate-with-snis/initial.yaml") + require.NoError(t, err) + + // To ignore noise, we ignore the Key and Cert fields because they are not relevant for this test. + ignoredFields := []cmp.Option{ + cmpopts.IgnoreFields( + kong.Certificate{}, + "Key", + "Cert", + ), + } + + testKongState(t, client, false, utils.KongRawState{ + Certificates: []*kong.Certificate{ + { + ID: kong.String("c75a775b-3a32-4b73-8e05-f68169c23941"), + Tags: kong.StringSlice("before"), + }, + }, + SNIs: []*kong.SNI{ + { + Name: kong.String("example.com"), + Certificate: &kong.Certificate{ + ID: kong.String("c75a775b-3a32-4b73-8e05-f68169c23941"), + }, + }, + }, + }, ignoredFields) + + err = sync("testdata/sync/023-create-and-update-certificate-with-snis/update.yaml") + require.NoError(t, err) + + testKongState(t, client, false, utils.KongRawState{ + Certificates: []*kong.Certificate{ + { + ID: kong.String("c75a775b-3a32-4b73-8e05-f68169c23941"), + Tags: kong.StringSlice("after"), // Tag should be updated. + }, + }, + SNIs: []*kong.SNI{ + { + Name: kong.String("example.com"), + Certificate: &kong.Certificate{ + ID: kong.String("c75a775b-3a32-4b73-8e05-f68169c23941"), + }, + }, + }, + }, ignoredFields) +} diff --git a/tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/initial.yaml b/tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/initial.yaml new file mode 100644 index 000000000..65f2781fd --- /dev/null +++ b/tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/initial.yaml @@ -0,0 +1,55 @@ +_format_version: "3.0" +certificates: + - id: 13c562a1-191c-4464-9b18-e5222b46035b + cert: | + -----BEGIN CERTIFICATE----- + MIIC1jCCAb4CCQCt23nwvxSCvjANBgkqhkiG9w0BAQsFADAtMRYwFAYDVQQDDA0q + LmV4YW1wbGUuY29tMRMwEQYDVQQKDAprb25naHEub3JnMB4XDTE4MTIzMTIwMTkw + MVoXDTE5MTIzMTIwMTkwMVowLTEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTETMBEG + A1UECgwKa29uZ2hxLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB + AKj/2r1AXo9x+2Csrd0SHbpnzuW+xYqgsd+YA9ZrZNV7SZGSbaZymsRMz8wg5OIU + iUik2GM1749/lYvojLFStBPy9UY/gd++5f3wLp4xHiI+IU2XQ97otXKGfyh36RmN + dKDqPLN8BG3R346s/y1GOulFvLthYmZVYF9ufHiqimfEDSbTt79P5C3X0Rw/afK1 + GjHEJPCB/XkZ6lkcEyL6LqZI5oBigDqa9hI/nWLxEzfm8pgosiS38p9TAijlOkpm + tX2p2b1pktlNIy3rxsqj6IynN9Wc7FpV1N4HoPKV7vQQ08hjwW6WfanVthaaJosj + Vr2TBCJ1ltAmsb+5B2VPYVkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAnByTyQfV + 3LkwuoWS57CWcqbNw/cHnv/ChzmIv+6mIXvDBSvCgrPZIWCpaCfYRG6R51E44fr/ + 8V1AKT0Zt15DjrXEEcIGQgsIDO91/wlL091fTAUzSbL0yt7HTlm8sX6xndPNAZrq + cfcIPVMxknfqPy2VqS4IrNC03pHkDKtokphBjVUlkiWsdcq+fHYbS2xL2d1Da/uN + hX/iwgo+v5gOF5xtaXx7D7L3Cf+MHb/MOXWPfYXNiTpSBVX8/Kx5RP+QLI16nWvw + lrijTlXZFR8NIZBrCo/QZ2cNbUAbN3R0n+/kMFubxBL8WEm6Qhi9jBjbJeDMspd8 + C+/TZJQMpx5vyA== + -----END CERTIFICATE----- + key: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCo/9q9QF6Pcftg + rK3dEh26Z87lvsWKoLHfmAPWa2TVe0mRkm2mcprETM/MIOTiFIlIpNhjNe+Pf5WL + 6IyxUrQT8vVGP4HfvuX98C6eMR4iPiFNl0Pe6LVyhn8od+kZjXSg6jyzfARt0d+O + rP8tRjrpRby7YWJmVWBfbnx4qopnxA0m07e/T+Qt19EcP2nytRoxxCTwgf15GepZ + HBMi+i6mSOaAYoA6mvYSP51i8RM35vKYKLIkt/KfUwIo5TpKZrV9qdm9aZLZTSMt + 68bKo+iMpzfVnOxaVdTeB6Dyle70ENPIY8Fuln2p1bYWmiaLI1a9kwQidZbQJrG/ + uQdlT2FZAgMBAAECggEAVnyRcda2Tcy0K7ZTR9aUlie370VhDN/OB7JhDGNreAEf + FjuMl+kAoUL5+OpAmB6QXzfVcXhRv+s4GiCJl9nORINK2Id5rIqiYwF+qgBS/o0z + N+UYm8QVz6Va/9fV1/jXXd5h8Cygi58jPH32HTJaxbSlsHNXCy3YIx6E3q/QIueR + 6ZdSXPqMEqxEU19M9jW8UeiRFrpmcyYxVpfxYIY/+O9lYjSpaeLs7hZeCP9PqWXA + Sxz2CnHZ8BcsDxAyuoHoVw+kjMpUMvA3sD4lwkV8BAYzfLmQf6PR83SFNsrE8XYu + /8WnQuCuytcl8Zg55R6tGCvf6Wyyf+MDRPwv/43QMQKBgQDbqK9Dq54k+EHgSNnP + K6AhNjFd6aqcNC1kom/sSlWBnuA/BEqJMECr8S2dYvzONUPPfX5NNUjB4Vw3Qw7a + pUgKuCQoVpzpZs5m1bk78itWDtA84LjkXfdejnUXVw/aVxLCM5QV9aEkm/dEWWMI + P1WTYVoWoZCLlEE08q0AvZQcdQKBgQDE9ZCmc6ncmhnQftuRj5PnXG2a79MLCT61 + sCEBDVvkcUJVqbzwGRLwRkdIzLgvmiuP+SukHgyfr8/RXG99xEW/q7NDrtEcqfXP + 19QXwOIp5NwDnOXyAlXiyZ50fCE2tSo2wP485+NIhmKj5Zt6y/DL6Qbc5k73XmK4 + KX5Ej15k1QKBgQCc6KeiIFLMt+Ze78tfORue/dZP7p3oDUGr1Hk9AnCIMlSfz1Hr + I+Per17VQaOzLcttyYhSYNDDZld4RlezCkQnHBkAE7bs53pjbSJv1vLr+5L3GdQZ + laIiEoNEE/YIExEcVrne4eKlgyAj2/JpLszThcRTzD+z5UibKQs6LzJBDQKBgDVa + dAGzCUt57w48nwvyQdWFgydaWef+bB9Zg8c+MCtUxuxfm4/Kqwetcff1hNtYPv60 + N68weKj1Pi1vhcAi3+YJA/mMrJbAL5dK1uhMVreUiEjuQpfpLAzQIv1Y9sJUFwhY + BUbIZhgqVyQguZptDmCeUj6aoL9/sOxESTEXSTG1AoGBAMQ5iJZMsdLCERv0+6Y1 + F/t/YSW8cugB3vdV9jHZuosoprz48p92pYP8OdQc70H5hZt53hoYNgYFSd+MU6H1 + hJCaXTsiP4IUmBjiwzSp3o1ctP8lWvnyJpAadYdDhaDaAAoaMjCo9cm5OMwc8t8x + hwAPXV2cgWH8fPcT9NLAcwWk + -----END PRIVATE KEY----- + tags: + - before + snis: + - name: example.com diff --git a/tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/update.yaml b/tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/update.yaml new file mode 100644 index 000000000..7256a7d1b --- /dev/null +++ b/tests/integration/testdata/sync/023-create-and-update-certificate-with-snis/update.yaml @@ -0,0 +1,55 @@ +_format_version: "3.0" +certificates: + - id: 13c562a1-191c-4464-9b18-e5222b46035b + cert: | + -----BEGIN CERTIFICATE----- + MIIC1jCCAb4CCQCt23nwvxSCvjANBgkqhkiG9w0BAQsFADAtMRYwFAYDVQQDDA0q + LmV4YW1wbGUuY29tMRMwEQYDVQQKDAprb25naHEub3JnMB4XDTE4MTIzMTIwMTkw + MVoXDTE5MTIzMTIwMTkwMVowLTEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTETMBEG + A1UECgwKa29uZ2hxLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB + AKj/2r1AXo9x+2Csrd0SHbpnzuW+xYqgsd+YA9ZrZNV7SZGSbaZymsRMz8wg5OIU + iUik2GM1749/lYvojLFStBPy9UY/gd++5f3wLp4xHiI+IU2XQ97otXKGfyh36RmN + dKDqPLN8BG3R346s/y1GOulFvLthYmZVYF9ufHiqimfEDSbTt79P5C3X0Rw/afK1 + GjHEJPCB/XkZ6lkcEyL6LqZI5oBigDqa9hI/nWLxEzfm8pgosiS38p9TAijlOkpm + tX2p2b1pktlNIy3rxsqj6IynN9Wc7FpV1N4HoPKV7vQQ08hjwW6WfanVthaaJosj + Vr2TBCJ1ltAmsb+5B2VPYVkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAnByTyQfV + 3LkwuoWS57CWcqbNw/cHnv/ChzmIv+6mIXvDBSvCgrPZIWCpaCfYRG6R51E44fr/ + 8V1AKT0Zt15DjrXEEcIGQgsIDO91/wlL091fTAUzSbL0yt7HTlm8sX6xndPNAZrq + cfcIPVMxknfqPy2VqS4IrNC03pHkDKtokphBjVUlkiWsdcq+fHYbS2xL2d1Da/uN + hX/iwgo+v5gOF5xtaXx7D7L3Cf+MHb/MOXWPfYXNiTpSBVX8/Kx5RP+QLI16nWvw + lrijTlXZFR8NIZBrCo/QZ2cNbUAbN3R0n+/kMFubxBL8WEm6Qhi9jBjbJeDMspd8 + C+/TZJQMpx5vyA== + -----END CERTIFICATE----- + key: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCo/9q9QF6Pcftg + rK3dEh26Z87lvsWKoLHfmAPWa2TVe0mRkm2mcprETM/MIOTiFIlIpNhjNe+Pf5WL + 6IyxUrQT8vVGP4HfvuX98C6eMR4iPiFNl0Pe6LVyhn8od+kZjXSg6jyzfARt0d+O + rP8tRjrpRby7YWJmVWBfbnx4qopnxA0m07e/T+Qt19EcP2nytRoxxCTwgf15GepZ + HBMi+i6mSOaAYoA6mvYSP51i8RM35vKYKLIkt/KfUwIo5TpKZrV9qdm9aZLZTSMt + 68bKo+iMpzfVnOxaVdTeB6Dyle70ENPIY8Fuln2p1bYWmiaLI1a9kwQidZbQJrG/ + uQdlT2FZAgMBAAECggEAVnyRcda2Tcy0K7ZTR9aUlie370VhDN/OB7JhDGNreAEf + FjuMl+kAoUL5+OpAmB6QXzfVcXhRv+s4GiCJl9nORINK2Id5rIqiYwF+qgBS/o0z + N+UYm8QVz6Va/9fV1/jXXd5h8Cygi58jPH32HTJaxbSlsHNXCy3YIx6E3q/QIueR + 6ZdSXPqMEqxEU19M9jW8UeiRFrpmcyYxVpfxYIY/+O9lYjSpaeLs7hZeCP9PqWXA + Sxz2CnHZ8BcsDxAyuoHoVw+kjMpUMvA3sD4lwkV8BAYzfLmQf6PR83SFNsrE8XYu + /8WnQuCuytcl8Zg55R6tGCvf6Wyyf+MDRPwv/43QMQKBgQDbqK9Dq54k+EHgSNnP + K6AhNjFd6aqcNC1kom/sSlWBnuA/BEqJMECr8S2dYvzONUPPfX5NNUjB4Vw3Qw7a + pUgKuCQoVpzpZs5m1bk78itWDtA84LjkXfdejnUXVw/aVxLCM5QV9aEkm/dEWWMI + P1WTYVoWoZCLlEE08q0AvZQcdQKBgQDE9ZCmc6ncmhnQftuRj5PnXG2a79MLCT61 + sCEBDVvkcUJVqbzwGRLwRkdIzLgvmiuP+SukHgyfr8/RXG99xEW/q7NDrtEcqfXP + 19QXwOIp5NwDnOXyAlXiyZ50fCE2tSo2wP485+NIhmKj5Zt6y/DL6Qbc5k73XmK4 + KX5Ej15k1QKBgQCc6KeiIFLMt+Ze78tfORue/dZP7p3oDUGr1Hk9AnCIMlSfz1Hr + I+Per17VQaOzLcttyYhSYNDDZld4RlezCkQnHBkAE7bs53pjbSJv1vLr+5L3GdQZ + laIiEoNEE/YIExEcVrne4eKlgyAj2/JpLszThcRTzD+z5UibKQs6LzJBDQKBgDVa + dAGzCUt57w48nwvyQdWFgydaWef+bB9Zg8c+MCtUxuxfm4/Kqwetcff1hNtYPv60 + N68weKj1Pi1vhcAi3+YJA/mMrJbAL5dK1uhMVreUiEjuQpfpLAzQIv1Y9sJUFwhY + BUbIZhgqVyQguZptDmCeUj6aoL9/sOxESTEXSTG1AoGBAMQ5iJZMsdLCERv0+6Y1 + F/t/YSW8cugB3vdV9jHZuosoprz48p92pYP8OdQc70H5hZt53hoYNgYFSd+MU6H1 + hJCaXTsiP4IUmBjiwzSp3o1ctP8lWvnyJpAadYdDhaDaAAoaMjCo9cm5OMwc8t8x + hwAPXV2cgWH8fPcT9NLAcwWk + -----END PRIVATE KEY----- + tags: + - after # Only this changes between initial and updated config. + snis: + - name: example.com diff --git a/types/certificate.go b/types/certificate.go index 5349c7ad9..83811681b 100644 --- a/types/certificate.go +++ b/types/certificate.go @@ -12,7 +12,8 @@ import ( // certificateCRUD implements crud.Actions interface. type certificateCRUD struct { - client *kong.Client + client *kong.Client + isKonnect bool } func certificateFromStruct(arg crud.Event) *state.Certificate { @@ -30,6 +31,9 @@ func certificateFromStruct(arg crud.Event) *state.Certificate { func (s *certificateCRUD) Create(ctx context.Context, arg ...crud.Arg) (crud.Arg, error) { event := crud.EventFromArg(arg[0]) certificate := certificateFromStruct(event) + if s.isKonnect { + certificate.SNIs = nil + } createdCertificate, err := s.client.Certificates.Create(ctx, &certificate.Certificate) if err != nil { return nil, err @@ -59,6 +63,9 @@ func (s *certificateCRUD) Update(ctx context.Context, arg ...crud.Arg) (crud.Arg event := crud.EventFromArg(arg[0]) certificate := certificateFromStruct(event) + if s.isKonnect { + certificate.SNIs = nil + } updatedCertificate, err := s.client.Certificates.Create(ctx, &certificate.Certificate) if err != nil { return nil, err @@ -70,6 +77,8 @@ type certificateDiffer struct { kind crud.Kind currentState, targetState *state.KongState + + isKonnect bool } func (d *certificateDiffer) Deletes(handler func(crud.Event) error) error { @@ -138,6 +147,13 @@ func (d *certificateDiffer) createUpdateCertificate( certificateCopy := &state.Certificate{Certificate: *certificate.DeepCopy()} currentCertificate, err := d.currentState.Certificates.Get(*certificate.ID) + if d.isKonnect { + certificateCopy.SNIs = nil + if currentCertificate != nil { + currentCertificate.SNIs = nil + } + } + if errors.Is(err, state.ErrNotFound) { // certificate not present, create it return &crud.Event{ @@ -161,18 +177,20 @@ func (d *certificateDiffer) createUpdateCertificate( // To work around this issues, we set SNIs on certificates here using the // current certificate's SNI list. If there are changes to the SNIs, // subsequent actions on the SNI objects will handle those. - currentSNIs, err := d.currentState.SNIs.GetAllByCertID(*currentCertificate.ID) - if err != nil { - return nil, fmt.Errorf("error looking up current certificate SNIs %q: %w", - certificate.FriendlyName(), err) - } - sniNames := make([]*string, 0) - for _, s := range currentSNIs { - sniNames = append(sniNames, s.Name) - } + if !d.isKonnect { + currentSNIs, err := d.currentState.SNIs.GetAllByCertID(*currentCertificate.ID) + if err != nil { + return nil, fmt.Errorf("error looking up current certificate SNIs %q: %w", + certificate.FriendlyName(), err) + } + sniNames := make([]*string, 0) + for _, s := range currentSNIs { + sniNames = append(sniNames, s.Name) + } - certificateCopy.SNIs = sniNames - currentCertificate.SNIs = sniNames + certificateCopy.SNIs = sniNames + currentCertificate.SNIs = sniNames + } return &crud.Event{ Op: crud.Update, Kind: d.kind, diff --git a/types/core.go b/types/core.go index b914673bd..9d27a2283 100644 --- a/types/core.go +++ b/types/core.go @@ -336,7 +336,8 @@ func NewEntity(t EntityType, opts EntityOpts) (Entity, error) { return entityImpl{ typ: Certificate, crudActions: &certificateCRUD{ - client: opts.KongClient, + client: opts.KongClient, + isKonnect: opts.IsKonnect, }, postProcessActions: &certificatePostAction{ currentState: opts.CurrentState, @@ -345,6 +346,7 @@ func NewEntity(t EntityType, opts EntityOpts) (Entity, error) { kind: entityTypeToKind(Certificate), currentState: opts.CurrentState, targetState: opts.TargetState, + isKonnect: opts.IsKonnect, }, }, nil case CACertificate: From 26a4f49fdd3facff65318e2f37bdd0b70e27f4a2 Mon Sep 17 00:00:00 2001 From: Gabriele Gerbino Date: Wed, 19 Jul 2023 14:48:05 +0200 Subject: [PATCH 2/2] tests: restrict diff test scope to avoid failure due to schema changes --- tests/integration/diff_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/diff_test.go b/tests/integration/diff_test.go index 15db7aec3..65e81755b 100644 --- a/tests/integration/diff_test.go +++ b/tests/integration/diff_test.go @@ -617,7 +617,7 @@ func Test_Diff_Masked_NewerThan3x(t *testing.T) { for k, v := range tc.envVars { t.Setenv(k, v) } - runWhen(t, "kong", ">=3.1.0") + runWhen(t, "kong", ">=3.1.0 <3.4.0") teardown := setup(t) defer teardown(t) @@ -740,7 +740,7 @@ func Test_Diff_Unmasked_NewerThan3x(t *testing.T) { for k, v := range tc.envVars { t.Setenv(k, v) } - runWhen(t, "kong", ">=3.1.0") + runWhen(t, "kong", ">=3.1.0 <3.4.0") teardown := setup(t) defer teardown(t)