Skip to content

Commit

Permalink
fix(*): reject config if both deprecated and new field defined and th…
Browse files Browse the repository at this point in the history
…eir values mismatch

This commit adds a validation to deprecated fields
that checks if in case both new field and old field were defined -
their values must match.

KAG-5262
  • Loading branch information
nowNick committed Aug 27, 2024
1 parent aa160ee commit c24de51
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 14 deletions.
44 changes: 34 additions & 10 deletions kong/db/schema/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local is_reference = require "kong.pdk.vault".is_reference
local json = require "kong.db.schema.json"
local cjson_safe = require "cjson.safe"
local deprecation = require "kong.deprecation"
local inspect = require "inspect"


local compare_no_order = require "pl.tablex".compare_no_order
Expand All @@ -16,6 +17,7 @@ local cycle_aware_deep_copy = require "kong.tools.table".cycle_aware_deep_copy
local table_merge = require "kong.tools.table".table_merge
local table_path = require "kong.tools.table".table_path
local is_array = require "kong.tools.table".is_array
local join_string = require "kong.tools.string".join


local setmetatable = setmetatable
Expand Down Expand Up @@ -1703,6 +1705,28 @@ local function collect_field_reference(refs, key, reference)
end


local function validate_deprecation_exclusiveness(data, shorthand_value, shorthand_name, shorthand_definition)
if shorthand_definition.deprecation and shorthand_definition.deprecation.replaced_with then
for _, replaced_with_element in ipairs(shorthand_definition.deprecation.replaced_with) do
local new_field_value = replaced_with_element.translation and replaced_with_element.translation(data)
or table_path(data, replaced_with_element.path)

if new_field_value and not deepcompare(new_field_value, shorthand_value) then
local new_field_name = join_string(".", replaced_with_element.path)

return nil, string.format(
"both deprecated and new field are used but their values mismatch: %s = %s vs %s = %s",
shorthand_name, inspect(shorthand_value),
new_field_name, inspect(new_field_value)
)
end
end
end

return true
end


--- Given a table, update its fields whose schema
-- definition declares them as `auto = true`,
-- based on its CRUD operation context, and set
Expand Down Expand Up @@ -1736,25 +1760,25 @@ function Schema:process_auto_fields(data, context, nulls, opts)
local value = data[sname]
if value ~= nil then
local _, err = self:validate_field(sdata, value)
local _, deprecation_error = validate_deprecation_exclusiveness(data, value, sname, sdata)
if err then
errs[sname] = err
has_errs = true
elseif deprecation_error then
errs[sname] = deprecation_error
has_errs = true
else
data[sname] = nil
local new_values = sdata.func(value)
if new_values then
-- a shorthand field may have a deprecation property, that is used
-- to determine whether the shorthand's return value takes precedence
-- over the similarly named actual schema fields' value when both
-- are present. On deprecated shorthand fields the actual schema
-- field value takes the precedence, otherwise the shorthand's
-- return value takes the precedence.
local deprecation = sdata.deprecation
for k, v in pairs(new_values) do
if type(v) == "table" then
data[k] = deprecation and table_merge(v, data[k])
or table_merge(data[k] or {}, v)
elseif not deprecation or data[k] == nil then
local source = {}
if data[k] and data[k] ~= null then
source = data[k]
end
data[k] = table_merge(source, v)
else
data[k] = v
end
end
Expand Down
9 changes: 9 additions & 0 deletions kong/db/schema/metaschema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ local field_schema = {
{ message = { type = "string", required = true } },
{ removal_in_version = { type = "string", required = true } },
{ old_default = { type = "any", required = false } },
{ replaced_with = { type = "array", required = false,
elements = { type = "record",
required = false,
fields = {
{ path = { type = "array", len_min = 1, required = true, elements = { type = "string"}} },
{ translation = { type = "function", required = false }}
},
}
} },
},
} },
}
Expand Down
4 changes: 4 additions & 0 deletions kong/plugins/acme/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ local LEGACY_SCHEMA_TRANSLATIONS = {
len_min = 0,
translate_backwards = {'password'},
deprecation = {
replaced_with = { { path = { 'password' } } },
message = "acme: config.storage_config.redis.auth is deprecated, please use config.storage_config.redis.password instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -53,6 +54,7 @@ local LEGACY_SCHEMA_TRANSLATIONS = {
type = "string",
translate_backwards = {'server_name'},
deprecation = {
replaced_with = { { path = { 'server_name' } } },
message = "acme: config.storage_config.redis.ssl_server_name is deprecated, please use config.storage_config.redis.server_name instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -64,6 +66,7 @@ local LEGACY_SCHEMA_TRANSLATIONS = {
len_min = 0,
translate_backwards = {'extra_options', 'namespace'},
deprecation = {
replaced_with = { { path = { 'extra_options', 'namespace' } } },
message = "acme: config.storage_config.redis.namespace is deprecated, please use config.storage_config.redis.extra_options.namespace instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -74,6 +77,7 @@ local LEGACY_SCHEMA_TRANSLATIONS = {
type = "integer",
translate_backwards = {'extra_options', 'scan_count'},
deprecation = {
replaced_with = { { path = { 'extra_options', 'scan_count' } } },
message = "acme: config.storage_config.redis.scan_count is deprecated, please use config.storage_config.redis.extra_options.scan_count instead",
removal_in_version = "4.0", },
func = function(value)
Expand Down
9 changes: 9 additions & 0 deletions kong/plugins/rate-limiting/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ return {
type = "string",
translate_backwards = {'redis', 'host'},
deprecation = {
replaced_with = { { path = { 'redis', 'host' } } },
message = "rate-limiting: config.redis_host is deprecated, please use config.redis.host instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -114,6 +115,7 @@ return {
type = "integer",
translate_backwards = {'redis', 'port'},
deprecation = {
replaced_with = { { path = { 'redis', 'port' } } },
message = "rate-limiting: config.redis_port is deprecated, please use config.redis.port instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -125,6 +127,7 @@ return {
len_min = 0,
translate_backwards = {'redis', 'password'},
deprecation = {
replaced_with = { { path = { 'redis', 'password' } } },
message = "rate-limiting: config.redis_password is deprecated, please use config.redis.password instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -135,6 +138,7 @@ return {
type = "string",
translate_backwards = {'redis', 'username'},
deprecation = {
replaced_with = { { path = { 'redis', 'username' } } },
message = "rate-limiting: config.redis_username is deprecated, please use config.redis.username instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -145,6 +149,7 @@ return {
type = "boolean",
translate_backwards = {'redis', 'ssl'},
deprecation = {
replaced_with = { { path = { 'redis', 'ssl' } } },
message = "rate-limiting: config.redis_ssl is deprecated, please use config.redis.ssl instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -155,6 +160,7 @@ return {
type = "boolean",
translate_backwards = {'redis', 'ssl_verify'},
deprecation = {
replaced_with = { { path = { 'redis', 'ssl_verify' } } },
message = "rate-limiting: config.redis_ssl_verify is deprecated, please use config.redis.ssl_verify instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -165,6 +171,7 @@ return {
type = "string",
translate_backwards = {'redis', 'server_name'},
deprecation = {
replaced_with = { { path = { 'redis', 'server_name' } } },
message = "rate-limiting: config.redis_server_name is deprecated, please use config.redis.server_name instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -175,6 +182,7 @@ return {
type = "integer",
translate_backwards = {'redis', 'timeout'},
deprecation = {
replaced_with = { { path = { 'redis', 'timeout' } } },
message = "rate-limiting: config.redis_timeout is deprecated, please use config.redis.timeout instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -185,6 +193,7 @@ return {
type = "integer",
translate_backwards = {'redis', 'database'},
deprecation = {
replaced_with = { { path = { 'redis', 'database' } } },
message = "rate-limiting: config.redis_database is deprecated, please use config.redis.database instead",
removal_in_version = "4.0", },
func = function(value)
Expand Down
9 changes: 9 additions & 0 deletions kong/plugins/response-ratelimiting/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ return {
type = "string",
translate_backwards = {'redis', 'host'},
deprecation = {
replaced_with = { { path = { 'redis', 'host' } } },
message = "response-ratelimiting: config.redis_host is deprecated, please use config.redis.host instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -153,6 +154,7 @@ return {
type = "integer",
translate_backwards = {'redis', 'port'},
deprecation = {
replaced_with = { { path = {'redis', 'port'} } },
message = "response-ratelimiting: config.redis_port is deprecated, please use config.redis.port instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -164,6 +166,7 @@ return {
len_min = 0,
translate_backwards = {'redis', 'password'},
deprecation = {
replaced_with = { { path = {'redis', 'password'} } },
message = "response-ratelimiting: config.redis_password is deprecated, please use config.redis.password instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -174,6 +177,7 @@ return {
type = "string",
translate_backwards = {'redis', 'username'},
deprecation = {
replaced_with = { { path = {'redis', 'username'} } },
message = "response-ratelimiting: config.redis_username is deprecated, please use config.redis.username instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -184,6 +188,7 @@ return {
type = "boolean",
translate_backwards = {'redis', 'ssl'},
deprecation = {
replaced_with = { { path = {'redis', 'ssl'} } },
message = "response-ratelimiting: config.redis_ssl is deprecated, please use config.redis.ssl instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -194,6 +199,7 @@ return {
type = "boolean",
translate_backwards = {'redis', 'ssl_verify'},
deprecation = {
replaced_with = { { path = {'redis', 'ssl_verify'} } },
message = "response-ratelimiting: config.redis_ssl_verify is deprecated, please use config.redis.ssl_verify instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -204,6 +210,7 @@ return {
type = "string",
translate_backwards = {'redis', 'server_name'},
deprecation = {
replaced_with = { { path = {'redis', 'server_name'} } },
message = "response-ratelimiting: config.redis_server_name is deprecated, please use config.redis.server_name instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -214,6 +221,7 @@ return {
type = "integer",
translate_backwards = {'redis', 'timeout'},
deprecation = {
replaced_with = { { path = {'redis', 'timeout'} } },
message = "response-ratelimiting: config.redis_timeout is deprecated, please use config.redis.timeout instead",
removal_in_version = "4.0", },
func = function(value)
Expand All @@ -224,6 +232,7 @@ return {
type = "integer",
translate_backwards = {'redis', 'database'},
deprecation = {
replaced_with = { { path = {'redis', 'database'} } },
message = "response-ratelimiting: config.redis_database is deprecated, please use config.redis.database instead",
removal_in_version = "4.0", },
func = function(value)
Expand Down
Loading

0 comments on commit c24de51

Please sign in to comment.