Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(diff): clear unmatching deprecated fields #145

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 27 additions & 20 deletions pkg/diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"github.com/kong/go-database-reconciler/pkg/crud"
"github.com/kong/go-database-reconciler/pkg/konnect"
"github.com/kong/go-database-reconciler/pkg/state"
"github.com/kong/go-database-reconciler/pkg/types"

Check failure on line 17 in pkg/diff/diff.go

View workflow job for this annotation

GitHub Actions / test

could not import github.com/kong/go-database-reconciler/pkg/types (-: # github.com/kong/go-database-reconciler/pkg/types
"github.com/kong/go-database-reconciler/pkg/utils"
"github.com/kong/go-kong/kong"
)
Expand Down Expand Up @@ -612,28 +612,35 @@
pluginCopy := &state.Plugin{Plugin: *plugin.DeepCopy()}
e.Obj = pluginCopy

exists, err := utils.WorkspaceExists(ctx, sc.kongClient)
if err == nil && exists {
var schema map[string]interface{}
schema, err = sc.kongClient.Plugins.GetFullSchema(ctx, pluginCopy.Plugin.Name)
if err != nil {
return nil, err
}
if oldPlugin, ok := e.OldObj.(*state.Plugin); ok {
oldPluginCopy := &state.Plugin{Plugin: *oldPlugin.DeepCopy()}
e.OldObj = oldPluginCopy

if exists, _ := utils.WorkspaceExists(ctx, sc.kongClient); exists {
var schema map[string]interface{}
schema, err = sc.kongClient.Plugins.GetFullSchema(ctx, pluginCopy.Plugin.Name)
if err != nil {
return nil, err
}

// fill defaults and auto fields for the configuration that will be used for the diff
newPlugin := &pluginCopy.Plugin
if err := kong.FillPluginsDefaults(newPlugin, schema); err != nil {
return nil, fmt.Errorf("failed processing auto fields: %w", err)
}
// fill defaults and auto fields for the configuration that will be used for the diff
if err := kong.FillPluginsDefaults(&pluginCopy.Plugin, schema); err != nil {
return nil, fmt.Errorf("failed processing auto fields: %w", err)
}

// only fill auto fields for the configuration sent to Kong
// this is done because we want to avoid Kong to auto generate fields, which
// would make decK's configuration no longer fully "declarative"
if err := kong.FillPluginsDefaultsWithOpts(&plugin.Plugin, schema, kong.FillRecordOptions{
FillDefaults: false,
FillAuto: true,
}); err != nil {
return nil, fmt.Errorf("failed processing auto fields: %w", err)
}

// only fill auto fields for the configuration sent to Kong
// this is done because we want to avoid Kong to auto generate fields, which
// would make decK's configuration no longer fully "declarative"
if err := kong.FillPluginsDefaultsWithOpts(&plugin.Plugin, schema, kong.FillRecordOptions{
FillDefaults: false,
FillAuto: true,
}); err != nil {
return nil, fmt.Errorf("failed processing auto fields: %w", err)
if err := kong.ClearUnmatchingDeprecations(&pluginCopy.Plugin, &oldPluginCopy.Plugin, schema); err != nil {

Check failure on line 641 in pkg/diff/diff.go

View workflow job for this annotation

GitHub Actions / test

undefined: kong.ClearUnmatchingDeprecations (typecheck)
return nil, fmt.Errorf("failed processing auto fields: %w", err)
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/types/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@
return nil, fmt.Errorf("failed processing auto fields: %w", err)
}

if err := kong.ClearUnmatchingDeprecations(&pluginWithDefaults.Plugin, &currentPlugin.Plugin, schema); err != nil {

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / test

undefined: kong.ClearUnmatchingDeprecations (typecheck)

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / test

undefined: kong.ClearUnmatchingDeprecations) (typecheck)

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / integration-tests / integration (kong:2.8)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / integration-tests / integration (kong:3.4)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / integration-tests / integration (kong:3.5)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / integration-tests / integration (kong:3.6)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / integration-tests / integration (kong:3.7)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / integration-tests / integration (kong/kong:master)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / enterprise-integration-tests / integration (kong/kong-gateway:2.8)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / enterprise-integration-tests / integration (kong/kong-gateway:3.4)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / enterprise-integration-tests / integration (kong/kong-gateway:3.5)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / enterprise-integration-tests / integration (kong/kong-gateway:3.6)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / enterprise-integration-tests / integration (kong/kong-gateway:3.7)

undefined: kong.ClearUnmatchingDeprecations

Check failure on line 189 in pkg/types/plugin.go

View workflow job for this annotation

GitHub Actions / enterprise-integration-tests / integration (kong/kong-gateway-dev:latest)

undefined: kong.ClearUnmatchingDeprecations
return nil, fmt.Errorf("failed clearing unmatching deprecations fields: %w", err)
}

if !currentPlugin.EqualWithOpts(pluginWithDefaults, false, true, false) {
return &crud.Event{
Op: crud.Update,
Expand Down
237 changes: 237 additions & 0 deletions tests/integration/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,190 @@ Summary:
"errors": []
}

`
expectedOutputPluginUpdateNoChange = `Summary:
Created: 0
Updated: 0
Deleted: 0
`

expectedOutputPluginUpdateChangedNewFields = `updating plugin rate-limiting-advanced (global) {
"config": {
"consumer_groups": null,
"dictionary_name": "kong_rate_limiting_counters",
"disable_penalty": false,
"enforce_consumer_groups": false,
"error_code": 429,
"error_message": "API rate limit exceeded",
"header_name": null,
"hide_client_headers": false,
"identifier": "consumer",
"limit": [
10
],
"namespace": "ZEz47TWgUrv01HenyQBQa8io06MWsp0L",
"path": null,
"redis": {
"cluster_max_redirections": 5,
"cluster_nodes": [
{
"ip": "127.0.1.0",
- "port": 6379
+ "port": 7379
},
{
"ip": "127.0.1.0",
- "port": 6380
+ "port": 7380
},
{
"ip": "127.0.1.0",
- "port": 6381
+ "port": 7381
}
],
- "connect_timeout": 2000,
+ "connect_timeout": 2005,
"connection_is_proxied": false,
"database": 0,
"host": "127.0.0.5",
"keepalive_backlog": null,
"keepalive_pool_size": 256,
"password": null,
"port": 6380,
- "read_timeout": 2000,
+ "read_timeout": 2006,
- "send_timeout": 2000,
+ "send_timeout": 2007,
"sentinel_master": "mymaster",
"sentinel_nodes": [
{
"host": "127.0.2.0",
- "port": 6379
+ "port": 8379
},
{
"host": "127.0.2.0",
- "port": 6380
+ "port": 8380
},
{
"host": "127.0.2.0",
- "port": 6381
+ "port": 8381
}
],
"sentinel_password": null,
"sentinel_role": "master",
"sentinel_username": null,
"server_name": null,
"ssl": false,
"ssl_verify": false,
"username": null
},
"retry_after_jitter_max": 0,
"strategy": "redis",
"sync_rate": 10,
"window_size": [
60
],
"window_type": "sliding"
},
"enabled": true,
"id": "a1368a28-cb5c-4eee-86d8-03a6bdf94b5e",
"name": "rate-limiting-advanced",
"protocols": [
"grpc",
"grpcs",
"http",
"https"
]
}

Summary:
Created: 0
Updated: 1
Deleted: 0
`
expectedOutputPluginUpdateChangedOldFields = `updating plugin rate-limiting-advanced (global) {
"config": {
"consumer_groups": null,
"dictionary_name": "kong_rate_limiting_counters",
"disable_penalty": false,
"enforce_consumer_groups": false,
"error_code": 429,
"error_message": "API rate limit exceeded",
"header_name": null,
"hide_client_headers": false,
"identifier": "consumer",
"limit": [
10
],
"namespace": "ZEz47TWgUrv01HenyQBQa8io06MWsp0L",
"path": null,
"redis": {
"cluster_addresses": [
- "127.0.1.0:6379",
+ "127.0.1.0:7379",
- "127.0.1.0:6380",
+ "127.0.1.0:7380",
- "127.0.1.0:6381"
+ "127.0.1.0:7381"
],
"cluster_max_redirections": 5,
"connect_timeout": 2000,
"connection_is_proxied": false,
"database": 0,
"host": "127.0.0.5",
"keepalive_backlog": null,
"keepalive_pool_size": 256,
"password": null,
"port": 6380,
"read_timeout": 2000,
"send_timeout": 2000,
"sentinel_addresses": [
- "127.0.2.0:6379",
+ "127.0.2.0:8379",
- "127.0.2.0:6380",
+ "127.0.2.0:8380",
- "127.0.2.0:6381"
+ "127.0.2.0:8381"
],
"sentinel_master": "mymaster",
"sentinel_password": null,
"sentinel_role": "master",
"sentinel_username": null,
"server_name": null,
"ssl": false,
"ssl_verify": false,
- "timeout": 2000,
+ "timeout": 2007,
"username": null
},
"retry_after_jitter_max": 0,
"strategy": "redis",
- "sync_rate": 10,
+ "sync_rate": 11,
"window_size": [
60
],
"window_type": "sliding"
},
"enabled": true,
"id": "a1368a28-cb5c-4eee-86d8-03a6bdf94b5e",
"name": "rate-limiting-advanced",
"protocols": [
"grpc",
"grpcs",
"http",
"https"
]
}

Summary:
Created: 0
Updated: 1
Deleted: 0
`
)

Expand Down Expand Up @@ -742,3 +926,56 @@ func Test_Diff_Unmasked_NewerThan3x(t *testing.T) {
})
}
}

func Test_Diff_PluginUpdate_NewerThan3x(t *testing.T) {
runWhenEnterpriseOrKonnect(t, ">=3.8.0")
setup(t)

tests := []struct {
name string
initialStateFile string
stateFile string
expectedDiff string
}{
{
initialStateFile: "testdata/diff/004-plugin-update/initial-ee.yaml",
stateFile: "testdata/diff/004-plugin-update/initial-ee.yaml",
expectedDiff: expectedOutputPluginUpdateNoChange,
},
{
initialStateFile: "testdata/diff/004-plugin-update/initial-ee.yaml",
stateFile: "testdata/diff/004-plugin-update/kong-ee-no-change-old-fields.yaml",
expectedDiff: expectedOutputPluginUpdateNoChange,
},
{
initialStateFile: "testdata/diff/004-plugin-update/initial-ee.yaml",
stateFile: "testdata/diff/004-plugin-update/kong-ee-no-change-new-fields.yaml",
expectedDiff: expectedOutputPluginUpdateNoChange,
},
{
initialStateFile: "testdata/diff/004-plugin-update/initial-ee.yaml",
stateFile: "testdata/diff/004-plugin-update/kong-ee-changed-new-fields.yaml",
expectedDiff: expectedOutputPluginUpdateChangedNewFields,
},
{
initialStateFile: "testdata/diff/004-plugin-update/initial-ee.yaml",
stateFile: "testdata/diff/004-plugin-update/kong-ee-changed-old-fields.yaml",
expectedDiff: expectedOutputPluginUpdateChangedOldFields,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// initialize state
assert.NoError(t, sync(tc.initialStateFile))

fmt.Println("New stuff")
fmt.Println("New stuff")
fmt.Println("New stuff")
fmt.Println("New stuff")

out, err := diff(tc.stateFile)
assert.NoError(t, err)
assert.Equal(t, tc.expectedDiff, out)
})
}
}
61 changes: 61 additions & 0 deletions tests/integration/testdata/diff/004-plugin-update/initial-ee.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
_format_version: "3.0"
services:
- name: svc1
id: 9ecf5708-f2f4-444e-a4c7-fcd3a57f9a6d
host: mockbin.org
tags:
- test
plugins:
- id: a1368a28-cb5c-4eee-86d8-03a6bdf94b5e
enabled: true
name: rate-limiting-advanced
config:
consumer_groups: null
dictionary_name: kong_rate_limiting_counters
disable_penalty: false
enforce_consumer_groups: false
error_code: 429
error_message: API rate limit exceeded
header_name: null
hide_client_headers: false
identifier: consumer
limit:
- 10
namespace: ZEz47TWgUrv01HenyQBQa8io06MWsp0L
path: null
redis:
host: 127.0.0.5
port: 6380
cluster_addresses:
- 127.0.1.0:6379
- 127.0.1.0:6380
- 127.0.1.0:6381
cluster_nodes:
- ip: 127.0.1.0
port: 6379
- ip: 127.0.1.0
port: 6380
- ip: 127.0.1.0
port: 6381
timeout: 2000
connect_timeout: 2000
read_timeout: 2000
send_timeout: 2000
sentinel_addresses:
- 127.0.2.0:6379
- 127.0.2.0:6380
- 127.0.2.0:6381
sentinel_master: mymaster
sentinel_nodes:
- host: 127.0.2.0
port: 6379
- host: 127.0.2.0
port: 6380
- host: 127.0.2.0
port: 6381
sentinel_role: master
strategy: redis
sync_rate: 10
window_size:
- 60
window_type: sliding
Loading
Loading