Skip to content

Commit

Permalink
Merge pull request #1115 from eloycoto/PR-3.7
Browse files Browse the repository at this point in the history
RELEASE 3.7-beta1
  • Loading branch information
eloycoto authored Oct 2, 2019
2 parents d818e1a + cdb8122 commit 5d74478
Show file tree
Hide file tree
Showing 16 changed files with 504 additions and 58 deletions.
19 changes: 15 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
## [3.7.0-beta1]- 2019-09-13

### Added

- Introduce possibility of specifying policy order restrictions in their schemas. APIcast now shows a warning when those restrictions are not respected [#1088](https://github.com/3scale/APIcast/pull/1088), [THREESCALE-2896](https://issues.jboss.org/browse/THREESCALE-2896)
- Added new parameters to logging policy to allow custom access log [PR #1089](https://github.com/3scale/APIcast/pull/1089), [THREESCALE-1234](https://issues.jboss.org/browse/THREESCALE-1234)[THREESCALE-2876](https://issues.jboss.org/browse/THREESCALE-2876)
- Added new parameters to logging policy to allow custom access log [PR #1089](https://github.com/3scale/APIcast/pull/1089), [THREESCALE-1234](https://issues.jboss.org/browse/THREESCALE-1234)[THREESCALE-2876](https://issues.jboss.org/browse/THREESCALE-2876), [PR #1116] (https://github.com/3scale/APIcast/pull/1116)
- Added http_proxy policy to use an HTTP proxy in api_backed calls. [THREESCALE-2696](https://issues.jboss.org/browse/THREESCALE-2696), [PR #1080](https://github.com/3scale/APIcast/pull/1080)
- Option to load service configurations one by one lazily [PR #1099](https://github.com/3scale/APIcast/pull/1099), [THREESCALE-3168](https://issues.jboss.org/browse/THREESCALE-3168)
- New maintenance mode policy, useful for maintenance periods. [PR #1105](https://github.com/3scale/APIcast/pull/1105), [THREESCALE-3189](https://issues.jboss.org/browse/THREESCALE-3189)
Expand All @@ -18,15 +18,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Allow to use capture function in liquid templates. [PR #1107](https://github.com/3scale/APIcast/pull/1107), [THREESCALE-1911](https://issues.jboss.org/browse/THREESCALE-1911)
- OAuth 2.0 MTLS policy [PR #1101](https://github.com/3scale/APIcast/pull/1101) [Issue #1003](https://github.com/3scale/APIcast/issues/1003)
- Add an option to enable keepalive_timeout on gateway [THREESCALE-2886](https://issues.jboss.org/browse/THREESCALE-2886) [PR #1106](https://github.com/3scale/APIcast/pull/1106)

- Added a new replace path option in routing policy [THREESCALE-3512](https://issues.jboss.org/browse/THREESCALE-3512) [PR #1119](https://github.com/3scale/APIcast/pull/1119) [PR #1121](https://github.com/3scale/APIcast/pull/1121) [PR #1122](https://github.com/3scale/APIcast/pull/1122)

### Fixed

- Fix issues when OPENTRACING_FORWARD_HEADER was set [PR #1109](https://github.com/3scale/APIcast/pull/1109), [THREESCALE-1660](https://issues.jboss.org/browse/THREESCALE-1660)
- New TLS termination policy [PR #1108](https://github.com/3scale/APIcast/pull/1108), [THREESCALE-2898](https://issues.jboss.org/browse/THREESCALE-2898)
- Fix exception on rate limit policy when window was set as 0. [PR #1113](https://github.com/3scale/APIcast/pull/1108), [THREESCALE-3382](https://issues.jboss.org/browse/THREESCALE-3382)

## [3.6.0] - 2019-08-30

`3.6.0-rc2` was considered final and became `3.6.0`.

## [3.6.0-rc2] - 2019-07-25

### Fixed

- Fix typos on JWT claim policy jsonschema [PR #1095](https://github.com/3scale/APIcast/pull/1095), [THREESCALE-3046](https://issues.jboss.org/browse/THREESCALE-3046)

## [3.6.0-rc1] - 2019-07-04

Expand Down Expand Up @@ -670,7 +678,7 @@ expressed might change in future releases.
### Changed
- Major rewrite using JSON configuration instead of code generation.

[Unreleased]: https://github.com/3scale/apicast/compare/v3.6.0-rc1...HEAD
[Unreleased]: https://github.com/3scale/apicast/compare/v3.6.0...HEAD
[2.0.0]: https://github.com/3scale/apicast/compare/v0.2...v2.0.0
[3.0.0-alpha1]: https://github.com/3scale/apicast/compare/v2.0.0...v3.0.0-alpha1
[3.0.0-alpha2]: https://github.com/3scale/apicast/compare/v3.0.0-alpha1...v3.0.0-alpha2
Expand Down Expand Up @@ -708,3 +716,6 @@ expressed might change in future releases.
[3.5.1]: https://github.com/3scale/apicast/compare/v3.5.0...v3.5.1
[3.6.0-beta1]: https://github.com/3scale/apicast/compare/v3.5.1...v3.6.0-beta1
[3.6.0-rc1]: https://github.com/3scale/apicast/compare/v3.6.0-beta1...v3.6.0-rc1
[3.6.0-rc2]: https://github.com/3scale/apicast/compare/v3.6.0-rc1...v3.6.0-rc2
[3.6.0]: https://github.com/3scale/apicast/compare/v3.6.0-rc2...v3.6.0
[3.7.0-beta1]: https://github.com/3scale/apicast/compare/v3.6.0...v3.7.0-beta1
9 changes: 6 additions & 3 deletions gateway/src/apicast/executor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local Policy = require('apicast.policy')
local linked_list = require('apicast.linked_list')
local prometheus = require('apicast.prometheus')
local uuid = require('resty.jit-uuid')
local url_helper = require('resty.url_helper')

local setmetatable = setmetatable
local ipairs = ipairs
Expand Down Expand Up @@ -50,10 +51,12 @@ local function store_original_request(context)
end

pcall(function()
local path, query = url_helper.split_path(ngx.var.request_uri)
context.original_request = linked_list.readonly({
headers = ngx.req.get_headers(),
host = ngx.var.host,
path = ngx.var.request_uri,
path = path,
query = query,
uri = ngx.var.uri,
server_addr = ngx.var.server_addr,
})
Expand All @@ -73,8 +76,8 @@ local function shared_build_context(executor)
ctx.context = context
end

if not ctx.original_request then
store_original_request(ctx)
if not context.original_request then
store_original_request(context)
end

return context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
"rules": {
"type": "array",
"items": {
"required": [
"resource"
],
"properties": {
"combine_op": {
"type": "string",
Expand Down Expand Up @@ -67,6 +70,7 @@
"$ref": "#/definitions/value_type"
},
"operations": {
"description": "Operations to perform the condition",
"type": "array",
"items": {
"required": [
Expand Down Expand Up @@ -99,7 +103,7 @@
"type": "string"
},
"value_type": {
"description": "How to evaluate 'jwt_claim' value",
"description": "How to evaluate 'value' field",
"$ref": "#/definitions/value_type"
}
}
Expand Down
1 change: 1 addition & 0 deletions gateway/src/apicast/policy/logging/logging.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ local function get_request_context(context)
}

ctx.service = context.service or {}
ctx.original_request = context.original_request
return LinkedList.readonly(ctx, ngx.var)
end

Expand Down
34 changes: 34 additions & 0 deletions gateway/src/apicast/policy/routing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,37 @@ config that specifies `some_host.com` as the host of the Host header:
}
}
```


## Set the path used for upstream

By default, when a request is routed, the policy keeps the request path.
However, for a certain upstream maybe the path needs to be changed and cannot be
global due to is specific for the given API.

```json
{
"name": "routing",
"version": "builtin",
"configuration": {
"rules": [
{
"url": "http://example.com",
"replace_path": "{{ original_request.path | replace: 'v1beta1', 'v1' }}",
"condition": {
"operations": [
{
"match": "path",
"op": "==",
"value": "/v1beta1"
}
]
}
}
]
}
}
```

In this case, request original path is `v1beta1` and it'll call to
`http://example.com/v1/`
4 changes: 4 additions & 0 deletions gateway/src/apicast/policy/routing/apicast-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@
"url": {
"type": "string"
},
"replace_path": {
"type": "string",
"description": "Liquid filter to modify the request path to the matched Upstream URL. When no specified, keep the original path"
},
"host_header": {
"description": "Host for the Host header. When not specified, defaults to the host of the URL.",
"type": "string"
Expand Down
20 changes: 10 additions & 10 deletions gateway/src/apicast/policy/routing/routing_operation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,45 +25,45 @@ local function new(evaluate_left_side_func, op, value, value_type)
end

function _M.new_op_with_path(op, value, value_type)
local eval_left_func = function(request) return request:get_uri() end
local eval_left_func = function(context) return context.request:get_uri() end
return new(eval_left_func, op, value, value_type)
end

function _M.new_op_with_header(header_name, op, value, value_type)
local eval_left_func = function(request)
return request:get_header(header_name)
local eval_left_func = function(context)
return context.request:get_header(header_name)
end

return new(eval_left_func, op, value, value_type)
end

function _M.new_op_with_query_arg(query_arg_name, op, value, value_type)
local eval_left_func = function(request)
return request:get_uri_arg(query_arg_name)
local eval_left_func = function(context)
return context.request:get_uri_arg(query_arg_name)
end

return new(eval_left_func, op, value, value_type)
end

function _M.new_op_with_jwt_claim(jwt_claim_name, op, value, value_type)
local eval_left_func = function(request)
local jwt = request:get_validated_jwt()
local eval_left_func = function(context)
local jwt = context.request:get_validated_jwt()
return (jwt and jwt[jwt_claim_name]) or nil
end

return new(eval_left_func, op, value, value_type)
end

function _M.new_op_with_liquid_templating(liquid_expression, op, value, value_type)
local eval_left_func = function()
return TemplateString.new(liquid_expression or "" , "liquid"):render(ngx.ctx)
local eval_left_func = function(context)
return TemplateString.new(liquid_expression or "" , "liquid"):render(context)
end

return new(eval_left_func, op, value, value_type)
end

function _M:evaluate(context)
local left_operand_val = self.evaluate_left_side_func(context.request)
local left_operand_val = self.evaluate_left_side_func(context)

local op = Operation.new(
left_operand_val, 'plain', self.op, self.value, self.value_type
Expand Down
7 changes: 6 additions & 1 deletion gateway/src/apicast/policy/routing/rule.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ local tab_insert = table.insert
local tab_new = require('resty.core.base').new_tab
local error = error

local RoutingOperation = require('apicast.policy.routing.routing_operation')
local Condition = require('apicast.conditions.condition')
local RoutingOperation = require('apicast.policy.routing.routing_operation')
local TemplateString = require 'apicast.template_string'
local Upstream = require('apicast.upstream')

local _M = {}
Expand Down Expand Up @@ -61,6 +62,10 @@ function _M.new_from_config_rule(config_rule)

if upstream then
self.url = config_rule.url
if config_rule.replace_path then
self.replace_path = TemplateString.new(config_rule.replace_path, "liquid")
end

self.host_header = config_rule.host_header
self.condition = init_condition(config_rule.condition)
return self
Expand Down
5 changes: 5 additions & 0 deletions gateway/src/apicast/policy/routing/upstream_selector.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ function _M.select(_, rules, context)
if rule.host_header and rule.host_header ~= '' then
upstream:use_host_header(rule.host_header)
end
if rule.replace_path then
upstream:append_path(rule.replace_path:render(context))
-- Set uri as nil if not will be appended to the upstream
ngx.req.set_uri("/")
end

return upstream
end
Expand Down
59 changes: 21 additions & 38 deletions gateway/src/apicast/upstream.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@
--- upstream:call(context)

local setmetatable = setmetatable
local tonumber = tonumber
local str_format = string.format

local resty_resolver = require('resty.resolver')
local resty_url = require('resty.url')
local core_base = require('resty.core.base')
local url_helper = require('resty.url_helper')

local http_proxy = require('apicast.http_proxy')
local str_find = string.find
local str_sub = string.sub
local format = string.format
local new_tab = core_base.new_tab

local _M = {

Expand All @@ -31,45 +28,13 @@ local mt = {
__index = _M
}

local function split_path(path)
if not path then return end

local start = str_find(path, '?', 1, true)

if start then
return str_sub(path, 1, start - 1), str_sub(path, start + 1)
else
return path
end
end

local function parse_url(url)
local parsed, err = resty_url.split(url)

if err then return nil, err end

local uri = new_tab(0, 6)

uri.scheme = parsed[1]
uri.user = parsed[2]
uri.password = parsed[3]
uri.host = parsed[4]
uri.port = tonumber(parsed[5])

uri.path, uri.query = split_path(parsed[6])

return uri
end


--- Create new Upstream instance.
--- @tparam string url
--- @treturn Upstream|nil upstream instance
--- @treturn nil|string error when upstream can't be initialized
--- @static
function _M.new(url)
local uri, err = parse_url(url)

local uri, err = url_helper.parse_url(url)
if err then
return nil, 'invalid upstream'
end
Expand Down Expand Up @@ -148,6 +113,24 @@ function _M:use_host_header(host)
self.host = host
end

function _M:set_path(path)
self.uri.path, self.uri.query = url_helper.split_path(path)
end

function _M:append_path(path)
local tmp_path, tmp_query = url_helper.split_path(path)
if not self.uri.path then
self.uri.path = "/"
end
self.uri.path = resty_url.join(self.uri.path, tmp_path)

-- If query is already present, do not need to add more.
if tmp_query and tmp_query ~= "" then
return
end
self.uri.query = tmp_query
end

--- Rewrite request Host header to what is provided in the argument or in the URL.
function _M:rewrite_request()
local uri = self.uri
Expand Down
2 changes: 1 addition & 1 deletion gateway/src/apicast/version.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
return "3.6.0"
return "3.7.0-beta1"
Loading

0 comments on commit 5d74478

Please sign in to comment.