-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
feat(config) flexible tokens/headers configuration #3300
Conversation
@thibaultcha Does this look like the right way to go forward? |
@hbagdi Nice! It looks like there is more work that needs to happen still (we can improve the "sugar" and make the checks more readable probably, + style issues), but otherwise it looks like it is on the right track :) |
kong/conf_loader.lua
Outdated
@@ -11,7 +11,9 @@ local utils = require "kong.tools.utils" | |||
local log = require "kong.cmd.utils.log" | |||
local ip = require "kong.tools.ip" | |||
local ciphers = require "kong.tools.ciphers" | |||
local bit = require "bit" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's keep this simple:
local bit = require "bit"
kong/conf_loader.lua
Outdated
|
||
local bor = bit.bor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to cache that as an upvalue, in fact not doing so might provide more readable code in this particular case (bit.bor
being more specific than bor
). This is also not a global, nor is this a hot code path, nor is the function name long, so...
kong/conf_loader.lua
Outdated
if token == "off" then | ||
mask = 0 | ||
break | ||
elseif allowed[token] == nil then -- TODO what about case sensetive?? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: need line jump before this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's ok to be case-sensitive imho, and expect server
and not SERVER
or ServER
.
kong/conf_loader.lua
Outdated
break | ||
elseif allowed[token] == nil then -- TODO what about case sensetive?? | ||
errors[#errors+1] = "tokens: invalid entry '" .. tostring(token) .. "'" | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: ditto (line jump)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about all the styling issues in this (and all the previous) PR. I need to figure out my styling and code convention issues.
kong/constants.lua
Outdated
local bit = require "bit" | ||
|
||
|
||
local bor = bit.bor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, these 2 instructions are adding quite a lot of whitespaces and blank lines
kong/core/error_handlers.lua
Outdated
@@ -56,7 +59,7 @@ return function(ngx) | |||
local status = ngx.status | |||
message = BODIES["s" .. status] and BODIES["s" .. status] or format(BODIES.default, status) | |||
|
|||
if singletons.configuration.server_tokens then | |||
if band(constants.HEADER_MASKS[constants.HEADERS.SERVER], singletons.configuration.header_mask) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this, we can probably optimize this by building a table in conf_loader
that we can query like so:
local config = singletons.config
if config.header_tokens.server then
-- ...
end
if config.header_tokens.via then
-- ...
end
This way we save both the AND
operation, and simplify the readability of those conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes a lot of sense and gets rid off all the bit operations all together.
-- in conf_loader.load()
local headers = {
[headers.PROXY_LATENCY] = false,
[headers.UPSTREAM_LATENCY] = false,
[headers.SERVER] = false,
[headers.VIA] = false,
}
-- loop through headers field in configuration and update above table
-- and finally
config.headers = headers
One question,
Do we want to have server_tokens
or latency_tokens
boolean in our singleton configuration table or having only header granularity is enough? We will still have the above tokens in the config file as sugar which simply enable the set of headers.
kong/constants.lua
Outdated
[headers.UPSTREAM_LATENCY] = 0x02, | ||
[headers.SERVER] = 0x04, | ||
[headers.VIA] = 0x08, | ||
latency = bor(0x01,0x02), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that this property refers to multiple headers, this should be latencies
I believe
kong/constants.lua
Outdated
[headers.SERVER] = 0x04, | ||
[headers.VIA] = 0x08, | ||
latency = bor(0x01,0x02), | ||
server = bor(0x04,0x08), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one could be server_tokens
(and the property in the configuration could be headers
probably?) Sorry if I mislead you while drafting the quick implementation on the fly while we chatted. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put in names just as placeholders since I was having a difficult time in deciding on which one to chose.
headers
as a property in user visible configuration property is much easier to grok.
I understand that server_tokens
is coming from NGINX world and we would like to stick to the conventions but could that instead be server_names
? Is it a bit more descriptive?
I'm thinking:
headers = server_names, kong_latencies, X-Kong-Foo-Bar
a8d94f4
to
f5890bf
Compare
kong/conf_loader.lua
Outdated
[headers.SERVER] = false, | ||
[headers.VIA] = false, | ||
server_tokens = false, | ||
latency_tokens = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if *_tokens
are needed here.
kong/conf_loader.lua
Outdated
header_tokens[headers.UPSTREAM_LATENCY] = true | ||
end | ||
end | ||
conf.headers = header_tokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conf.headers = build_headers_table(conf.headers)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In check_and_infer
, we should only do validation (the errors[#errors+1] = ...
part). Below and once we know all values are correct, we can mutate the conf.headers
table.
@@ -80,7 +80,7 @@ describe("Server Tokens", function() | |||
|
|||
setup(start { | |||
nginx_conf = "spec/fixtures/custom_nginx.template", | |||
server_tokens = "on", | |||
headers = "server_tokens", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thibaultcha what is the approach to put new tests? Should they go into both spec
and spec-old-api
? '
I think only in spec
but want to confirm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, just spec
. old-spec
is for backards-compatibility with 0.12 and the API entity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick response!
3594cc5
to
47a8024
Compare
47a8024
to
2d5437a
Compare
@thibaultcha ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good, but still a few items to fix before we can merge it.
kong/conf_loader.lua
Outdated
break | ||
|
||
elseif header_tokens[token] == nil then | ||
errors[#errors+1] = "tokens: invalid entry '" .. tostring(token) .. "'" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefix should be "headers: ..."
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need tests for this error which I don't see any for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed both of these in the updated commit.
kong/conf_loader.lua
Outdated
header_tokens[headers.UPSTREAM_LATENCY] = true | ||
end | ||
end | ||
conf.headers = header_tokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In check_and_infer
, we should only do validation (the errors[#errors+1] = ...
part). Below and once we know all values are correct, we can mutate the conf.headers
table.
kong/core/handler.lua
Outdated
header[constants.HEADERS.UPSTREAM_LATENCY] = ctx.KONG_WAITING_TIME | ||
end | ||
|
||
if singletons.configuration.headers[constants.HEADERS.PROXY_LATENCY] then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: the line below has now has a weird looking assignment operator with too many spaces, fixing it should be in the scope of this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for this one!
0dbec50
to
37713c6
Compare
kong/conf_loader.lua
Outdated
-- load headers configuration | ||
for _, token in ipairs(conf.headers) do | ||
if token == "off" then | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This behaviour is slightly off with that of the new directives like proxy_listen
- fixing it should be easy.
In the new listeners directives, off
only has meaning if it is the first value:
proxy_listen = off, ...
With this headers
directive however, the following is possible but slightly confusing:
headers = latency_tokens, off, server_tokens
Here, we end up in a situation where "half" of the specified tokens were taken into consideration. This could have (arguably) been considered an acceptable behaviour, but better stay consistent with the stricter semantics of the *_listen
directives imho. So the above would set both latency_tokens
and server_tokens
, and to disable headers, one must do:
headers = off
Frankly, the off
flag probably should not be mixed with actual values (that is bad implementation from the listeners directives to accept that imho), but well, not the scope of this PR to address, and better stick to this behaviour for now probably.
The above validation can probably implement the same behaviour (or ignore "off" values altogether, thus validating all non-off values in this list, up to you).
I expected that this comment was coming. I've updated the code to match the behavior you describe above and added a test for it. An explicit solution would be to check for a mix of
Let me know if there's anything other than the |
37713c6
to
4e34d1c
Compare
kong/conf_loader.lua
Outdated
for _, token in ipairs(conf.headers) do | ||
if token ~= "off" then | ||
header_tokens_clone[token] = true | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how this behaviour is different from yesterday's version of this patch? It still doesn't seem like it follows the same approach as other array-like directives that accept off
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. If the first element is off
then turn it off else don't. My bad.
kong/conf_loader.lua
Outdated
-- load headers configuration | ||
for _, token in ipairs(conf.headers) do | ||
if token ~= "off" then | ||
header_tokens_clone[token] = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should allow for case-insensitive values when specifying headers in this directive (just like HTTP headers are). E.g.:
headers = latency_tokens, Via
is same as:
headers = latency_tokens, via
9fc3ccf
to
5bcc063
Compare
As new headers are introduced by Kong's core, instead of introducing a config option for each and every header or set of headers, an array of these values can be now specified using the `headers` config option. This offers a fine grained controlled and does not blow up the number of configuration options. The goal here is to move towards a simpler and easier to understand configuration, similar to 1b9976f (#3147).
5bcc063
to
5afad1e
Compare
@thibaultcha Updated the PR with the requested fixes. |
As new headers are introduced by Kong's core, instead of introducing a config option for each and every header or set of headers, an array of these values can be now specified using the `headers` config option. This offers a fine grained controlled and does not blow up the number of configuration options. The goal here is to move towards a simpler and easier to understand configuration, similar to 1b9976f (#3147). From #3300 Signed-off-by: Thibault Charbonnier <thibaultcha@me.com>
Merged! Thank you! |
This fixes a bug introduced in 976dd87 (#3300) where headers config option was being overwritten as a table. The table is not persisted in the intermediate config file and hence the config option does not take effect. This commit also exposes `get_running_conf` helper function to read conf from prefix directory in use during the current test.
This fixes a bug introduced in 976dd87 (#3300) where the `headers` config option were not properly written to `.kong_env`. This would be an issue when the value was specified from the configuration file (vs. via environment variables). From #3419 Signed-off-by: Thibault Charbonnier <thibaultcha@me.com>
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300 Signed-off-by: Harry Bagdi <harrybagdi@gmail.com>
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300 Signed-off-by: Harry Bagdi <harrybagdi@gmail.com>
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300 Signed-off-by: Harry Bagdi <harrybagdi@gmail.com>
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300 From #729
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300 From #729
With CE 0.14.0, a new `headers` configuration option is introduced and `server_tokens` and `latency_tokens` are removed. See Kong/kong#3300 From #729
Instead of introducing a config option for each
and every header or set of headers, an array of
these values can be now specified using the
headers
config option.
Only headers or tokens specified in the headers will
be set by Kong when applicable.
The goal here is to move towards a simpler and
easier to understand configuration, similar to
1b9976f (#3147).