From 81cef73c5a36d13e87d8e243aefa4628bbb56e48 Mon Sep 17 00:00:00 2001 From: owl Date: Thu, 7 Dec 2023 15:06:45 +0800 Subject: [PATCH 1/8] fix(dbless): fix error data loss caused by shallow copying of a table in declarative_config_flattened function --- kong/db/errors.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kong/db/errors.lua b/kong/db/errors.lua index 5a43911741a0..455072ebbedc 100644 --- a/kong/db/errors.lua +++ b/kong/db/errors.lua @@ -1,5 +1,6 @@ local pl_pretty = require("pl.pretty").write local pl_keys = require("pl.tablex").keys +local pl_table_deepcopy = require("pl.tablex").deepcopy local nkeys = require("table.nkeys") local table_isarray = require("table.isarray") local utils = require("kong.tools.utils") @@ -1152,8 +1153,8 @@ function _M:declarative_config_flattened(err_t, input) error("err_t input is nil or not a table", 2) end - local flattened = flatten_errors(input, err_t) - + local err_t_f = pl_table_deepcopy(err_t) + local flattened = flatten_errors(input, err_t_f) err_t = self:declarative_config(err_t) err_t.flattened_errors = flattened From 2ecd40c630cb0983edb95280f84fad998077870b Mon Sep 17 00:00:00 2001 From: owl Date: Thu, 7 Dec 2023 16:20:52 +0800 Subject: [PATCH 2/8] fix(dbless): fix code --- kong/db/errors.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kong/db/errors.lua b/kong/db/errors.lua index 455072ebbedc..85fc264c9b99 100644 --- a/kong/db/errors.lua +++ b/kong/db/errors.lua @@ -681,7 +681,8 @@ do end t[key] = nil - + local cjson = require("cjson") + ngx.log(ngx.ERR, "drain_iter: ", key, " => ", cjson.encode(value)) return key, value end @@ -1034,13 +1035,14 @@ do for i, err_t_i in drain(section_errors) do local entity = entities[i] - if type(entity) == "table" then + if type(entity) == "table" and type(err_t_i) == "table" then add_entity_errors(entity_type, entity, err_t_i, flattened) else log(WARN, "failed to resolve errors for ", entity_type, " at ", "index '", i, "'") section_errors[i] = err_t_i + err_t[entity_type] = section_errors end end @@ -1153,8 +1155,7 @@ function _M:declarative_config_flattened(err_t, input) error("err_t input is nil or not a table", 2) end - local err_t_f = pl_table_deepcopy(err_t) - local flattened = flatten_errors(input, err_t_f) + local flattened = flatten_errors(input, err_t) err_t = self:declarative_config(err_t) err_t.flattened_errors = flattened From f2f0127027fd548cf056bcf4901b3b33ec06e019 Mon Sep 17 00:00:00 2001 From: owl Date: Tue, 12 Dec 2023 15:27:23 +0800 Subject: [PATCH 3/8] fix(dbless): fix code --- kong/db/errors.lua | 2 - .../04-admin_api/15-off_spec.lua | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/kong/db/errors.lua b/kong/db/errors.lua index 85fc264c9b99..c92e41f645f9 100644 --- a/kong/db/errors.lua +++ b/kong/db/errors.lua @@ -681,8 +681,6 @@ do end t[key] = nil - local cjson = require("cjson") - ngx.log(ngx.ERR, "drain_iter: ", key, " => ", cjson.encode(value)) return key, value end diff --git a/spec/02-integration/04-admin_api/15-off_spec.lua b/spec/02-integration/04-admin_api/15-off_spec.lua index 7373a82b3564..ee19c38c1d7c 100644 --- a/spec/02-integration/04-admin_api/15-off_spec.lua +++ b/spec/02-integration/04-admin_api/15-off_spec.lua @@ -2697,6 +2697,46 @@ R6InCcH2Wh8wSeY5AuDXvu2tv9g/PW9wIJmPuKSHMA== }, }, flattened) end) + it("origin error do not loss when enable flatten_errors - (#12167)", function() + local input = { + _format_version = "3.0", + consumers = { + { + username = "test-consumer-1", + }, + { + username = "test-consumer-1", + }, + }, + } + + local res = client:post("/config?flatten_errors=1", { + body = input, + headers = { + ["Content-Type"] = "application/json" + }, + }) + + assert.response(res).has.status(400) + local body = assert.response(res).has.jsonbody() + + local errors = body.flattened_errors + + assert.not_nil(errors, "`flattened_errors` is missing from the response") + assert.is_table(errors, "`flattened_errors` is not a table") + + assert.logfile().has.no.line("[emerg]", true, 0) + assert.logfile().has.no.line("[crit]", true, 0) + assert.logfile().has.no.line("[alert]", true, 0) + assert.logfile().has.no.line("[error]", true, 0) + + -- empty flattened errors + assert.equals(0, #errors, "unexpected number of flattened errors") + + -- original errors exist + assert.equals(body.fields.consumers[2], "uniqueness violation: 'consumers' entity with username set to 'test-consumer-1' already declared", "unexpected original errors") + + end) end) From cdd1a620a2d9de958d0e7b643d734eb85e2b12e1 Mon Sep 17 00:00:00 2001 From: owl Date: Tue, 12 Dec 2023 15:34:19 +0800 Subject: [PATCH 4/8] fix(dbless): fix code --- .../kong/fix-declarative-config-flattened-data-loss.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/unreleased/kong/fix-declarative-config-flattened-data-loss.yml diff --git a/changelog/unreleased/kong/fix-declarative-config-flattened-data-loss.yml b/changelog/unreleased/kong/fix-declarative-config-flattened-data-loss.yml new file mode 100644 index 000000000000..05991af010d0 --- /dev/null +++ b/changelog/unreleased/kong/fix-declarative-config-flattened-data-loss.yml @@ -0,0 +1,3 @@ +message: fix error data loss caused by weakly typed of function in declarative_config_flattened function +type: bugfix +scope: Configuration From 6f9cfd0a126d439732733167f231763b511942e3 Mon Sep 17 00:00:00 2001 From: owl Date: Tue, 12 Dec 2023 15:40:03 +0800 Subject: [PATCH 5/8] fix(dbless): fix code --- kong/db/errors.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/kong/db/errors.lua b/kong/db/errors.lua index c92e41f645f9..6247a91a0546 100644 --- a/kong/db/errors.lua +++ b/kong/db/errors.lua @@ -1,6 +1,5 @@ local pl_pretty = require("pl.pretty").write local pl_keys = require("pl.tablex").keys -local pl_table_deepcopy = require("pl.tablex").deepcopy local nkeys = require("table.nkeys") local table_isarray = require("table.isarray") local utils = require("kong.tools.utils") From d1c0b122c96990289f3c70ded1269817658cd856 Mon Sep 17 00:00:00 2001 From: owl Date: Mon, 18 Dec 2023 14:29:22 +0800 Subject: [PATCH 6/8] fix: fix code --- kong/db/errors.lua | 7 +++- .../04-admin_api/15-off_spec.lua | 32 ++++--------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/kong/db/errors.lua b/kong/db/errors.lua index 6247a91a0546..b0a16d955b44 100644 --- a/kong/db/errors.lua +++ b/kong/db/errors.lua @@ -1032,6 +1032,12 @@ do for i, err_t_i in drain(section_errors) do local entity = entities[i] + + -- promote error strings to `@entity` type errors + if type(err_t_i) == "string" then + err_t_i = { ["@entity"] = err_t_i } + end + if type(entity) == "table" and type(err_t_i) == "table" then add_entity_errors(entity_type, entity, err_t_i, flattened) @@ -1039,7 +1045,6 @@ do log(WARN, "failed to resolve errors for ", entity_type, " at ", "index '", i, "'") section_errors[i] = err_t_i - err_t[entity_type] = section_errors end end diff --git a/spec/02-integration/04-admin_api/15-off_spec.lua b/spec/02-integration/04-admin_api/15-off_spec.lua index ee19c38c1d7c..cf0786a061df 100644 --- a/spec/02-integration/04-admin_api/15-off_spec.lua +++ b/spec/02-integration/04-admin_api/15-off_spec.lua @@ -2702,40 +2702,22 @@ R6InCcH2Wh8wSeY5AuDXvu2tv9g/PW9wIJmPuKSHMA== _format_version = "3.0", consumers = { { + id = "a73dc9a7-93df-584d-97c0-7f41a1bbce3d", username = "test-consumer-1", }, { + id = "a73dc9a7-93df-584d-97c0-7f41a1bbce32", username = "test-consumer-1", }, }, } - local res = client:post("/config?flatten_errors=1", { - body = input, - headers = { - ["Content-Type"] = "application/json" - }, - }) - - assert.response(res).has.status(400) - local body = assert.response(res).has.jsonbody() - - local errors = body.flattened_errors - - assert.not_nil(errors, "`flattened_errors` is missing from the response") - assert.is_table(errors, "`flattened_errors` is not a table") - - assert.logfile().has.no.line("[emerg]", true, 0) - assert.logfile().has.no.line("[crit]", true, 0) - assert.logfile().has.no.line("[alert]", true, 0) - assert.logfile().has.no.line("[error]", true, 0) - - -- empty flattened errors - assert.equals(0, #errors, "unexpected number of flattened errors") - - -- original errors exist - assert.equals(body.fields.consumers[2], "uniqueness violation: 'consumers' entity with username set to 'test-consumer-1' already declared", "unexpected original errors") + local flattened = post_config(input) + assert.equals(1, #flattened, + "unexpected number of flattened errors") + assert.equals("uniqueness violation: 'consumers' entity with username set to 'test-consumer-1' already declared", flattened[1].errors[1].message) + assert.equals("entity", flattened[1].errors[1].type) end) end) From f53b4004a29f4aa3868bd85b2cc072234b12c922 Mon Sep 17 00:00:00 2001 From: owl Date: Mon, 18 Dec 2023 14:32:33 +0800 Subject: [PATCH 7/8] fix: fix code --- kong/db/errors.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kong/db/errors.lua b/kong/db/errors.lua index b0a16d955b44..7139c636ddb6 100644 --- a/kong/db/errors.lua +++ b/kong/db/errors.lua @@ -680,6 +680,7 @@ do end t[key] = nil + return key, value end @@ -1158,6 +1159,7 @@ function _M:declarative_config_flattened(err_t, input) end local flattened = flatten_errors(input, err_t) + err_t = self:declarative_config(err_t) err_t.flattened_errors = flattened From 512fd7a48d3fe575e4259d3eae704a0bb943050a Mon Sep 17 00:00:00 2001 From: owl Date: Tue, 19 Dec 2023 10:56:24 +0800 Subject: [PATCH 8/8] fix: fix code --- .../04-admin_api/15-off_spec.lua | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/spec/02-integration/04-admin_api/15-off_spec.lua b/spec/02-integration/04-admin_api/15-off_spec.lua index cf0786a061df..54bb00e7e820 100644 --- a/spec/02-integration/04-admin_api/15-off_spec.lua +++ b/spec/02-integration/04-admin_api/15-off_spec.lua @@ -2704,20 +2704,35 @@ R6InCcH2Wh8wSeY5AuDXvu2tv9g/PW9wIJmPuKSHMA== { id = "a73dc9a7-93df-584d-97c0-7f41a1bbce3d", username = "test-consumer-1", + tags = { "consumer-1" }, }, { id = "a73dc9a7-93df-584d-97c0-7f41a1bbce32", username = "test-consumer-1", + tags = { "consumer-2" }, }, }, } - local flattened = post_config(input) - - assert.equals(1, #flattened, - "unexpected number of flattened errors") - assert.equals("uniqueness violation: 'consumers' entity with username set to 'test-consumer-1' already declared", flattened[1].errors[1].message) - assert.equals("entity", flattened[1].errors[1].type) + validate({ + { + entity_type = "consumer", + entity_id = "a73dc9a7-93df-584d-97c0-7f41a1bbce32", + entity_name = nil, + entity_tags = { "consumer-2" }, + entity = { + id = "a73dc9a7-93df-584d-97c0-7f41a1bbce32", + username = "test-consumer-1", + tags = { "consumer-2" }, + }, + errors = { + { + type = "entity", + message = "uniqueness violation: 'consumers' entity with username set to 'test-consumer-1' already declared", + } + }, + }, + }, flattened) end) end)