-
Notifications
You must be signed in to change notification settings - Fork 170
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
ability to configure policy chains globally #496
Conversation
4574c66
to
f2b9201
Compare
examples/configuration/echo.lua
Outdated
policy_chain:insert(policy_chain.load('apicast.policy.echo')) | ||
|
||
return { | ||
policy_chain = policy_chain |
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 will have to start documenting the environment config format. It is Lua, so no JSON schema.
3e32e24
to
9bf402f
Compare
spec/policy_chain_spec.lua
Outdated
@@ -92,6 +92,38 @@ describe('policy_chain', function() | |||
end, 'readonly table') | |||
end) | |||
|
|||
describe('.insert', function() | |||
|
|||
it('adds policy to the chain', function() |
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'd modify this test or add a new one. For .insert
we need to test that it adds the policy to the end of the list. If we do not initialize the chain with a few elements, we won't be able to test that. This test would pass even if the code added the policy to the beginning of the list or in a random position.
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.
Good point 👍 Will fix.
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.
Fixed in d340bf1 but going to be squashed.
spec/policy_chain_spec.lua
Outdated
assert.equal(0, #chain) | ||
end) | ||
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.
Would be good to test .default
for completeness. The other two methods introduced in this PR for that module are tested.
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.
Good point. Fixing 👍
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.
Fixed in 1fbfff8 and will squash it in a rebase.
gateway/src/apicast/policy_chain.lua
Outdated
-- @tparam[opt] int position the position to add the policy to, defaults to last one | ||
function _M:insert(policy, position) | ||
if self.frozen then | ||
return nil, 'frozen chain' |
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.
Maybe we should be more specific in the error message. Not sure this will be obvious to contributors.
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 the error messages in openresty are pretty simple because people can treat them like error code and match them. I'd probably even go for just 'frozen'
so it is easier to match.
Error codes from lua-resty-redis:
- not initialized
- not subscribed
- closed
- timeout
If "frozen" is not understandable I could rename it to: immutable, finalized, locked (other suggestions welcome).
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.
Fair enough. I was thinking more about clarifying what the error is about to possible contributors rather than making sure it's easy to match.
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.
That probably should be addressed by the method documentation describing the error messages. Will do 👍
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.
Fixed in f4be8fb and going to be squashed.
gateway/src/apicast/policy_chain.lua
Outdated
@@ -96,6 +109,25 @@ function _M:export() | |||
return chain | |||
end | |||
|
|||
--- Freeze the policy chain to prevent modifications. | |||
-- After calling this method it won't be possible to insert more policies. | |||
-- @treturn self |
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.
nitpick: missing type
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 file is probably not generating the doc as we had a whitelist in config.ld.
Will add it there and see the generated documentation.
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.
Fixed f4be8fb and going to be squashed.
examples/configuration/echo.lua
Outdated
@@ -0,0 +1,7 @@ | |||
local policy_chain = require('apicast.policy_chain').build({ }) |
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 these 2 lines could be simplified to:
local policy_chain = require('apicast.policy_chain').build({'apicast.policy.echo'})
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. I wanted to show the :insert
as an example. But that would be better with the default chain.
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.
What about:
local policy_chain = require('apicast.policy_chain').default()
local echo = require('apicast.policy.echo').new({ exit = 0 })
policy_chain:insert(echo, 1)
?
It shows off the insert - how to extend the default chain and how to pass options to policy.
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.
But apicast.policy.echo
doesn't have a constructor that can receive that table.
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.
Well I'd change it to accept a configuration for sake of the example.
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.
OK. In that case, I think that the latest example looks better than the original one 👍
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.
Fixed in 02ad4ab and going to be squashed or extracted into own commit.
examples/configuration/echo.lua
Outdated
@@ -0,0 +1,7 @@ | |||
local policy_chain = require('apicast.policy_chain').build({ }) | |||
|
|||
policy_chain:insert(policy_chain.load('apicast.policy.echo')) |
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 insert + load combination looks a bit confusing to me. I wonder if we should make .load
private.
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.
And just rely on require(...).new()
instead of .load
?
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.
What about .insert
calling .load
like .build
does and making .load
private?
I think that policy_chain:insert('apicast.policy.echo')
or policy_chain:insert(echo.new(something))
looks better than policy_chain:insert(policy_chain.load(...))
.
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'd like insert
to be an API that does one thing only. So I'd prefer it does not initialize the module because then it would also accept the configuration.
I agree .load
is kind of an useless abstraction and it would be better to use plain require. The only reason for is existence was that I wanted to have an abstraction so the internals can be replaced without much hassle.
But when replacing internal and for example changing :new
to .new
the policies would have to change anyway and it would leak this concept to the policy. But at least all the uses of the policy would not have to change.
So we should agree if we want to expose the policy initialization to users and deal with the consequences if we need to ever change it or expose some method to load/initialize policies.
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.
The new example looks like 02ad4ab so it uses plain require
. Guess that is ok for now.
$ENV{APICAST_CONFIGURATION_LOADER} = 'boot'; | ||
$ENV{THREESCALE_CONFIG_FILE} = 't/servroot/html/config.json'; | ||
#$ENV{TEST_NGINX_NO_CLEAN} = 1; |
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.
Commented.
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.
Well spotted. 👍
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.
Fixed in 19a3bb8 and will be squashed.
|
||
local template = Template:new(context, dir, true) | ||
local function apicast_root() | ||
return resty_env.get('APICAST_DIR') or pl.path.abspath('.') |
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.
Should we call .value
instead?
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. Good point!
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.
Did mass change in 569c520 and will squash it.
local function openresty_binary(candidates) | ||
return resty_env.value('APICAST_OPENRESTY_BINARY') or | ||
resty_env.value('TEST_NGINX_BINARY') or | ||
pick_openesty(candidates) |
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.
typo, also, I find naming here a bit confusing. This method is choosing the openresty binary but it's calling one named pick_openresty
.
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. I was too lazy to rename this function. Will do 👍
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.
Fixed in d5a7ca0 and will squash it.
insert(nameservers, tostring(nameserver)) | ||
end | ||
|
||
if #nameservers > 0 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.
Why return nil instead of {} ?
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.
Because then it is easier to verify that there are no nameservers. resolver
directive in the nginx conf has to have at least one server. So if there are none we can't set it.
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.
Would be good to document this.
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.
Hopefully 5aa2e0c is clear enough and describes that the type of this can be a table of strings or nil. Would that be enough?
@@ -0,0 +1,129 @@ | |||
local pl_path = require('pl.path') |
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.
Would be good to document the purpose of this module.
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.
Yep, Opened #500 so we can see the documentation artifacts and verify it looks correctly. Will write it after that one is merged and I can see the documetation.
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.
Documented in 5aa2e0c but going to squash it with the commit that introduced it.
I think it would be good to add an integration test that shows how to configure policy chains via environment. |
@davidor yep that is a good idea 👍 Will do. |
9bf402f
to
5aa2e0c
Compare
local _M = {} | ||
--- | ||
-- @field default_environment Default environment name. | ||
-- @table self |
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.
Couldn't figure out a better way to document this. This actually means there would be a property self
of the module returned by this file.
But there is no way I could find to have properties of the module just plain values with description. Only tables can be properties of the module and only tables can have fields.
1690e57
to
6811716
Compare
6811716
to
90017b4
Compare
returning policy_chain from the environment configuration will use that policy chain in nginx
90017b4
to
ee195d9
Compare
examples/configuration/echo.lua
Outdated
@@ -0,0 +1,8 @@ | |||
local policy_chain = require('apicast.policy_chain').default() |
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.
examples/configuration
contains many examples for different things. I think it'd be good from now on to explain what each one of them is about. A sentence at the begginning of the file should be enough.
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.
Good point. This one probably should be in own folder.
gateway/src/apicast/policy/echo.lua
Outdated
@@ -1,9 +1,22 @@ | |||
local policy = require('apicast.policy') | |||
local _M = policy.new('Echo Policy') | |||
local _M = require('apicast.policy').new('Echo Policy') |
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.
Similar to the comment above. This policy is trivial, but thinking about future contributors, I think that a description of 1 or 2 lines would help.
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.
As I pointed out in the comments, I think there are a couple of descriptions that we need to add. Apart from that, looks good.
👌
so enironment configurations can do conversions
464eff0
to
506c694
Compare
c7834b5
to
a63eccc
Compare
* show how environment configuration can define a policy_chain * show that it has access to ENV * change echo policy to have more granular configuration options
a63eccc
to
024363b
Compare
closes #481
It is possible to return a table with field
policy_chain
that is going to be used as the policy chain instead of the default one.Example: