Skip to content

Commit

Permalink
feat(core): Admin GUI integration
Browse files Browse the repository at this point in the history
Serve static assets from Canopy project

Changes include:
* new nginx config template for static file serving
* new configuration items under admin_gui_* namespace
* bundle canopy assets during the build stage
* more CORS support for Admin API
* tests and more tests
  • Loading branch information
nekolab committed Jul 17, 2023
1 parent b7bf999 commit b1f8411
Show file tree
Hide file tree
Showing 34 changed files with 1,707 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ jobs:

- name: Build Kong
if: steps.cache-deps.outputs.cache-hit != 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
make build-kong
BUILD_PREFIX=$BUILD_ROOT/kong-dev
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:

- name: Build Kong
if: steps.cache-deps.outputs.cache-hit != 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
make build-kong
BUILD_PREFIX=$BUILD_ROOT/kong-dev
Expand All @@ -69,7 +71,7 @@ jobs:
if: steps.cache-deps.outputs.cache-hit != 'true'
run: |
make install-dev-rocks
# the above should be same as build_and_test.yml expect that perf.yml is used in cache_key

perf:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ jobs:
- name: Build Kong dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
bazel build --config release //build:kong --verbose_failures ${{ matrix.bazel-args }}
Expand Down
1 change: 1 addition & 0 deletions .requirements
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ LUA_RESTY_EVENTS=2f6fa23eb3d0b76a3b35fd915711200e90bc6732 # 0.1.6
LUA_RESTY_WEBSOCKET=60eafc3d7153bceb16e6327074e0afc3d94b1316 # 0.4.0
ATC_ROUTER=72cc8fddeac024c54c9c1fa5a25c28a72d79080e # 1.1.0

KONG_MANAGER=nightly
14 changes: 14 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,20 @@ config_setting(
visibility = ["//visibility:public"],
)

# --//:skip_webui=false
bool_flag(
name = "skip_webui",
build_setting_default = False,
)

config_setting(
name = "skip_webui_flags",
flag_values = {
":skip_webui": "true",
},
visibility = ["//visibility:public"],
)

##### constraints, platforms and config_settings for cross-compile

constraint_setting(name = "libc_version")
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@

#### Admin API

#### Kong Manager
- First release of the Kong Manager Open Source Edition.
[#11131](https://github.com/Kong/kong/pull/11131)

#### Status API

#### Plugins
Expand Down
16 changes: 14 additions & 2 deletions build/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ install_lualib_deps_cmd = "\n".join([
for dep in lualib_deps
])

install_webui_cmd = select({
"//conditions:default": """
cp -r $(location @kong_admin_gui//:dist_files) ${BUILD_DESTDIR}/kong/gui
""",
"@kong//:skip_webui_flags": "\n",
})

kong_directory_genrule(
name = "kong",
srcs = [
Expand All @@ -46,7 +53,12 @@ kong_directory_genrule(
"@luarocks//:luarocks_make",
"@luarocks//:luarocks_target",
"@protoc//:all_srcs",
] + lib_deps + lualib_deps,
] + select({
"@kong//:skip_webui_flags": [],
"//conditions:default": [
"@kong_admin_gui//:dist_files",
],
}) + lib_deps + lualib_deps,
cmd =
""" set -e
function copy_with_filter {
Expand Down Expand Up @@ -93,7 +105,7 @@ kong_directory_genrule(
cp -r $(locations @protoc//:all_srcs) ${BUILD_DESTDIR}/kong/.
""" + install_lib_deps_cmd + install_lualib_deps_cmd +
""" + install_lib_deps_cmd + install_lualib_deps_cmd + install_webui_cmd +
"""
mkdir -p ${BUILD_DESTDIR}/etc/kong
cp kong.conf.default ${BUILD_DESTDIR}/etc/kong/kong.conf.default
Expand Down
13 changes: 11 additions & 2 deletions build/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ def github_cli_repositories():
build_file_content = _SRCS_BUILD_FILE_CONTENT,
)

def kong_github_repositories():
maybe(
github_release,
name = "kong_admin_gui",
repo = "kong/kong-manager",
tag = KONG_VAR["KONG_MANAGER"],
pattern = "release.tar.gz",
build_file_content = _DIST_BUILD_FILE_CONTENT,
)

def _copyright_header(ctx):
paths = ctx.execute(["find", ctx.path("."), "-type", "f"]).stdout.split("\n")

Expand Down Expand Up @@ -96,8 +106,6 @@ def _github_release_impl(ctx):

ctx.extract(ctx.attr.pattern)

_copyright_header(ctx)

github_release = repository_rule(
implementation = _github_release_impl,
attrs = {
Expand Down Expand Up @@ -135,6 +143,7 @@ def build_repositories():

kong_resty_websocket_repositories()
github_cli_repositories()
kong_github_repositories()

protoc_repositories()

Expand Down
3 changes: 3 additions & 0 deletions kong-3.4.0-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ build = {

["kong.templates.nginx"] = "kong/templates/nginx.lua",
["kong.templates.nginx_kong"] = "kong/templates/nginx_kong.lua",
["kong.templates.nginx_kong_gui_include"] = "kong/templates/nginx_kong_gui_include.lua",
["kong.templates.nginx_kong_stream"] = "kong/templates/nginx_kong_stream.lua",
["kong.templates.kong_defaults"] = "kong/templates/kong_defaults.lua",
["kong.templates.kong_yml"] = "kong/templates/kong_yml.lua",
Expand Down Expand Up @@ -137,6 +138,8 @@ build = {
["kong.api.routes.clustering"] = "kong/api/routes/clustering.lua",
["kong.api.routes.debug"] = "kong/api/routes/debug.lua",

["kong.admin_gui"] = "kong/admin_gui/init.lua",

["kong.status"] = "kong/status/init.lua",
["kong.status.ready"] = "kong/status/ready.lua",

Expand Down
108 changes: 108 additions & 0 deletions kong.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -1843,3 +1843,111 @@
# in a Kong cluster must have a unique and
# valid UUID. When empty, node ID is
# automatically generated.

#------------------------------------------------------------------------------
# KONG MANAGER
#------------------------------------------------------------------------------
#
# The Admin GUI for Kong Gateway.
#
#admin_gui_listen = 0.0.0.0:8002, 0.0.0.0:8445 ssl
# Kong Manager Listeners
#
# Comma-separated list of addresses and ports on which
# Kong will expose Kong Manager. This web application
# lets you configure and manage Kong, and therefore
# should be kept secured.
#
# Suffixes can be specified for each pair, similarly to
# the `admin_listen` directive.

#admin_gui_url =
# Kong Manager URL
#
# The lookup, or balancer, address for Kong Manager.
#
# When set, the CORS headers in the Admin API response
# will also change to the corresponding origin
#
# Accepted format (items in parentheses are optional):
#
# `<scheme>://<IP / HOSTNAME>(:<PORT>)`
#
# Examples:
#
# - `http://127.0.0.1:8003`
# - `https://kong-manager.test`
# - `http://dev-machine`

#admin_gui_path = /
# Kong Manager base path
#
# This configuration parameter allows the user to customize
# the path prefix where Kong Manager is served. When updating
# this parameter, it's recommended to update the path in
# `admin_gui_url` as well.
#
# Accepted format:
#
# - Path must start with a `/`
# - Path must not end with a `/` (except for the `/`)
# - Path can only contain letters, digits, hyphens (`-`),
# underscores (`_`), and slashes (`/`)
# - Path must not contain continuous slashes (e.g., `//` and `///`)
#
# Examples:
#
# - `/`
# - `/manager`
# - `/kong-manager`
# - `/kong/manager`

#admin_gui_api_url =
# Hierarchical part of a URL which is composed
# optionally of a host, port, and path at which the
# Admin API accepts HTTP or HTTPS traffic. When
# this config is not provided, Kong Manager will
# use the window protocol + host and append the
# resolved admin_listen HTTP/HTTPS port.

#admin_gui_ssl_cert =
# The SSL certificate for `admin_gui_listen` values
# with SSL enabled.
#
# values:
# * absolute path to the certificate
# * certificate content
# * base64 encoded certificate content

#admin_gui_ssl_cert_key =
# The SSL key for `admin_gui_listen` values with SSL
# enabled.
#
# values:
# * absolute path to the certificate key
# * certificate key content
# * base64 encoded certificate key content

#admin_gui_access_log = logs/admin_gui_access.log
# Kong Manager Access Logs
#
# Here you can set an absolute or relative path for
# Kong Manager access logs. When the path is relative,
# logs are placed in the `prefix` location.
#
# Setting this value to `off` disables access logs
# for Kong Manager.


#admin_gui_error_log = logs/admin_gui_error.log
# Kong Manager Error Logs
#
# Here you can set an absolute or relative path for
# Kong Manager access logs. When the path is relative,
# logs are placed in the `prefix` location.
#
# Setting this value to `off` disables error logs for
# Kong Manager.
#
# Granularity can be adjusted through the `log_level`
# directive.
56 changes: 56 additions & 0 deletions kong/admin_gui/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
local meta = require "kong.meta"

local _M = {}

-- return first listener matching filters
local function select_listener(listeners, filters)
for _, listener in ipairs(listeners) do
local match = true
for filter, value in pairs(filters) do
if listener[filter] ~= value then
match = false
end
end
if match then
return listener
end
end
end

local function prepare_variable(variable)
if variable == nil then
return ""
end

return tostring(variable)
end

function _M.generate_kconfig(kong_config)
local api_listen = select_listener(kong_config.admin_listeners, {ssl = false})
local api_port = api_listen and api_listen.port
local api_ssl_listen = select_listener(kong_config.admin_listeners, {ssl = true})
local api_ssl_port = api_ssl_listen and api_ssl_listen.port

local configs = {
ADMIN_GUI_URL = prepare_variable(kong_config.admin_gui_url),
ADMIN_GUI_PATH = prepare_variable(kong_config.admin_gui_path),
ADMIN_API_URL = prepare_variable(kong_config.admin_gui_api_url),
ADMIN_API_PORT = prepare_variable(api_port),
ADMIN_API_SSL_PORT = prepare_variable(api_ssl_port),
KONG_VERSION = prepare_variable(meta.version),
KONG_EDITION = "community",
ANONYMOUS_REPORTS = prepare_variable(kong_config.anonymous_reports),
}

local kconfig_str = "window.K_CONFIG = {\n"
for config, value in pairs(configs) do
kconfig_str = kconfig_str .. " '" .. config .. "': '" .. value .. "',\n"
end

-- remove trailing comma
kconfig_str = kconfig_str:sub(1, -3)

return kconfig_str .. "\n}\n"
end

return _M
24 changes: 21 additions & 3 deletions kong/api/api_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local hooks = require "kong.hooks"


local ngx = ngx
local header = ngx.header
local sub = string.sub
local find = string.find
local type = type
Expand Down Expand Up @@ -266,6 +267,23 @@ function _M.before_filter(self)
return kong.response.exit(415)
end

function _M.cors_filter(self)
local origin = self.req.headers["Origin"]

if kong.configuration.admin_gui_origin then
origin = kong.configuration.admin_gui_origin
end

ngx.header["Access-Control-Allow-Origin"] = origin or "*"
ngx.header["Access-Control-Allow-Credentials"] = "true"

if ngx.req.get_method() == "OPTIONS" then
local request_allow_headers = self.req.headers["Access-Control-Request-Headers"]
if request_allow_headers then
ngx.header["Access-Control-Allow-Headers"] = request_allow_headers
end
end
end

local function parse_params(fn)
return app_helpers.json_params(function(self, ...)
Expand Down Expand Up @@ -386,9 +404,9 @@ end
local function options_method(methods)
return function()
kong.response.exit(204, nil, {
["Allow"] = methods,
["Access-Control-Allow-Methods"] = methods,
["Access-Control-Allow-Headers"] = "Content-Type",
["Allow"] = header["Access-Control-Allow-Methods"] or methods,
["Access-Control-Allow-Methods"] = header["Access-Control-Allow-Methods"] or methods,
["Access-Control-Allow-Headers"] = header["Access-Control-Allow-Headers"] or "Content-Type"
})
end
end
Expand Down
1 change: 1 addition & 0 deletions kong/api/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ local app = lapis.Application()
app.default_route = api_helpers.default_route
app.handle_404 = api_helpers.handle_404
app.handle_error = api_helpers.handle_error
app:before_filter(api_helpers.cors_filter)
app:before_filter(api_helpers.before_filter)


Expand Down
Loading

0 comments on commit b1f8411

Please sign in to comment.