Skip to content

Commit 76dc1ba

Browse files
nowNickjschmid1
authored andcommitted
Revert "refactor(shorthand_fields): remove translate_backwards in favor of replaced_with (#13604)"
This reverts commit 11405e5.
1 parent b7ab58b commit 76dc1ba

File tree

6 files changed

+354
-12
lines changed

6 files changed

+354
-12
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
message: Reverted removal of `translate_backwards` from plugins' metaschema in order to maintain backward compatibility.
2+
type: bugfix
3+
scope: Core

kong/db/schema/init.lua

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,18 +1746,35 @@ local function validate_deprecation_exclusiveness(data, shorthand_value, shortha
17461746
if shorthand_value == nil or
17471747
shorthand_value == ngx.null or
17481748
shorthand_definition.deprecation == nil or
1749-
shorthand_definition.deprecation.replaced_with == nil then
1749+
(shorthand_definition.deprecation.replaced_with == nil and shorthand_definition.translate_backwards == nil) then
17501750
return true
17511751
end
17521752

1753-
for _, replaced_with_element in ipairs(shorthand_definition.deprecation.replaced_with) do
1754-
local new_field_value = replaced_with_element.reverse_mapping_function and replaced_with_element.reverse_mapping_function(data)
1755-
or table_path(data, replaced_with_element.path)
1753+
if shorthand_definition.deprecation.replaced_with then
1754+
for _, replaced_with_element in ipairs(shorthand_definition.deprecation.replaced_with) do
1755+
local new_field_value = replaced_with_element.reverse_mapping_function and replaced_with_element.reverse_mapping_function(data)
1756+
or table_path(data, replaced_with_element.path)
1757+
1758+
if new_field_value and
1759+
new_field_value ~= ngx.null and
1760+
not deepcompare(new_field_value, shorthand_value) then
1761+
local new_field_name = join_string(".", replaced_with_element.path)
1762+
1763+
return nil, string.format(
1764+
"both deprecated and new field are used but their values mismatch: %s = %s vs %s = %s",
1765+
shorthand_name, tostring(shorthand_value),
1766+
new_field_name, tostring(new_field_value)
1767+
)
1768+
end
1769+
end
1770+
elseif shorthand_definition.translate_backwards then
1771+
local new_field_value = shorthand_definition.translate_backwards_with and shorthand_definition.translate_backwards_with(data)
1772+
or table_path(data, shorthand_definition.translate_backwards)
17561773

17571774
if new_field_value and
1758-
new_field_value ~= ngx.null and
1759-
not deepcompare(new_field_value, shorthand_value) then
1760-
local new_field_name = join_string(".", replaced_with_element.path)
1775+
new_field_value ~= ngx.null and
1776+
not deepcompare(new_field_value, shorthand_value) then
1777+
local new_field_name = join_string(".", shorthand_definition.translate_backwards)
17611778

17621779
return nil, string.format(
17631780
"both deprecated and new field are used but their values mismatch: %s = %s vs %s = %s",
@@ -1847,10 +1864,16 @@ function Schema:process_auto_fields(data, context, nulls, opts)
18471864
sdata.deprecation.replaced_with[1]
18481865
if replaced_with then
18491866
if replaced_with.reverse_mapping_function then
1850-
data[sname] = replaced_with.reverse_mapping_function(data)
1867+
data[sname] = replaced_with.reverse_mapping_function(data)
18511868
else
18521869
data[sname] = table_path(data, replaced_with.path)
18531870
end
1871+
1872+
-- Falling back to processing `translate_backwards` for backwards compatibility
1873+
-- this might be the case when someone is using `rate-limiting`, `acme`, `response-ratelimiting` plugin
1874+
-- from version 3.6.x or 3.7.x
1875+
elseif sdata.translate_backwards then
1876+
data[sname] = table_path(data, sdata.translate_backwards)
18541877
end
18551878
end
18561879
end
@@ -2000,21 +2023,25 @@ function Schema:process_auto_fields(data, context, nulls, opts)
20002023
elseif not ((key == "ttl" and self.ttl) or
20012024
(key == "ws_id" and show_ws)) then
20022025

2003-
local should_be_in_ouput = false
2026+
local should_be_in_output = false
20042027

20052028
if self.shorthand_fields then
20062029
for _, shorthand_field in ipairs(self.shorthand_fields) do
20072030
if shorthand_field[key] then
20082031
local replaced_with = shorthand_field[key].deprecation and shorthand_field[key].deprecation.replaced_with and
20092032
#shorthand_field[key].deprecation.replaced_with[1]
2010-
if replaced_with then
2011-
should_be_in_ouput = is_select
2033+
2034+
-- Either using replaced_with or falling back to processing `translate_backwards` for backwards compatibility
2035+
-- this might be the case when someone is using `rate-limiting`, `acme`, `response-ratelimiting` plugin
2036+
-- from version 3.6.x or 3.7.x
2037+
if replaced_with or shorthand_field[key].translate_backwards then
2038+
should_be_in_output = is_select
20122039
end
20132040
end
20142041
end
20152042
end
20162043

2017-
if not should_be_in_ouput then
2044+
if not should_be_in_output then
20182045
data[key] = nil
20192046
end
20202047
end

kong/db/schema/metaschema.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ local function make_shorthand_field_schema()
716716
shorthand_field_schema[1] = { type = { type = "string", one_of = shorthand_field_types, required = true }, }
717717

718718
insert(shorthand_field_schema, { func = { type = "function", required = true } })
719+
insert(shorthand_field_schema, { translate_backwards = { type = "array", elements = { type = "string" }, required = false } })
719720
return shorthand_field_schema
720721
end
721722

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
local helpers = require "spec.helpers"
2+
local cjson = require "cjson"
3+
local uuid = require("kong.tools.uuid").uuid
4+
5+
6+
describe("an old plugin: translate_backwards", function()
7+
local bp, db, route, admin_client
8+
local plugin_id = uuid()
9+
10+
lazy_setup(function()
11+
helpers.test_conf.lua_package_path = helpers.test_conf.lua_package_path .. ";./spec-ee/fixtures/custom_plugins/?.lua"
12+
bp, db = helpers.get_db_utils(nil, {
13+
"plugins",
14+
}, { 'translate-backwards-older-plugin' })
15+
16+
route = assert(bp.routes:insert {
17+
hosts = { "redis.test" },
18+
})
19+
20+
assert(helpers.start_kong({
21+
plugins = "bundled,translate-backwards-older-plugin",
22+
nginx_conf = "spec/fixtures/custom_nginx.template",
23+
lua_package_path = "?./spec-ee/fixtures/custom_plugins/?.lua",
24+
}))
25+
26+
admin_client = assert(helpers.admin_client())
27+
end)
28+
29+
lazy_teardown(function()
30+
if admin_client then
31+
admin_client:close()
32+
end
33+
34+
helpers.stop_kong()
35+
end)
36+
37+
describe("when creating custom plugin", function()
38+
after_each(function()
39+
db:truncate("plugins")
40+
end)
41+
42+
describe("when using the new field", function()
43+
it("creates the custom plugin and fills in old field in response", function()
44+
-- POST
45+
local res = assert(admin_client:send {
46+
method = "POST",
47+
route = {
48+
id = route.id
49+
},
50+
path = "/plugins",
51+
headers = { ["Content-Type"] = "application/json" },
52+
body = {
53+
id = plugin_id,
54+
name = "translate-backwards-older-plugin",
55+
config = {
56+
new_field = "ABC"
57+
},
58+
},
59+
})
60+
61+
local json = cjson.decode(assert.res_status(201, res))
62+
assert.same(json.config.new_field, "ABC")
63+
assert.same(json.config.old_field, "ABC")
64+
65+
-- PATCH
66+
res = assert(admin_client:send {
67+
method = "PATCH",
68+
path = "/plugins/" .. plugin_id,
69+
headers = { ["Content-Type"] = "application/json" },
70+
body = {
71+
name = "translate-backwards-older-plugin",
72+
config = {
73+
new_field = "XYZ"
74+
},
75+
},
76+
})
77+
78+
json = cjson.decode(assert.res_status(200, res))
79+
assert.same(json.config.new_field, "XYZ")
80+
assert.same(json.config.old_field, "XYZ")
81+
82+
-- GET
83+
res = assert(admin_client:send {
84+
method = "GET",
85+
path = "/plugins/" .. plugin_id
86+
})
87+
88+
json = cjson.decode(assert.res_status(200, res))
89+
assert.same(json.config.new_field, "XYZ")
90+
assert.same(json.config.old_field, "XYZ")
91+
end)
92+
end)
93+
94+
describe("when using the old field", function()
95+
it("creates the custom plugin and fills in old field in response", function()
96+
-- POST
97+
local res = assert(admin_client:send {
98+
method = "POST",
99+
route = {
100+
id = route.id
101+
},
102+
path = "/plugins",
103+
headers = { ["Content-Type"] = "application/json" },
104+
body = {
105+
id = plugin_id,
106+
name = "translate-backwards-older-plugin",
107+
config = {
108+
old_field = "ABC"
109+
},
110+
},
111+
})
112+
113+
local json = cjson.decode(assert.res_status(201, res))
114+
assert.same(json.config.new_field, "ABC")
115+
assert.same(json.config.old_field, "ABC")
116+
117+
-- PATCH
118+
res = assert(admin_client:send {
119+
method = "PATCH",
120+
path = "/plugins/" .. plugin_id,
121+
headers = { ["Content-Type"] = "application/json" },
122+
body = {
123+
name = "translate-backwards-older-plugin",
124+
config = {
125+
old_field = "XYZ"
126+
},
127+
},
128+
})
129+
130+
json = cjson.decode(assert.res_status(200, res))
131+
assert.same(json.config.new_field, "XYZ")
132+
assert.same(json.config.old_field, "XYZ")
133+
134+
-- GET
135+
res = assert(admin_client:send {
136+
method = "GET",
137+
path = "/plugins/" .. plugin_id
138+
})
139+
140+
json = cjson.decode(assert.res_status(200, res))
141+
assert.same(json.config.new_field, "XYZ")
142+
assert.same(json.config.old_field, "XYZ")
143+
end)
144+
end)
145+
146+
describe("when using the both new and old fields", function()
147+
describe("when their values match", function()
148+
it("creates the custom plugin and fills in old field in response", function()
149+
-- POST
150+
local res = assert(admin_client:send {
151+
method = "POST",
152+
route = {
153+
id = route.id
154+
},
155+
path = "/plugins",
156+
headers = { ["Content-Type"] = "application/json" },
157+
body = {
158+
id = plugin_id,
159+
name = "translate-backwards-older-plugin",
160+
config = {
161+
new_field = "ABC",
162+
old_field = "ABC"
163+
},
164+
},
165+
})
166+
167+
local json = cjson.decode(assert.res_status(201, res))
168+
assert.same(json.config.new_field, "ABC")
169+
assert.same(json.config.old_field, "ABC")
170+
171+
-- PATCH
172+
res = assert(admin_client:send {
173+
method = "PATCH",
174+
path = "/plugins/" .. plugin_id,
175+
headers = { ["Content-Type"] = "application/json" },
176+
body = {
177+
name = "translate-backwards-older-plugin",
178+
config = {
179+
new_field = "XYZ",
180+
old_field = "XYZ"
181+
},
182+
},
183+
})
184+
185+
json = cjson.decode(assert.res_status(200, res))
186+
assert.same(json.config.new_field, "XYZ")
187+
assert.same(json.config.old_field, "XYZ")
188+
189+
-- GET
190+
res = assert(admin_client:send {
191+
method = "GET",
192+
path = "/plugins/" .. plugin_id
193+
})
194+
195+
json = cjson.decode(assert.res_status(200, res))
196+
assert.same(json.config.new_field, "XYZ")
197+
assert.same(json.config.old_field, "XYZ")
198+
end)
199+
end)
200+
201+
describe("when their values mismatch", function()
202+
it("rejects such plugin", function()
203+
-- POST --- with mismatched values
204+
local res = assert(admin_client:send {
205+
method = "POST",
206+
route = {
207+
id = route.id
208+
},
209+
path = "/plugins",
210+
headers = { ["Content-Type"] = "application/json" },
211+
body = {
212+
id = plugin_id,
213+
name = "translate-backwards-older-plugin",
214+
config = {
215+
new_field = "ABC",
216+
old_field = "XYZ"
217+
},
218+
},
219+
})
220+
221+
assert.res_status(400, res)
222+
223+
-- POST --- with correct values so that we can send PATCH below
224+
res = assert(admin_client:send {
225+
method = "POST",
226+
route = {
227+
id = route.id
228+
},
229+
path = "/plugins",
230+
headers = { ["Content-Type"] = "application/json" },
231+
body = {
232+
id = plugin_id,
233+
name = "translate-backwards-older-plugin",
234+
config = {
235+
new_field = "ABC",
236+
old_field = "ABC"
237+
},
238+
},
239+
})
240+
241+
local json = cjson.decode(assert.res_status(201, res))
242+
assert.same(json.config.new_field, "ABC")
243+
assert.same(json.config.old_field, "ABC")
244+
245+
-- PATCH
246+
res = assert(admin_client:send {
247+
method = "PATCH",
248+
path = "/plugins/" .. plugin_id,
249+
headers = { ["Content-Type"] = "application/json" },
250+
body = {
251+
name = "translate-backwards-older-plugin",
252+
config = {
253+
new_field = "EFG",
254+
old_field = "XYZ"
255+
},
256+
},
257+
})
258+
259+
assert.res_status(400, res)
260+
261+
-- GET
262+
res = assert(admin_client:send {
263+
method = "GET",
264+
path = "/plugins/" .. plugin_id
265+
})
266+
267+
json = cjson.decode(assert.res_status(200, res))
268+
assert.same(json.config.new_field, "ABC")
269+
assert.same(json.config.old_field, "ABC")
270+
end)
271+
end)
272+
end)
273+
end)
274+
end)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
local kong = kong
2+
3+
local TranslateBackwardsOlderPlugin = {
4+
PRIORITY = 1000,
5+
VERSION = "0.1.0",
6+
}
7+
8+
function TranslateBackwardsOlderPlugin:access(conf)
9+
kong.log("access phase")
10+
end
11+
12+
return TranslateBackwardsOlderPlugin

0 commit comments

Comments
 (0)