Skip to content

Commit

Permalink
THREESCALE-6552 - RFE
Browse files Browse the repository at this point in the history
- Sharing upstream.uri in the liquid context as "upstream"
- Unit + integration tests updated
  • Loading branch information
samugi committed Feb 7, 2021
1 parent 9c1c7ed commit 0330364
Show file tree
Hide file tree
Showing 6 changed files with 515 additions and 18 deletions.
26 changes: 25 additions & 1 deletion gateway/src/apicast/policy/maintenance_mode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ and message. It's useful for maintenance periods or to temporarily block an API.
| status (integer, _optional_) | 503 | Response code |
| message (string, _optional_) | Service Unavailable - Maintenance | Response message |

## Example Configuration
## Examples Configuration

- Custom response message
```json
{
"name": "maintenance-mode",
Expand All @@ -20,3 +22,25 @@ and message. It's useful for maintenance periods or to temporarily block an API.
}
}
```
- Apply Maintenance Mode for a specific upstream
```json
{
"name": "maintenance_mode",
"configuration": {
"condition": {
"operations": [
{
"left_type": "liquid",
"right_type": "plain",
"left": "{{ upstream.host }}{{ upstream.path }}",
"right": "echo-api.3scale.net/test",
"op": "=="
}
],
"combine_op": "and"
},
"status": 503,
"message": "Echo API /test is currently Unavailable"
}
}
```
98 changes: 96 additions & 2 deletions gateway/src/apicast/policy/maintenance_mode/apicast-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,79 @@
"$schema": "http://apicast.io/policy-v1.1/schema#manifest#",
"name": "Maintenance Mode",
"summary": "Rejects incoming requests. Useful for maintenance periods.",
"description": ["A policy which allows you reject incoming requests with a specified status code and message.",
"It's useful for maintenance periods or to temporarily block an API."
"description": [
"A policy which allows you to reject incoming requests with a specified status code and message. ",
"It's useful for maintenance periods or to temporarily block an API. \n",
"It allows to select a list of Upstream URLs for which to enable the maintenance mode."
],
"version": "builtin",
"configuration": {
"definitions": {
"operation": {
"type": "object",
"$id": "#/definitions/operation",
"properties": {
"left": {
"type": "string"
},
"op": {
"description": "Operation to apply. The matches op supports PCRE (Perl compatible regular expressions)",
"type": "string",
"enum": [
"==",
"!=",
"matches"
]
},
"right": {
"type": "string"
},
"left_type": {
"description": "How to evaluate 'left'",
"type": "string",
"default": "plain",
"oneOf": [
{
"enum": [
"plain"
],
"title": "Evaluate 'left' as plain text."
},
{
"enum": [
"liquid"
],
"title": "Evaluate 'left' as liquid."
}
]
},
"right_type": {
"description": "How to evaluate 'right'",
"type": "string",
"default": "plain",
"oneOf": [
{
"enum": [
"plain"
],
"title": "Evaluate 'right' as plain text."
},
{
"enum": [
"liquid"
],
"title": "Evaluate 'right' as liquid."
}
]
}
},
"required": [
"left",
"op",
"right"
]
}
},
"type": "object",
"properties": {
"status": {
Expand All @@ -23,6 +91,32 @@
"type": "string",
"description": "Content-Type header for the response",
"default": "text/plain; charset=utf-8"
},
"condition": {
"type": "object",
"title": "Condition",
"required": [
"combine_op",
"operations"
],
"properties": {
"combine_op": {
"title": "Combine operation",
"type": "string",
"default": "and",
"enum": [
"and",
"or"
]
},
"operations": {
"type": "array",
"items": {
"$ref": "#/definitions/operation"
},
"minItems": 1
}
}
}
}
}
Expand Down
41 changes: 39 additions & 2 deletions gateway/src/apicast/policy/maintenance_mode/maintenance_mode.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- This is a simple policy. It allows you reject incoming requests with a
-- This policy allows to reject incoming requests with a
-- specified status code and message.
-- It's useful for maintenance periods or to temporarily block an API

Expand All @@ -11,6 +11,9 @@ local default_status_code = 503
local default_message = "Service Unavailable - Maintenance"
local default_message_content_type = "text/plain; charset=utf-8"

local Condition = require('apicast.conditions.condition')
local Operation = require('apicast.conditions.operation')

function _M.new(configuration)
local policy = new(configuration)

Expand All @@ -19,20 +22,54 @@ function _M.new(configuration)
policy.message_content_type = default_message_content_type

if configuration then
policy.maintenance_upstreams = configuration.upstreams
policy.status_code = tonumber(configuration.status) or policy.status_code
policy.message = configuration.message or policy.message
policy.message_content_type = configuration.message_content_type or policy.message_content_type
end

policy:load_condition(configuration)
return policy
end

function _M:rewrite()
function _M:load_condition(config)
if not config or not config.condition then
return
end

local operations = {}
for _, operation in ipairs(config.condition.operations or {}) do
table.insert( operations,
Operation.new(
operation.left,
operation.left_type or default_template_type,
operation.op,
operation.right,
operation.right_type or default_template_type))
end
self.condition = Condition.new( operations, config.condition.combine_op or default_combine_op)
end

function set_maintenance_mode(self)
ngx.header['Content-Type'] = self.message_content_type
ngx.status = self.status_code
ngx.say(self.message)

return ngx.exit(ngx.status)
end

function _M:access(context)
-- Before the condition was not set, so the maintenance mode when condition is
-- nil should work.
if self.condition == nil then
return set_maintenance_mode(self)
end

context.upstream = context.route_upstream or context:get_upstream() or {}
context.upstream = context.upstream.uri or context.upstream
if self.condition:evaluate(context) then
return set_maintenance_mode(self)
end
end

return _M
4 changes: 4 additions & 0 deletions gateway/src/apicast/policy/upstream/upstream.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ function _M:rewrite(context)
end
end

function _M:access(context)
context.route_upstream = context[self] or context.route_upstream
end

function _M:content(context)
local upstream = context[self]

Expand Down
Loading

0 comments on commit 0330364

Please sign in to comment.