-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[standalone] introduce standalone policy
- Loading branch information
Showing
9 changed files
with
770 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
global: | ||
log_level: debug | ||
error_log: stderr | ||
access_log: stdout | ||
opentracing_tracer: jaeger | ||
upstream: | ||
load_balancer: least_conn | ||
retry: 5xx | ||
retry_times: 3 | ||
|
||
# we can pretend this would be nested inside `servers` block in the future | ||
server: | ||
# nginx config options like client_body_timeout or send_timeout | ||
listen: | ||
- port: 8090 | ||
name: management | ||
- port: 8081 | ||
name: echo # and also fake backend | ||
- port: 8080 | ||
name: default # default would be the default name | ||
- port: 8089 | ||
name: default # default would be the default name | ||
proxy_protocol: true | ||
- port: 8443 | ||
# name: default # several listen could have the same name | ||
protocol: http2 # | spdy | http | ||
tls: true | ||
- port: 8444 | ||
name: default | ||
protocol: http2 # | spdy | http | ||
proxy_protocol: true | ||
tls: | ||
protocols: TLSv1.3 | ||
# those two could be the defaults as policies have ssl_certificate phase | ||
certificate: /var/run/secret/apicast/certificate.crt | ||
certificate_key: /var/run/secret/apicast/certificate.key | ||
ciphers: "HIGH:!aNULL:!MD5" | ||
- port: 9421 | ||
name: prometheus | ||
tls: | ||
protocols: TLSv1.3 | ||
# those two could be the defaults as policies have ssl_certificate phase | ||
certificate: /var/run/secret/apicast/certificate.crt | ||
certificate_key: /var/run/secret/apicast/certificate.key | ||
ciphers: "HIGH:!aNULL:!MD5" | ||
|
||
routes: | ||
- # Route object | ||
name: management | ||
match: | ||
# Condition DSL to be defined by Rate limit policy and Conditional policy evaluation | ||
server_port: management # otherwise would match the default | ||
destination: # Destination DSL, AB testing, traffic split, etc. to be extended in the future | ||
service: management | ||
policy_chain: management | ||
upstream: management | ||
|
||
- name: echo | ||
match: | ||
server_port: echo # otherwise would match the default | ||
destination: | ||
service: echo | ||
|
||
- match: | ||
server_port: prometheus | ||
routes: | ||
- match: | ||
uri_path: '/metrics' | ||
http_method: 'GET' | ||
destination: | ||
service: prometheus | ||
|
||
- match: | ||
http_method: 'POST' | ||
destination: | ||
http_response: 405 | ||
|
||
# I'd like to treat this as a route tree. | ||
# If it matches all conditions of this rule then we can route it deeper. | ||
# But if it does not match the child rules we should reject the request with 404 (or with some other policy). | ||
destination: | ||
service: not_found | ||
|
||
- match: | ||
http_host: auth.example.com | ||
destination: | ||
service: auth-server | ||
|
||
- match: | ||
server_port: default # could be ommited, default would be the default | ||
destination: | ||
service: 3scale | ||
|
||
- match: | ||
always: true | ||
destination: | ||
service: not_found | ||
|
||
internal: # TODO: if we can figure out better name than "service" we would make our life much easier, vhost? | ||
|
||
- name: auth-server | ||
policy_chain: | ||
- policy: example.authentication.server | ||
configuration: | ||
redis: external://redis | ||
|
||
- name: 3scale | ||
policy_chain: | ||
- policy: apicast.policy.load_configuration | ||
- policy: apicast.policy.find_service | ||
- policy: apicast.policy.local_chain | ||
|
||
- name: simple | ||
policy_chain: | ||
- policy: example.authentication.client | ||
configuration: | ||
server: internal://auth-server | ||
|
||
upstream: http://echo-api.3scale.net | ||
|
||
- name: echo | ||
policy_chain: | ||
- logging | ||
# - echo | ||
# upstream: http://echo-api.3scale.net | ||
upstream: external://echo | ||
|
||
- name: backend # this is fake backend | ||
policy_chain: | ||
- echo | ||
|
||
- name: management | ||
policy_chain: | ||
- policy: apicast.policy.management | ||
configuration: | ||
mode: debug | ||
|
||
- name: prometheus | ||
policy_chain: | ||
- policy: apicast.policy.prometheus | ||
|
||
- name: echo | ||
policy_chain: | ||
- policy: apicast.policy.cors | ||
configuration: | ||
allow_methods: GET | ||
allow_origin: '*' | ||
- policy: apicast.policy.echo | ||
|
||
- name: logging | ||
policy_chain: | ||
- policy: log | ||
configuration: | ||
url: syslog://localhost | ||
fields: url, path, client_ip | ||
|
||
external: # kind of like egress, but it could also be an internal service | ||
# an abstraction for stubbing out external services with policies (fake backend vs external service) | ||
- name: backend | ||
server: https://su1.3scale.net | ||
load_balancer: least_conn | ||
|
||
- name: echo | ||
server: https://echo-api.3scale.net | ||
load_balancer: least_conn | ||
|
||
- name: redis | ||
server: tcp://localhost:6879 | ||
load_balancer: least_conn | ||
retries: 3 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
local PolicyChain = require('apicast.policy_chain') | ||
local resty_url = require('resty.url') | ||
local format = string.format | ||
|
||
local function to_url(uri) | ||
local url = resty_url.parse(uri) | ||
|
||
if url then | ||
return uri | ||
elseif uri then | ||
return format('file:%s', uri) | ||
end | ||
end | ||
|
||
local standalone = assert(PolicyChain.load_policy( | ||
'apicast.policy.standalone', | ||
'builtin', | ||
{ url = to_url(context.configuration) })) | ||
|
||
if arg then -- running CLI to generate nginx config | ||
return { | ||
template = 'http.d/standalone.conf.liquid', | ||
standalone = standalone:load_configuration(), | ||
configuration = standalone.url, | ||
} | ||
|
||
else -- booting APIcast | ||
return { | ||
policy_chain = PolicyChain.new{ | ||
standalone, | ||
}, | ||
configuration = standalone.url, | ||
} | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{% for server in standalone.server.listen %} | ||
server { | ||
listen {{ server.port }} default_server | ||
{%- if server.tls %} ssl {% endif -%} | ||
{%- case server.protocol -%} | ||
{%- when 'http2' %}{{- server.protocol -}} | ||
{%- when 'spdy' %}{{- server.protocol -}} | ||
{%- endcase -%} | ||
{%- if server.proxy_protocol %} proxy_protocol {% endif -%} | ||
; | ||
|
||
{% if server.tls.protocols -%} | ||
ssl_protocols {{ server.tls.protocols | join: " " }}; | ||
{%- endif %} | ||
|
||
{%- capture server_name -%}{{ server.name | default: 'default' }}{%- endcapture %} | ||
set $port_name {{ server_name }}; | ||
server_name {{ server_name }}; | ||
|
||
set $ctx_ref -1; | ||
|
||
location / { | ||
rewrite_by_lua_block { | ||
require('resty.ctx').stash() | ||
require('apicast.executor'):rewrite() | ||
} | ||
access_by_lua_block { require('apicast.executor'):access() } | ||
content_by_lua_block { require('apicast.executor'):content() } | ||
post_action @post_action; | ||
} | ||
|
||
body_filter_by_lua_block { require('apicast.executor'):body_filter() } | ||
header_filter_by_lua_block { require('apicast.executor'):header_filter() } | ||
|
||
location @post_action { | ||
internal; | ||
|
||
proxy_pass_request_headers off; | ||
|
||
rewrite_by_lua_block { require('resty.ctx').apply() } | ||
content_by_lua_block { require('apicast.executor'):post_action() } | ||
log_by_lua_block { require('apicast.executor'):log() } | ||
} | ||
} | ||
{% endfor %} | ||
|
||
{% for upstream in standalone.external %} | ||
upstream {{ upstream.name }} { | ||
server 0.0.0.1:1; | ||
|
||
balancer_by_lua_block { | ||
require('apicast.executor'):balancer('{{ upstream.load_balancer }}') | ||
} | ||
|
||
keepalive {{ upstream.keepalive | default: 64 }}; | ||
} | ||
|
||
{% endfor %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
local resty_url = require('resty.url') | ||
|
||
local setmetatable = setmetatable | ||
|
||
local _M = { | ||
|
||
} | ||
local mt = { __index = _M } | ||
|
||
local allowed_schemes = { | ||
file = true, | ||
-- TODO: support Data URI | ||
} | ||
|
||
|
||
function _M.new(uri) | ||
local url, err = resty_url.parse(uri) | ||
|
||
if not url then return nil, err end | ||
|
||
if not allowed_schemes[url.scheme] then | ||
return nil, 'scheme not supported' | ||
end | ||
|
||
return setmetatable({ url = url }, mt) | ||
end | ||
|
||
do | ||
local loaders = { } | ||
local path = require('pl.path') | ||
local file = require('pl.file') | ||
|
||
local YAML = require('lyaml') | ||
|
||
local decoders = { | ||
['.yml'] = YAML.load, | ||
['.yaml'] = YAML.load, | ||
} | ||
|
||
local function decode(fmt, contents) | ||
local decoder = decoders[fmt] | ||
|
||
if not decoder then return nil, 'unsupported format' end | ||
return decoder(contents) | ||
end | ||
|
||
function loaders.file(uri) | ||
local filename = uri.opaque | ||
if not filename then return nil, 'invalid file url' end | ||
|
||
local ext = path.extension(filename) | ||
local contents = file.read(filename) | ||
|
||
if contents then | ||
return decode(ext, contents) | ||
else | ||
return nil, 'no such file' | ||
end | ||
end | ||
|
||
function _M:load() | ||
local url = self and self.url | ||
if not url then return nil, 'not initialized' end | ||
|
||
local load = loaders[url.scheme] | ||
if not load then return nil, 'cannot load scheme' end | ||
|
||
|
||
return load(url) | ||
end | ||
|
||
end | ||
|
||
|
||
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
return require('standalone') |
Oops, something went wrong.