Skip to content

Commit

Permalink
[management] split management api
Browse files Browse the repository at this point in the history
into two parts: status and debug

debug includes status and all other endpoints
status includes just /status/ endpoints
  • Loading branch information
mikz committed Mar 2, 2017
1 parent 8a3992c commit 9485ac4
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 11 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ REDIS_HOST=redis

# Set number of worker processes.
# APICAST_WORKERS=2

# How much to open the Management API. Allowed values are: disabled, status, debug.
# OpenShift template has status as the default value to use it for healt checks.
APICAST_MANAGEMENT_API=debug
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Reduce use of global objects [PR #273](https://github.com/3scale/apicast/pull/273)
- Load V2 configuration for all services in parallel [PR #272](https://github.com/3scale/apicast/pull/272)
- Configuration is using LRU cache [PR #274](https://github.com/3scale/apicast/pull/274)
- Management API not opened by default [PR #276](https://github.com/3scale/apicast/pull/276)

### Added

Expand Down
1 change: 1 addition & 0 deletions apicast/conf/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ env APICAST_MODULE;
env APICAST_MISSING_CONFIGURATION;
env APICAST_REQUEST_LOGS;
env APICAST_RESPONSE_CODES;
env APICAST_MANAGEMENT_API;
env AUTO_UPDATE_INTERVAL;
env BACKEND_ENDPOINT_OVERRIDE;

Expand Down
45 changes: 37 additions & 8 deletions apicast/src/management.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ local configuration_parser = require('configuration_parser')
local configuration_loader = require('configuration_loader')
local inspect = require('inspect')
local resolver_cache = require('resty.resolver.cache')
local env = require('resty.env')

local live = cjson.encode({status = 'live', success = true})

local function json_response(body, status)
ngx.header.content_type = 'application/json; charset=utf-8'
ngx.status = status or 200
ngx.status = status or ngx.HTTP_OK
ngx.say(cjson.encode(body))
end

function _M.ready()
local status = _M.status()
local code = status.success and 200 or 412
local code = status.success and ngx.HTTP_OK or 412

ngx.status = code
ngx.say(cjson.encode(status))
end

function _M.live()
ngx.status = 200
ngx.status = ngx.HTTP_OK
ngx.say(live)
end

Expand All @@ -48,7 +49,7 @@ function _M.config()
local contents = cjson.encode(config.configured and { services = config:all() } or nil)

ngx.header.content_type = 'application/json; charset=utf-8'
ngx.status = 200
ngx.status = ngx.HTTP_OK
ngx.say(contents)
end

Expand Down Expand Up @@ -100,20 +101,48 @@ function _M.dns_cache()
return json_response(cache:all())
end

function _M.router()
local r = router.new()
function _M.disabled()
ngx.exit(ngx.HTTP_FORBIDDEN)
end

local routes = {}

function routes.disabled(r)
r:get('/', _M.disabled)
end

function routes.status(r)
r:get('/status/ready', _M.ready)
r:get('/status/live', _M.live)
end

function routes.debug(r)
r:get('/config', _M.config)
r:put('/config', _M.update_config)
r:post('/config', _M.update_config)
r:delete('/config', _M.delete_config)

r:get('/status/ready', _M.ready)
r:get('/status/live', _M.live)
routes.status(r)

r:get('/dns/cache', _M.dns_cache)

ngx.log(ngx.WARN, 'adding boot')
r:post('/boot', _M.boot)
end

function _M.router()
local r = router.new()

local name = env.value('APICAST_MANAGEMENT_API') or 'status'
local api = routes[name]

ngx.log(ngx.DEBUG, 'management api mode: ', name)

if api then
api(r)
else
ngx.log(ngx.ERR, 'invalid management api setting: ', name)
end

return r
end
Expand Down
13 changes: 12 additions & 1 deletion doc/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,15 @@ Note that when deploying APIcast v2 with OpenShift, some of thee parameters can

URI that overrides backend endpoint from the configuration. Useful when deploying outside OpenShift deployed AMP.

**Example**: `https://backend.example.com`.
**Example**: `https://backend.example.com`.

- `APICAST_MANAGEMENT_API`

**Values:**

- `disabled`: completely disabled, just listens on the port
- `status`: only the `/status/` endpoints enabled for health checks
- `debug`: full API is open

The [Management API](./management-api.md) is powerful and can control the APIcast configuration.
You should enable the debug level only for debugging.
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ services:
- gateway
entrypoint: ""
dns: 127.0.0.1
environment:
APICAST_MANAGEMENT_API: debug
dns_search:
- example.com
prove:
Expand Down
6 changes: 6 additions & 0 deletions openshift/apicast-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ objects:
value: "${REDIS_HOST}"
- name: REDIS_PORT
value: "${REDIS_PORT}"
- name: APICAST_MANAGEMENT_API
value: "${MANAGEMENT_API}"
image: "${THREESCALE_GATEWAY_IMAGE}"
imagePullPolicy: Always
name: "${THREESCALE_GATEWAY_NAME}"
Expand Down Expand Up @@ -158,3 +160,7 @@ parameters:
name: REDIS_PORT
required: false
value: "6379"
- name: MANAGEMENT_API
description: "Scope of the Management API. Can be disabled, status or debug. At least status required for health checks."
required: false
value: "status"
51 changes: 49 additions & 2 deletions t/001-management.t
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ __DATA__
=== TEST 1: readiness probe with saved configuration
When configuration is saved, readiness probe returns success.
--- main_config
env APICAST_MANAGEMENT_API=status;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
Expand All @@ -36,6 +38,8 @@ GET /status/ready
=== TEST 2: readiness probe without configuration
Should respond with error status and a reason.
--- main_config
env APICAST_MANAGEMENT_API=status;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
--- config
Expand All @@ -50,6 +54,8 @@ GET /status/ready
=== TEST 3: readiness probe with 0 services
Should respond with error status and a reason.
--- main_config
env APICAST_MANAGEMENT_API=status;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
init_by_lua_block {
Expand All @@ -67,6 +73,8 @@ GET /status/ready
=== TEST 4: liveness probe returns success
As it is always alive.
--- main_config
env APICAST_MANAGEMENT_API=status;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
--- config
Expand All @@ -81,7 +89,8 @@ GET /status/live
=== TEST 5: config endpoint returns the configuration
Endpoint that dumps the original configuration.
--- main_config
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
Expand All @@ -102,7 +111,8 @@ Content-Type: application/json; charset=utf-8
=== TEST 6: config endpoint can write configuration
And can be later retrieved.
--- main_config
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
--- config
Expand Down Expand Up @@ -145,6 +155,7 @@ exposes boot function
--- main_config
env THREESCALE_PORTAL_ENDPOINT=http://localhost:$TEST_NGINX_SERVER_PORT/config/;
env RESOLVER=127.0.0.1:1953;
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
init_by_lua_block {
Expand All @@ -168,6 +179,7 @@ keeps the same configuration
--- main_config
env THREESCALE_PORTAL_ENDPOINT=http://localhost:$TEST_NGINX_SERVER_PORT/config/;
env RESOLVER=127.0.0.1:1953;
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
init_by_lua_block {
Expand All @@ -193,6 +205,8 @@ $::dns->("localhost", "127.0.0.1", 60)
=== TEST 10: config endpoint can delete configuration
--- main_config
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
--- config
Expand All @@ -216,6 +230,8 @@ null
=== TEST 11: all endpoints use correct Content-Type
JSON response body and content type application/json should be returned.
--- main_config
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
--- config
Expand All @@ -240,6 +256,8 @@ JSON response body and content type application/json should be returned.
=== TEST 12: GET /dns/cache
JSON response of the internal DNS cache.
--- main_config
env APICAST_MANAGEMENT_API=debug;
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
init_by_lua_block {
Expand All @@ -263,3 +281,32 @@ Content-Type: application/json; charset=utf-8
{"127.0.0.1.xip.io":{"expires_in":199,"value":{"1":{"address":"127.0.0.1","section":1,"type":1,"class":1,"name":"127.0.0.1.xip.io","ttl":199},"name":"127.0.0.1.xip.io","ttl":199}}}
--- no_error_log
[error]
=== TEST 13: liveness status is not accessible
Unless the APICAST_MANAGEMENT_API is set to 'status'.
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
--- config
include $TEST_NGINX_MANAGEMENT_CONFIG;
--- request
GET /status/live
--- error_code: 404
--- no_error_log
[error]
=== TEST 14: config endpoint is not accessible
Unless the APICAST_MANAGEMENT_API is set to 'debug'.
--- http_config
lua_package_path "$TEST_NGINX_LUA_PATH";
init_by_lua_block {
require('module').proxy:configure({ services = { { id = 42 } } })
}
--- config
include $TEST_NGINX_MANAGEMENT_CONFIG;
--- request
GET /config
--- error_code: 404
--- no_error_log
[error]

0 comments on commit 9485ac4

Please sign in to comment.