Skip to content

Commit

Permalink
[cli] allow changing policy load path
Browse files Browse the repository at this point in the history
  • Loading branch information
mikz committed Feb 7, 2018
1 parent 1bb9706 commit b3b96d6
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
9 changes: 9 additions & 0 deletions doc/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,12 @@ This is a new **experimental** feature for increasing performance. Client
won't see the backend latency and everything will be processed asynchronously.
This value determines how many asynchronous reports can be running simultaneously
before the client is throttled by adding latency.

### `APICAST_POLICY_LOAD_PATH`

**Default**: APICAST_DIR/policies
**Value:**: string\[:<string>\]
**Example**: ~/apicast/policies:$PWD/policies

Double colon (`:`) separated list of paths where APIcast should look for policies.
It can be used to first load policies from a development directory or to load examples.
6 changes: 6 additions & 0 deletions doc/policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ Lets say the policy needs some 3rd party dependency. Those can be put anywhere i

The policy has access to only code it provides and shared code in `APICAST_DIR/src/`.

You can start APIcast with different policy load path parameter (`--policy-load-path` or `APICAST_POLICY_LOAD_PATH`) to load
policies from different than the default path. Example:
```shell
bin/apicast start --policy-load-path examples/policies:spec/fixtures/policies
```

### Policy code

To write your own policy you need to write a Lua module that instantiates a
Expand Down
6 changes: 6 additions & 0 deletions gateway/src/apicast/cli/command/start.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local min = math.min
local max = math.max
local insert = table.insert
local concat = table.concat
local format = string.format

local exec = require('resty.execvp')
local resty_env = require('resty.env')
Expand Down Expand Up @@ -109,6 +110,7 @@ local function build_env(options, config)
APICAST_CONFIGURATION_LOADER = options.boot and 'boot' or 'lazy',
APICAST_CONFIGURATION_CACHE = options.cache,
THREESCALE_DEPLOYMENT_ENV = config.name,
APICAST_POLICY_LOAD_PATH = options.policy_load_path,
}
end

Expand Down Expand Up @@ -193,6 +195,10 @@ local function configure(cmd)
"Cache configuration for N seconds. Using 0 will reload on every request (not for production).",
resty_env.value('APICAST_CONFIGURATION_CACHE'))

cmd:option("--policy-load-path",
"Load path where to find policies. Entries separated by `:`.",
resty_env.value('APICAST_POLICY_LOAD_PATH') or format('%s/policies', apicast_root())
)
cmd:mutex(
cmd:flag('-v --verbose',
"Increase logging verbosity (can be repeated).")
Expand Down
29 changes: 20 additions & 9 deletions gateway/src/apicast/policy_loader.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
local format = string.format
local error = error
local type = type
local ipairs = ipairs
local loadfile = loadfile
local getenv = os.getenv
local insert = table.insert
local setmetatable = setmetatable
local concat = table.concat
Expand All @@ -25,6 +25,9 @@ local root_require = require

local preload = package.preload

local resty_env = require('resty.env')
local re = require('ngx.re')

--- create a require function not using the global namespace
-- loading code from policy namespace should have no effect on the global namespace
-- but poliocy can load shared libraries that would be cached globally
Expand Down Expand Up @@ -211,16 +214,24 @@ local mt = {
__call = function(loader, ...) return loader.env.require(...) end
}

function _M.new(name, version, dir)
local apicast_dir = dir or getenv('APICAST_DIR') or '.'
do
local apicast_dir = resty_env.value('APICAST_DIR') or '.'
local policy_load_path = resty_env.value('APICAST_POLICY_LOAD_PATH') or
format('%s/policies', apicast_dir)

local path = {
-- first path contains
format('%s/policies/%s/%s/?.lua', apicast_dir, name, version),
}
_M.policy_load_paths = re.split(policy_load_path, ':', 'oj')
_M.builtin_policy_load_path = format('%s/src/apicast/policy', apicast_dir)
end

function _M.new(name, version, paths)
local load_paths = {}

for _, path in ipairs(paths or _M.policy_load_paths) do
insert(load_paths, format('%s/%s/%s/?.lua', path, name, version))
end

if version == 'builtin' then
insert(path, format('%s/src/apicast/policy/%s/?.lua', apicast_dir, name))
insert(load_paths, format('%s/%s/?.lua', _M.builtin_policy_load_path, name))
end

-- need to create global variable package that mimics the native one
Expand All @@ -229,7 +240,7 @@ function _M.new(name, version, dir)
preload = preload,
searchers = {}, -- http://www.lua.org/manual/5.2/manual.html#pdf-package.searchers
searchpath = searchpath,
path = concat(path, ';'),
path = concat(load_paths, ';'),
cpath = '', -- no C libraries allowed in policies
}

Expand Down
8 changes: 4 additions & 4 deletions spec/policy_loader_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ describe('APIcast Policy Loader', function()
end)

it('loads two instances of the same policy', function()
local test = _M:call('test', '1.0.0-0', 'spec/fixtures')
local test2 = _M:call('test', '1.0.0-0', 'spec/fixtures')
local test = _M:call('test', '1.0.0-0', { 'spec/fixtures/policies' })
local test2 = _M:call('test', '1.0.0-0', { 'spec/fixtures/policies' })

test.one = 1
assert.falsy(test2.one)
Expand All @@ -34,8 +34,8 @@ describe('APIcast Policy Loader', function()
end)

it('loads two versions of the same policy', function()
local test = _M:call('test', '1.0.0-0', 'spec/fixtures')
local test2 = _M:call('test', '2.0.0-0', 'spec/fixtures')
local test = _M:call('test', '1.0.0-0', { 'spec/fixtures/policies' })
local test2 = _M:call('test', '2.0.0-0', { 'spec/fixtures/policies' })

assert.are.same({ '1.0 dependency' }, test.dependency)
assert.are.same({ '2.0 dependency' }, test2.dependency)
Expand Down

0 comments on commit b3b96d6

Please sign in to comment.