From 8c374edbe62f16dd6d19fa24cd9f525f70f39f8b Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Wed, 16 Feb 2022 10:28:34 -0800 Subject: [PATCH 01/74] fix(aws-lambda) proxy correctly with lua-resty-http (#8406) Fix some bugs and warts in the aws-lambda plugin: * Fix broken proxying by always using `https_proxy` with resty.http * Deprecate `proxy_scheme` config param Some minimal test coverage for proxying was added, and some defunct test cases were removed. --- .github/workflows/build_and_test.yml | 10 -- CHANGELOG.md | 3 + kong/plugins/aws-lambda/CHANGELOG.md | 17 ++- kong/plugins/aws-lambda/handler.lua | 23 +-- ...> kong-plugin-aws-lambda-3.6.3-0.rockspec} | 5 +- kong/plugins/aws-lambda/schema.lua | 19 ++- .../27-aws-lambda/02-schema_spec.lua | 21 +-- .../27-aws-lambda/50-http-proxy_spec.lua | 133 ------------------ .../27-aws-lambda/99-access_spec.lua | 39 +++++ spec/fixtures/aws-lambda.lua | 14 ++ spec/fixtures/forward-proxy-server.lua | 76 ++++++++++ 11 files changed, 192 insertions(+), 168 deletions(-) rename kong/plugins/aws-lambda/{kong-plugin-aws-lambda-3.5.4-1.rockspec => kong-plugin-aws-lambda-3.6.3-0.rockspec} (88%) delete mode 100644 spec/03-plugins/27-aws-lambda/50-http-proxy_spec.lua create mode 100644 spec/fixtures/forward-proxy-server.lua diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 32755718f0c5..1a7137a62eb1 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -155,11 +155,6 @@ jobs: - 6379:6379 options: --entrypoint redis-server - squid: - image: datadog/squid - ports: - - 3128:3128 - zipkin: image: openzipkin/zipkin:2.19 ports: @@ -283,11 +278,6 @@ jobs: - 6379:6379 options: --entrypoint redis-server - squid: - image: datadog/squid - ports: - - 3128:3128 - zipkin: image: openzipkin/zipkin:2.19 ports: diff --git a/CHANGELOG.md b/CHANGELOG.md index baf9da306322..23f6fc3138a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -156,6 +156,9 @@ - **External Plugins**: Unwrap `ConsumerSpec` and `AuthenticateArgs`. Thanks, [@raptium](https://github.com/raptium)! [#8280](https://github.com/Kong/kong/pull/8280) +- **AWS-Lambda**: Fixed incorrect behavior when configured to use an http proxy + and deprecated the `proxy_scheme` config attribute for removal in 3.0 + [#8406](https://github.com/Kong/kong/pull/8406) ## [2.7.1] diff --git a/kong/plugins/aws-lambda/CHANGELOG.md b/kong/plugins/aws-lambda/CHANGELOG.md index d752f861b611..6fad6f55582f 100644 --- a/kong/plugins/aws-lambda/CHANGELOG.md +++ b/kong/plugins/aws-lambda/CHANGELOG.md @@ -11,9 +11,24 @@ - upload to luarocks; `luarocks upload kong-plugin-aws-lambda-x.y.z-1.rockspec --api-key=abc...` - test rockspec; `luarocks install kong-plugin-aws-lambda` +## aws-lambda 3.6.3 15-Feb-2022 -## unreleased +- tests: update forward-proxy fixture +- tests: remove old http proxy tests +- fix: always use https_proxy +- fix: deprecate proxy_scheme parameter +- fix: ensure proxy_url scheme is http +## aws-lambda 3.6.2 07-Sep-2021 + +- chore: bump lua-resty-http from 0.15 to 0.16.1 [#7797](https://github.com/Kong/kong/pull/7797) + +## aws-lambda 3.6.1 07-Sep-2021 +- refactor: use error function instead of kong.log.err + kong.response.error [#7797](https://github.com/Kong/kong/pull/7797) + +## aws-lambda 3.6.0 30-Aug-2021 + +- feat: add support for detecting AWS region from environment variable [#7765](https://github.com/Kong/kong/pull/7765) - fix: handle multivalueheaders [#59](https://github.com/Kong/kong-plugin-aws-lambda/pull/59) ## aws-lambda 3.5.4 22-Mar-2021 diff --git a/kong/plugins/aws-lambda/handler.lua b/kong/plugins/aws-lambda/handler.lua index 3291fc54ebb2..486be33f6622 100644 --- a/kong/plugins/aws-lambda/handler.lua +++ b/kong/plugins/aws-lambda/handler.lua @@ -17,6 +17,8 @@ local AWS_REGION do AWS_REGION = os.getenv("AWS_REGION") or os.getenv("AWS_DEFAULT_REGION") end +local _logged_proxy_scheme_warning + local fetch_credentials do local credential_sources = { require "kong.plugins.aws-lambda.iam-ecs-credentials", @@ -44,7 +46,6 @@ local error = error local pairs = pairs local kong = kong local type = type -local find = string.find local fmt = string.format @@ -244,17 +245,17 @@ function AWSLambdaHandler:access(conf) local uri = port and fmt("https://%s:%d", host, port) or fmt("https://%s", host) + if conf.proxy_scheme and not _logged_proxy_scheme_warning then + kong.log.warn("`proxy_scheme` is deprecated and will be removed in Kong 3.0") + _logged_proxy_scheme_warning = true + end + local proxy_opts if conf.proxy_url then - if find(conf.proxy_url, "https", 1, true) == 1 then - proxy_opts = { - https_proxy = conf.proxy_url, - } - else - proxy_opts = { - http_proxy = conf.proxy_url, - } - end + -- lua-resty-http uses the request scheme to determine which of + -- http_proxy/https_proxy it will use, and from this plugin's POV, the + -- request scheme is always https + proxy_opts = { https_proxy = conf.proxy_url } end -- Trigger request @@ -326,6 +327,6 @@ function AWSLambdaHandler:access(conf) end AWSLambdaHandler.PRIORITY = 750 -AWSLambdaHandler.VERSION = "3.6.2" +AWSLambdaHandler.VERSION = "3.6.3" return AWSLambdaHandler diff --git a/kong/plugins/aws-lambda/kong-plugin-aws-lambda-3.5.4-1.rockspec b/kong/plugins/aws-lambda/kong-plugin-aws-lambda-3.6.3-0.rockspec similarity index 88% rename from kong/plugins/aws-lambda/kong-plugin-aws-lambda-3.5.4-1.rockspec rename to kong/plugins/aws-lambda/kong-plugin-aws-lambda-3.6.3-0.rockspec index 030baad00b5f..14fd0ceacc03 100644 --- a/kong/plugins/aws-lambda/kong-plugin-aws-lambda-3.5.4-1.rockspec +++ b/kong/plugins/aws-lambda/kong-plugin-aws-lambda-3.6.3-0.rockspec @@ -1,10 +1,10 @@ package = "kong-plugin-aws-lambda" -version = "3.5.4-1" +version = "3.6.3-1" supported_platforms = {"linux", "macosx"} source = { url = "git://github.com/kong/kong-plugin-aws-lambda", - tag = "3.5.4", + tag = "3.6.3", } description = { @@ -26,7 +26,6 @@ build = { ["kong.plugins.aws-lambda.iam-ecs-credentials"] = "kong/plugins/aws-lambda/iam-ecs-credentials.lua", ["kong.plugins.aws-lambda.schema"] = "kong/plugins/aws-lambda/schema.lua", ["kong.plugins.aws-lambda.v4"] = "kong/plugins/aws-lambda/v4.lua", - ["kong.plugins.aws-lambda.http.connect-better"] = "kong/plugins/aws-lambda/http/connect-better.lua", ["kong.plugins.aws-lambda.request-util"] = "kong/plugins/aws-lambda/request-util.lua", } } diff --git a/kong/plugins/aws-lambda/schema.lua b/kong/plugins/aws-lambda/schema.lua index 536ebca88812..6ddb4d8c22d2 100644 --- a/kong/plugins/aws-lambda/schema.lua +++ b/kong/plugins/aws-lambda/schema.lua @@ -77,6 +77,7 @@ return { type = "boolean", default = false, } }, + -- TODO: remove proxy_scheme in Kong 3.0 { proxy_scheme = { type = "string", one_of = { "http", "https" } @@ -95,7 +96,23 @@ return { } }, entity_checks = { { mutually_required = { "config.aws_key", "config.aws_secret" } }, - { mutually_required = { "config.proxy_scheme", "config.proxy_url" } }, { mutually_exclusive = { "config.aws_region", "config.host" } }, + { custom_entity_check = { + field_sources = { "config.proxy_url" }, + fn = function(entity) + local proxy_url = entity.config and entity.config.proxy_url + + if type(proxy_url) == "string" then + local scheme = proxy_url:match("^([^:]+)://") + + if scheme and scheme ~= "http" then + return nil, "proxy_url scheme must be http" + end + end + + return true + end, + } + }, } } diff --git a/spec/03-plugins/27-aws-lambda/02-schema_spec.lua b/spec/03-plugins/27-aws-lambda/02-schema_spec.lua index fd59d1d0bd92..4f97c1cb7d9b 100644 --- a/spec/03-plugins/27-aws-lambda/02-schema_spec.lua +++ b/spec/03-plugins/27-aws-lambda/02-schema_spec.lua @@ -79,15 +79,18 @@ describe("Plugin: AWS Lambda (schema)", function() assert.falsy(ok) end) - it("errors if proxy_scheme is missing while proxy_url is provided", function() - local ok, err = v({ - proxy_url = "http://hello.com/proxy", - aws_region = "us-east-1", - function_name = "my-function" - }, schema_def) - - assert.equal("all or none of these fields must be set: 'config.proxy_scheme', 'config.proxy_url'", err["@entity"][1]) - assert.falsy(ok) + it("errors with a non-http proxy_url", function() + for _, scheme in ipairs({"https", "ftp", "wss"}) do + local ok, err = v({ + proxy_url = scheme .. "://squid:3128", + aws_region = "us-east-1", + function_name = "my-function" + }, schema_def) + + assert.not_nil(err) + assert.falsy(ok) + assert.equals("proxy_url scheme must be http", err["@entity"][1]) + end end) it("accepts a host", function() diff --git a/spec/03-plugins/27-aws-lambda/50-http-proxy_spec.lua b/spec/03-plugins/27-aws-lambda/50-http-proxy_spec.lua deleted file mode 100644 index b732fdcd766b..000000000000 --- a/spec/03-plugins/27-aws-lambda/50-http-proxy_spec.lua +++ /dev/null @@ -1,133 +0,0 @@ -require "spec.helpers" -local http = require "resty.http" - -local configs = { - { - name = "plain #http", - scheme = "http", - host = "httpbin.org", - path = "/anything", - },{ - name = "plain #https", - scheme = "https", - host = "httpbin.org", - path = "/anything", - },{ - name = "#http via proxy", - scheme = "http", - host = "mockbin.org", - path = "/request", - proxy_url = "http://127.0.0.1:3128/", - },{ - name = "#https via proxy", - scheme = "https", - host = "mockbin.org", - path = "/request", - proxy_url = "http://127.0.0.1:3128/", - },{ - name = "#http via authenticated proxy", - scheme = "http", - host = "httpbin.org", - path = "/anything", - proxy_url = "http://127.0.0.1:3128/", - authorization = "Basic a29uZzpraW5n", -- base64("kong:king") - },{ - name = "#https via authenticated proxy", - scheme = "https", - host = "httpbin.org", - path = "/anything", - proxy_url = "http://127.0.0.1:3128/", - authorization = "Basic a29uZzpraW5n", -- base64("kong:king") - } -} - -local max_idle_timeout = 3 - -local function make_request(config) - -- create and connect the client - local client = http.new() - local ok, err = client:connect { - scheme = config.scheme, - host = config.host, - port = config.scheme == "https" and 443 or 80, - ssl_verify = config.scheme == "https" and false, - ssl_server_name = config.scheme == "https" and config.host, - proxy_opts = config.proxy_url and { - http_proxy = config.proxy_url, - http_proxy_authorization = config.authorization, - } - } - assert.is_nil(err) - assert.truthy(ok) - - -- make the request - local res, err = client:request { - method = "GET", - path = config.path, - body = nil, - headers = { - Host = config.host, - -- for plain http; proxy-auth must be in the headers - ["Proxy-Authorization"] = (config.scheme == "http" and config.authorization), - } - } - - assert.is_nil(err) - assert.truthy(res) - - -- read the body to finish socket ops - res.body = res:read_body() - local reuse = client.sock:getreusedtimes() - - -- close it - ok, err = client:set_keepalive(max_idle_timeout) --luacheck: ignore - --assert.is_nil(err) -- result can be: 2, with error connection had to be closed - assert.truthy(ok) -- resul 2 also qualifies as truthy. - - -- verify http result - if res.status ~= 200 then assert.equal({}, res) end - assert.equal(200, res.status) - return reuse -end - - - - -describe("#proxy #squid", function() - lazy_teardown(function() - ngx.sleep(max_idle_timeout + 0.5) -- wait for keepalive to expire and all socket pools to become empty again - end) - - for _, config in ipairs(configs) do - it("Make a request " .. config.name, function() - make_request(config) - end) - end - -end) - - - -describe("#keepalive #squid", function() - lazy_teardown(function() - ngx.sleep(max_idle_timeout + 0.5) -- wait for keepalive to expire and all socket pools to become empty again - end) - - for _, config in ipairs(configs) do - it("Repeat a request " .. config.name, function() - local reuse = 0 - local loop_size = 10 - - for i = 1, loop_size do - local conn_count = make_request(config) - reuse = math.max(reuse, conn_count) - end - - --print(reuse) - assert(reuse > 0, "expected socket re-use to be > 0, but got: " .. tostring(reuse)) - assert(reuse < loop_size, "re-use expected to be less than " .. loop_size .. - " but was " .. reuse .. ". So probably the socket-poolname is not unique?") - end) - end - -end) diff --git a/spec/03-plugins/27-aws-lambda/99-access_spec.lua b/spec/03-plugins/27-aws-lambda/99-access_spec.lua index 87f8d3b3ae31..5115e7c2d71f 100644 --- a/spec/03-plugins/27-aws-lambda/99-access_spec.lua +++ b/spec/03-plugins/27-aws-lambda/99-access_spec.lua @@ -129,6 +129,13 @@ for _, strategy in helpers.each_strategy() do service = null, } + local route20 = bp.routes:insert { + hosts = { "lambda20.test" }, + protocols = { "http", "https" }, + service = null, + } + + bp.plugins:insert { name = "aws-lambda", route = { id = route1.id }, @@ -389,6 +396,20 @@ for _, strategy in helpers.each_strategy() do } } + bp.plugins:insert { + name = "aws-lambda", + route = { id = route20.id }, + config = { + port = 10001, + aws_key = "mock-key", + aws_secret = "mock-secret", + function_name = "functionEcho", + proxy_url = "http://127.0.0.1:13128", + keepalive = 1, + } + } + + fixtures.dns_mock:A({ name = "lambda18.test", address = helpers.mock_upstream_host, @@ -400,6 +421,10 @@ for _, strategy in helpers.each_strategy() do database = strategy, plugins = "aws-lambda", nginx_conf = "spec/fixtures/custom_nginx.template", + + -- we don't actually use any stream proxy features in this test suite, + -- but this is needed in order to load our forward-proxy stream_mock fixture + stream_listen = helpers.get_proxy_ip(false) .. ":19000", }, nil, nil, fixtures)) end) @@ -1001,6 +1026,20 @@ for _, strategy in helpers.each_strategy() do assert.is_string(res.headers.age) assert.is_array(res.headers["Access-Control-Allow-Origin"]) end) + + it("works with a forward proxy", function() + local res = assert(proxy_client:send({ + method = "GET", + path = "/get?a=1&b=2", + headers = { + ["Host"] = "lambda20.test" + } + })) + + assert.res_status(200, res) + local req = assert.response(res).has.jsonbody() + assert.equals("https", req.vars.scheme) + end) end) end) end diff --git a/spec/fixtures/aws-lambda.lua b/spec/fixtures/aws-lambda.lua index 7798428a640d..78972384aefe 100644 --- a/spec/fixtures/aws-lambda.lua +++ b/spec/fixtures/aws-lambda.lua @@ -45,6 +45,9 @@ local fixtures = { elseif string.match(ngx.var.uri, "functionWithMultiValueHeadersResponse") then ngx.say("{\"statusCode\": 200, \"headers\": { \"Age\": \"3600\"}, \"multiValueHeaders\": {\"Access-Control-Allow-Origin\": [\"site1.com\", \"site2.com\"]}}") + elseif string.match(ngx.var.uri, "functionEcho") then + require("spec.fixtures.mock_upstream").send_default_json_response() + elseif type(res) == 'string' then ngx.header["Content-Length"] = #res + 1 ngx.say(res) @@ -96,6 +99,17 @@ local fixtures = { }, } +fixtures.stream_mock = { + lambda_proxy = [[ + server { + listen 13128; + + content_by_lua_block { + require("spec.fixtures.forward-proxy-server").connect() + } + } + ]], +} fixtures.dns_mock:A { name = "lambda.us-east-1.amazonaws.com", diff --git a/spec/fixtures/forward-proxy-server.lua b/spec/fixtures/forward-proxy-server.lua new file mode 100644 index 000000000000..61bda1196a9b --- /dev/null +++ b/spec/fixtures/forward-proxy-server.lua @@ -0,0 +1,76 @@ +local _M = {} + +local split = require("kong.tools.utils").split + + +-- This is a very naive forward proxy, which accepts a CONNECT over HTTP, and +-- then starts tunnelling the bytes blind (for end-to-end SSL). +function _M.connect() + + local req_sock = ngx.req.socket(true) + req_sock:settimeouts(1000, 1000, 1000) + + -- receive request line + local req_line = req_sock:receive() + ngx.log(ngx.DEBUG, "request line: ", req_line) + + local method, host_port = unpack(split(req_line, " ")) + if method ~= "CONNECT" then + return ngx.exit(400) + end + + local upstream_host, upstream_port = unpack(split(host_port, ":")) + + -- receive and discard any headers + repeat + local line = req_sock:receive("*l") + ngx.log(ngx.DEBUG, "request header: ", line) + until ngx.re.find(line, "^\\s*$", "jo") + + -- Connect to requested upstream + local upstream_sock = ngx.socket.tcp() + upstream_sock:settimeouts(1000, 1000, 1000) + local ok, err = upstream_sock:connect(upstream_host, upstream_port) + if not ok then + ngx.log(ngx.ERR, "connect to upstream ", upstream_host, ":", upstream_port, + " failed: ", err) + return ngx.exit(504) + end + + -- Tell the client we are good to go + ngx.print("HTTP/1.1 200 OK\n\n") + ngx.flush() + + -- 10Kb in either direction should be plenty + local max_bytes = 10 * 1024 + + repeat + local req_data = req_sock:receiveany(max_bytes) + if req_data then + ngx.log(ngx.DEBUG, "client RCV ", #req_data, " bytes") + + local bytes, err = upstream_sock:send(req_data) + if bytes then + ngx.log(ngx.DEBUG, "upstream SND ", bytes, " bytes") + elseif err then + ngx.log(ngx.ERR, "upstream SND failed: ", err) + end + end + + local res_data = upstream_sock:receiveany(max_bytes) + if res_data then + ngx.log(ngx.DEBUG, "upstream RCV ", #res_data, " bytes") + + local bytes, err = req_sock:send(res_data) + if bytes then + ngx.log(ngx.DEBUG, "client SND: ", bytes, " bytes") + elseif err then + ngx.log(ngx.ERR, "client SND failed: ", err) + end + end + until not req_data and not res_data -- request socket should be closed + + upstream_sock:close() +end + +return _M From 5da00c5bafc31f0acd54290facf6fc1b383cf120 Mon Sep 17 00:00:00 2001 From: Alan Boudreault Date: Tue, 22 Feb 2022 09:48:13 -0500 Subject: [PATCH 02/74] chore(rate-limiting) bump plugin version --- kong/plugins/rate-limiting/handler.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kong/plugins/rate-limiting/handler.lua b/kong/plugins/rate-limiting/handler.lua index a5af871f8f67..9d64306757c1 100644 --- a/kong/plugins/rate-limiting/handler.lua +++ b/kong/plugins/rate-limiting/handler.lua @@ -47,7 +47,7 @@ local RateLimitingHandler = {} RateLimitingHandler.PRIORITY = 901 -RateLimitingHandler.VERSION = "2.3.0" +RateLimitingHandler.VERSION = "2.4.0" local function get_identifier(conf) From d6396348776ecdf01847c9abeac58f13a4c8f5b1 Mon Sep 17 00:00:00 2001 From: Alan Boudreault Date: Tue, 22 Feb 2022 09:48:47 -0500 Subject: [PATCH 03/74] chore(response-ratelimiting) bump plugin version --- kong/plugins/response-ratelimiting/handler.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kong/plugins/response-ratelimiting/handler.lua b/kong/plugins/response-ratelimiting/handler.lua index 637c43b1e483..5afca49ac613 100644 --- a/kong/plugins/response-ratelimiting/handler.lua +++ b/kong/plugins/response-ratelimiting/handler.lua @@ -27,7 +27,7 @@ end ResponseRateLimitingHandler.PRIORITY = 900 -ResponseRateLimitingHandler.VERSION = "2.0.1" +ResponseRateLimitingHandler.VERSION = "2.1.0" return ResponseRateLimitingHandler From 14675020b1ba1312c7ab28b28e0d89ca07e88a32 Mon Sep 17 00:00:00 2001 From: Guilherme Salazar Date: Wed, 23 Feb 2022 14:04:31 -0300 Subject: [PATCH 04/74] docs(changelog) add deprecation of go-pluginserver --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f6fc3138a1..954ca93fbd7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,12 @@ ## [2.8.0] (UNRELEASED) +### Deprecations + +- The external [go-pluginserver](https://github.com/Kong/go-pluginserver) project +is considered deprecated in favor of the embedded server approach described in +the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). + ### Dependencies - OpenSSL bumped to 1.1.1m From 7ca08864179ceff5aed09ceecb7ff681288432dc Mon Sep 17 00:00:00 2001 From: Falon Darville Date: Tue, 15 Feb 2022 21:39:17 -0800 Subject: [PATCH 05/74] docs(autodoc) Update Admin API note (#8405) --- autodoc/admin-api/generate.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autodoc/admin-api/generate.lua b/autodoc/admin-api/generate.lua index 02b3f6f2223a..9d0fa4e3341b 100755 --- a/autodoc/admin-api/generate.lua +++ b/autodoc/admin-api/generate.lua @@ -542,7 +542,7 @@ local function write_endpoint(outfd, endpoint, ep_data, dbless_methods) or not dbless_methods[endpoint][method]) then write_title(outfd, 3, meth_data.title) - warning_message(outfd, "**Note**: Not available in DB-less mode.") + warning_message(outfd, "**Note**: This API is not available in DB-less mode.") else write_title(outfd, 3, meth_data.title, "{:.badge .dbless}") end From d61a0c9d59d89f58e12c58da350a669b282edf01 Mon Sep 17 00:00:00 2001 From: Falon Darville Date: Tue, 15 Feb 2022 21:40:38 -0800 Subject: [PATCH 06/74] docs(autodoc) Update Admin API Target Object (#8413) * Update Admin API note * [DOCU-2140] Admin API: rm wording about cannot delete/mod --- autodoc/admin-api/data/admin-api.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/autodoc/admin-api/data/admin-api.lua b/autodoc/admin-api/data/admin-api.lua index 55c804a6ad60..11a99abd85b2 100644 --- a/autodoc/admin-api/data/admin-api.lua +++ b/autodoc/admin-api/data/admin-api.lua @@ -1606,8 +1606,7 @@ return { service. Every upstream can have many targets, and the targets can be dynamically added, modified, or deleted. Changes take effect on the fly. - Because the upstream maintains a history of target changes, the targets cannot - be deleted or modified. To disable a target, post a new one with `weight=0`; + To disable a target, post a new one with `weight=0`; alternatively, use the `DELETE` convenience method to accomplish the same. The current target object definition is the one with the latest `created_at`. From 8c29a240b4e7a8bf0fe016ec3d5a0c2bbbc271e8 Mon Sep 17 00:00:00 2001 From: Javier Date: Wed, 16 Feb 2022 07:11:39 -0500 Subject: [PATCH 07/74] fix(go-pdk) request.GetRawBody when buffered (#8390) --- kong/pluginsocket.proto | 10 +++++++++- kong/runloop/plugin_servers/pb_rpc.lua | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/kong/pluginsocket.proto b/kong/pluginsocket.proto index d005025d1c53..305ce8c51435 100644 --- a/kong/pluginsocket.proto +++ b/kong/pluginsocket.proto @@ -113,6 +113,14 @@ message CertificateKey { string id = 1; } +message RawBodyResult { + oneof kind { + bytes content = 1; + string body_filepath = 2; + string error = 3; + } +} + message Route { string id = 1; int64 created_at = 2; @@ -292,7 +300,7 @@ service Kong { rpc Request_GetQuery(Int) returns (google.protobuf.Struct); rpc Request_GetHeader(String) returns (String); rpc Request_GetHeaders(Int) returns (google.protobuf.Struct); - rpc Request_GetRawBody(google.protobuf.Empty) returns (String); + rpc Request_GetRawBody(google.protobuf.Empty) returns (RawBodyResult); rpc Response_GetStatus(google.protobuf.Empty) returns (Int); rpc Response_GetHeader(String) returns (String); diff --git a/kong/runloop/plugin_servers/pb_rpc.lua b/kong/runloop/plugin_servers/pb_rpc.lua index d4cf8b0f6c65..38f3aafe7d7b 100644 --- a/kong/runloop/plugin_servers/pb_rpc.lua +++ b/kong/runloop/plugin_servers/pb_rpc.lua @@ -151,6 +151,18 @@ do [".kong_plugin_protocol.Number"] = wrap_val, [".kong_plugin_protocol.Int"] = wrap_val, [".kong_plugin_protocol.String"] = wrap_val, + [".kong_plugin_protocol.RawBodyResult"] = function(v, err) + if type(v) == "string" then + return { content = v } + end + + local path = ngx.req.get_body_file() + if path then + return { body_filepath = path } + end + + return { error = err or "Can't read request body" } + end, --[".kong_plugin_protocol.MemoryStats"] = - function(v) -- return { -- lua_shared_dicts = { From 75e569abe49cce8952960957976414e80ceecd1c Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Tue, 15 Feb 2022 17:43:20 +0200 Subject: [PATCH 08/74] fix(pdk) missing vault was not handled correctly and could lead to runtime error --- kong/pdk/vault.lua | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/kong/pdk/vault.lua b/kong/pdk/vault.lua index eeb4d829bcbb..fead23e54bdf 100644 --- a/kong/pdk/vault.lua +++ b/kong/pdk/vault.lua @@ -170,7 +170,6 @@ end local function config_secret(reference, opts) - local vault, strategy, err local kong = kong if not kong.db then return nil, "kong.db not yet loaded" @@ -178,24 +177,27 @@ local function config_secret(reference, opts) local name = opts.name local vaults = kong.db.vaults_beta local cache = kong.core_cache + local vault + local err if cache then local cache_key = vaults:cache_key(name) vault, err = cache:get(cache_key, nil, vaults.select_by_prefix, vaults, name) - if not vault then - if err then - return nil, fmt("unable to load vault (%s): %s [%s]", name, err, reference) - end - return nil, fmt("vault not found (%s) [%s]", name, reference) + else + vault, err = vaults:select_by_prefix(name) + end + + if not vault then + if err then + return nil, fmt("unable to load vault (%s): %s [%s]", name, err, reference) end - else - vault = vaults:select_by_prefix(name) + return nil, fmt("vault not found (%s) [%s]", name, reference) end local vname = vault.name - strategy = vaults.strategies[vname] + local strategy = vaults.strategies[vname] if not strategy then return nil, fmt("vault not installed (%s) [%s]", vname, reference) end From 970b398af96f987c5c3bc33ba1be00ce322f43b7 Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Tue, 15 Feb 2022 20:06:03 +0200 Subject: [PATCH 09/74] fix(pdk) change detection of process/config secrets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary Previously we used `ngx.IS_CLI` to determine whether we want config secret or a process secret, that is: - should we look database for entity prefix - should we look our vault implementations by name We decided (with Joshua) that talking about process secrets / config secrets is confusing to users, so I changed the detection algorithm to: We look for implementation by name when: 1. name is one of the bundled vaults or specified in ´KONG_VAULTS=...` 2. OR kong and kong.db is uninitialized Otherwise, we look for database prefix. This PR also disallows configuring Vault entity prefix with value that is a name of one of the bundled vaults or specified in `KONG_VAULTS`. I also added admin API tests with this. --- kong/cmd/vault.lua | 20 +- kong/db/schema/entities/vaults_beta.lua | 39 ++- kong/pdk/vault.lua | 31 +- spec/02-integration/02-cmd/14-vault_spec.lua | 2 +- .../04-admin_api/19-vaults_spec.lua | 289 ++++++++++++++++++ 5 files changed, 352 insertions(+), 29 deletions(-) create mode 100644 spec/02-integration/04-admin_api/19-vaults_spec.lua diff --git a/kong/cmd/vault.lua b/kong/cmd/vault.lua index 55a3a504b6fa..16f19a5154a9 100644 --- a/kong/cmd/vault.lua +++ b/kong/cmd/vault.lua @@ -38,8 +38,6 @@ local function init_db(args) assert(db.vaults_beta:load_vault_schemas(conf.loaded_vaults)) _G.kong.db = db - - return db end @@ -51,7 +49,7 @@ local function get(args) return error("the 'get' command needs a argument \nkong vault get ") end - local db = init_db(args) + init_db(args) if not vault.is_reference(reference) then -- assuming short form: /[/] @@ -63,21 +61,7 @@ local function get(args) return error(err) end - local name = opts.name - local res - - local vaults = db.vaults_beta - if vaults.strategies[name] then - res, err = vault.get(reference) - - elseif vaults:select_by_prefix(name) then - ngx.IS_CLI = false - res, err = vault.get(reference) - ngx.IS_CLI = true - else - error(fmt("vault '%s' was not found", name, name, args[1])) - end - + local res, err = vault.get(reference) if err then return error(err) end diff --git a/kong/db/schema/entities/vaults_beta.lua b/kong/db/schema/entities/vaults_beta.lua index f07201109064..25d2616e38cf 100644 --- a/kong/db/schema/entities/vaults_beta.lua +++ b/kong/db/schema/entities/vaults_beta.lua @@ -1,6 +1,43 @@ local typedefs = require "kong.db.schema.typedefs" +local VAULTS do + local i = 0 + local pairs = pairs + local names = {} + local constants = require "kong.constants" + local bundled = constants and constants.BUNDLED_VAULTS + if bundled then + for name in pairs(bundled) do + if not names[name] then + names[name] = true + i = i + 1 + if i == 1 then + VAULTS = { name } + else + VAULTS[i] = name + end + end + end + end + + local loaded_vaults = kong and kong.configuration and kong.configuration.loaded_vaults + if loaded_vaults then + for name in pairs(loaded_vaults) do + if not names[name] then + names[name] = true + i = i + 1 + if i == 1 then + VAULTS = { name } + else + VAULTS[i] = name + end + end + end + end +end + + return { name = "vaults_beta", primary_key = { "id" }, @@ -16,7 +53,7 @@ return { -- note: prefix must be valid in a host part of vault reference uri: -- {vault:///[/ Date: Wed, 16 Feb 2022 14:51:07 +0200 Subject: [PATCH 10/74] fix(db) when auto-dereferencing fails set value to nil ### Summary When auto-dereferencing secrets fail, we have two options: 1. keep the value (which means the value is actually a reference such as: `{vault://env/cert-1/key}` 2. set value to `nil` In both cases the error is also logged. Original implementation followed 1. but this commit changes it to 2. Reason being that reference strings can leak to secrets, which they are not meant to. For example session plugin has secret. If you set secret to `{vault://env/session-secret}` and the dereferencing fails, the secret becomes `{vault://env/session-secret}`. This can lead to potential leak of secret on a system that does not resolve secrets correctly. Or at least it is not good idea that references can become secrets. This commit changes it so that on failure (we log the warning) and also set the value to `nil`. --- kong/db/schema/init.lua | 9 +++- .../13-vaults/01-vault_spec.lua | 48 ++++++++++++++----- spec/helpers.lua | 6 ++- spec/kong_tests.conf | 1 + 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/kong/db/schema/init.lua b/kong/db/schema/init.lua index c5ba60affb46..7b642ab21030 100644 --- a/kong/db/schema/init.lua +++ b/kong/db/schema/init.lua @@ -1665,6 +1665,7 @@ function Schema:process_auto_fields(data, context, nulls, opts) -- and and admin api requests, admin api request could be -- detected with ngx.ctx.KONG_PHASE, but to limit context -- access we use nulls that admin api sets to true. + local kong = kong local resolve_references if is_select and not nulls then if kong and kong.configuration then @@ -1733,10 +1734,12 @@ function Schema:process_auto_fields(data, context, nulls, opts) value = deref else if err then - kong.log.warn("unable to resolve reference ", value, "(", err, ")") + kong.log.warn("unable to resolve reference ", value, " (", err, ")") else kong.log.warn("unable to resolve reference ", value) end + + value = nil end end @@ -1752,10 +1755,12 @@ function Schema:process_auto_fields(data, context, nulls, opts) value = deref else if err then - kong.log.warn("unable to resolve reference ", value, "(", err, ")") + kong.log.warn("unable to resolve reference ", value, " (", err, ")") else kong.log.warn("unable to resolve reference ", value) end + + value[i] = nil end end end diff --git a/spec/02-integration/13-vaults/01-vault_spec.lua b/spec/02-integration/13-vaults/01-vault_spec.lua index 26a9bf6e3834..f048d2db5dee 100644 --- a/spec/02-integration/13-vaults/01-vault_spec.lua +++ b/spec/02-integration/13-vaults/01-vault_spec.lua @@ -6,9 +6,14 @@ local cjson = require "cjson" for _, strategy in helpers.each_strategy() do describe("/certificates with DB: #" .. strategy, function() local client + local db lazy_setup(function() - helpers.get_db_utils(strategy, { + helpers.setenv("CERT", ssl_fixtures.cert) + helpers.setenv("KEY", ssl_fixtures.key) + + local _ + _, db = helpers.get_db_utils(strategy, { "certificates", "vaults_beta", }) @@ -38,27 +43,44 @@ for _, strategy in helpers.each_strategy() do lazy_teardown(function() helpers.stop_kong() + helpers.unsetenv("CERT") + helpers.unsetenv("KEY") end) it("create certificates with cert and key as secret", function() - finally(function() - helpers.unsetenv("CERT") - helpers.unsetenv("KEY") - end) - helpers.setenv("CERT", ssl_fixtures.cert) - helpers.setenv("KEY", ssl_fixtures.key) local res, err = client:post("/certificates", { - body = { - cert = "{vault://test-vault/cert}", - key = "{vault://test-vault/key}", - }, headers = { ["Content-Type"] = "application/json" }, + body = { + cert = "{vault://test-vault/cert}", + key = "{vault://test-vault/key}", + cert_alt = "{vault://unknown/cert}", + key_alt = "{vault://unknown/missing-key}", + }, }) assert.is_nil(err) local body = assert.res_status(201, res) local certificate = cjson.decode(body) - assert.not_nil(certificate.key) - assert.not_nil(certificate.cert) + assert.equal("{vault://test-vault/cert}", certificate.cert) + assert.equal("{vault://test-vault/key}", certificate.key) + assert.equal("{vault://unknown/cert}", certificate.cert_alt) + assert.equal("{vault://unknown/missing-key}", certificate.key_alt) + + certificate, err = db.certificates:select({ id = certificate.id }) + assert.is_nil(err) + assert.equal(ssl_fixtures.cert, certificate.cert) + assert.equal(ssl_fixtures.key, certificate.key) + assert.is_nil(certificate.cert_alt) + assert.is_nil(certificate.key_alt) + + -- TODO: this is unexpected but schema.process_auto_fields uses currently + -- the `nulls` parameter to detect if the call comes from Admin API + -- for performance reasons + certificate, err = db.certificates:select({ id = certificate.id }, { nulls = true }) + assert.is_nil(err) + assert.equal("{vault://test-vault/cert}", certificate.cert) + assert.equal("{vault://test-vault/key}", certificate.key) + assert.equal("{vault://unknown/cert}", certificate.cert_alt) + assert.equal("{vault://unknown/missing-key}", certificate.key_alt) end) end) end diff --git a/spec/helpers.lua b/spec/helpers.lua index 4eb993ceca87..644b40df320e 100644 --- a/spec/helpers.lua +++ b/spec/helpers.lua @@ -183,16 +183,19 @@ _G.kong = kong_global.new() kong_global.init_pdk(_G.kong, conf, nil) -- nil: latest PDK ngx.ctx.KONG_PHASE = kong_global.phases.access _G.kong.core_cache = { - get = function(self, key) + get = function(self, key, opts, func, ...) if key == constants.CLUSTER_ID_PARAM_KEY then return "123e4567-e89b-12d3-a456-426655440000" end + + return func(...) end } local db = assert(DB.new(conf)) assert(db:init_connector()) db.plugins:load_plugin_schemas(conf.loaded_plugins) +db.vaults_beta:load_vault_schemas(conf.loaded_vaults) local blueprints = assert(Blueprints.new(db)) local dcbp local config_yml @@ -399,6 +402,7 @@ local function get_db_utils(strategy, tables, plugins) db:truncate("plugins") assert(db.plugins:load_plugin_schemas(conf.loaded_plugins)) + assert(db.vaults_beta:load_vault_schemas(conf.loaded_vaults)) -- cleanup the tags table, since it will be hacky and -- not necessary to implement "truncate trigger" in Cassandra diff --git a/spec/kong_tests.conf b/spec/kong_tests.conf index 0dea3407f12a..de46df2aa009 100644 --- a/spec/kong_tests.conf +++ b/spec/kong_tests.conf @@ -39,3 +39,4 @@ go_plugins_dir = off untrusted_lua = sandbox +vaults = bundled From 5bbc8ff047ea27ddab75aa7462db0dbd5cfd021a Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 16 Feb 2022 20:46:09 +0200 Subject: [PATCH 11/74] fix(pdk) vault process configs loading with strategy that has "-" in its name ### Summary This will just convert possible `-` in strategy name with `_` when loading its configuration for process secrets. --- kong/pdk/vault.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kong/pdk/vault.lua b/kong/pdk/vault.lua index 59f845a4894b..c21f3dfda727 100644 --- a/kong/pdk/vault.lua +++ b/kong/pdk/vault.lua @@ -20,6 +20,7 @@ local ngx = ngx local fmt = string.format local sub = string.sub local byte = string.byte +local gsub = string.gsub local type = type local next = next local pcall = pcall @@ -157,10 +158,11 @@ local function process_secret(reference, opts) if kong and kong.configuration then local configuration = kong.configuration local fields = field.fields + local env_name = gsub(name, "-", "_") for i = 1, #fields do local k = next(fields[i]) if config[k] == nil then - local n = lower(fmt("vault_%s_%s", name, k)) + local n = lower(fmt("vault_%s_%s", env_name, k)) local v = configuration[n] if v ~= nil then config[k] = v From 601cb7587a2f551a72701f01b8cfa304ef68e7ac Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 16 Feb 2022 20:47:17 +0200 Subject: [PATCH 12/74] fix(pdk) env vault to replace "-" in resource with "_" ### Summary This will just convert possible `-` in resource name with `_` when looking up for an environment variable. --- kong/vaults/env/init.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kong/vaults/env/init.lua b/kong/vaults/env/init.lua index 2144a1538821..713bb8443fd3 100644 --- a/kong/vaults/env/init.lua +++ b/kong/vaults/env/init.lua @@ -1,4 +1,5 @@ local type = type +local gsub = string.gsub local upper = string.upper local kong = kong @@ -35,15 +36,20 @@ end local function get(conf, resource, version) local prefix = conf.prefix + + resource = gsub(resource, "-", "_") + if type(prefix) == "string" then resource = prefix .. resource end + resource = upper(resource) + if version == 2 then resource = resource .. "_PREVIOUS" end - return ENV[upper(resource)] + return ENV[resource] end From cd9dbb1404d66dbcd151967cd5bcdf40a4c4c861 Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Fri, 18 Feb 2022 13:56:55 +0200 Subject: [PATCH 13/74] chore(deps) bump pgmoon from 1.13.0 to 1.14.0 (#8429) ### Summary See: https://github.com/leafo/pgmoon/releases/tag/v1.14.0 ### Issues Resolved Fix #8259 --- kong-2.7.0-0.rockspec | 2 +- spec/02-integration/03-db/01-db_spec.lua | 172 +++++++++++++++-------- 2 files changed, 115 insertions(+), 59 deletions(-) diff --git a/kong-2.7.0-0.rockspec b/kong-2.7.0-0.rockspec index 92f96ca74266..0f307d517b83 100644 --- a/kong-2.7.0-0.rockspec +++ b/kong-2.7.0-0.rockspec @@ -23,7 +23,7 @@ dependencies = { "version == 1.0.1", "kong-lapis == 1.8.3.1", "lua-cassandra == 1.5.1", - "pgmoon == 1.13.0", + "pgmoon == 1.14.0", "luatz == 0.4", "lua_system_constants == 0.1.4", "lyaml == 6.2.7", diff --git a/spec/02-integration/03-db/01-db_spec.lua b/spec/02-integration/03-db/01-db_spec.lua index 10d58fcd3840..10af4723125d 100644 --- a/spec/02-integration/03-db/01-db_spec.lua +++ b/spec/02-integration/03-db/01-db_spec.lua @@ -285,11 +285,13 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().ssl) end - assert.is_false(db.connector:get_stored_connection().ssl) db:close() end) @@ -308,13 +310,13 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", - db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - end + assert.equal("luasocket", db.connector:get_stored_connection().sock_type) + assert.is_false(db.connector:get_stored_connection().config.ssl) - assert.is_false(db.connector:get_stored_connection().ssl) + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().ssl) + end db:close() end) @@ -339,11 +341,12 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - end + assert.is_true(db.connector:get_stored_connection().config.ssl) - assert.is_true(db.connector:get_stored_connection().ssl) + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().ssl) + end db:close() end) @@ -367,13 +370,13 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", - db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - end + assert.equal("luasocket", db.connector:get_stored_connection().sock_type) + assert.is_true(db.connector:get_stored_connection().config.ssl) - assert.is_true(db.connector:get_stored_connection().ssl) + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().ssl) + end db:close() end) @@ -398,7 +401,12 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(db.connector:get_stored_connection()) -- empty defaults to "write" assert.equal("nginx", db.connector:get_stored_connection("read").sock_type) - assert.is_false(db.connector:get_stored_connection("read").ssl) + + if strategy == "postgres" then + assert.is_false(db.connector:get_stored_connection("read").config.ssl) + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("read").ssl) + end db:close() end) @@ -423,10 +431,20 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(db.connector:get_stored_connection("read")) assert.equal("luasocket", db.connector:get_stored_connection("write").sock_type) - assert.is_false(db.connector:get_stored_connection("write").ssl) + + if strategy == "portgres" then + assert.is_false(db.connector:get_stored_connection("write").config.ssl) + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("write").ssl) + end assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().ssl) + + if strategy == "portgres" then + assert.is_false(db.connector:get_stored_connection("write").config.ssl) + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("write").ssl) + end db:close() end) @@ -451,13 +469,16 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(err) assert.is_table(conn) + if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().ssl) end - assert.is_false(db.connector:get_stored_connection().ssl) assert.is_true(db:setkeepalive()) db:close() @@ -477,13 +498,15 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", - db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.equal("luasocket", db.connector:get_stored_connection().sock_type) + assert.is_false(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().ssl) end - assert.is_false(db.connector:get_stored_connection().ssl) + assert.is_true(db:setkeepalive()) db:close() @@ -509,11 +532,13 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().ssl) end - assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:setkeepalive()) db:close() @@ -538,13 +563,15 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", - db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.equal("luasocket", db.connector:get_stored_connection().sock_type) + assert.is_true(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().ssl) end - assert.is_true(db.connector:get_stored_connection().ssl) + assert.is_true(db:setkeepalive()) db:close() @@ -599,8 +626,14 @@ for _, strategy in helpers.each_strategy() do assert.equal("nginx", db.connector:get_stored_connection("read").sock_type) assert.equal("nginx", db.connector:get_stored_connection("write").sock_type) - assert.is_false(db.connector:get_stored_connection("read").ssl) - assert.is_false(db.connector:get_stored_connection("write").ssl) + if strategy == "postgres" then + assert.is_false(db.connector:get_stored_connection("read").config.ssl) + assert.is_false(db.connector:get_stored_connection("write").config.ssl) + + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("read").ssl) + assert.is_false(db.connector:get_stored_connection("write").ssl) + end assert.is_true(db:setkeepalive()) @@ -634,7 +667,11 @@ for _, strategy in helpers.each_strategy() do assert.equal("luasocket", db.connector:get_stored_connection("write").sock_type) assert.is_nil(db.connector:get_stored_connection("read")) - assert.is_false(db.connector:get_stored_connection("write").ssl) + if strategy == "postgres" then + assert.is_false(db.connector:get_stored_connection("write").config.ssl) + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("write").ssl) + end assert.is_true(db:setkeepalive()) @@ -666,11 +703,14 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().ssl) end - assert.is_false(db.connector:get_stored_connection().ssl) + assert.is_true(db:close()) end) @@ -689,11 +729,14 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_false(db.connector:get_stored_connection().ssl) end - assert.is_false(db.connector:get_stored_connection().ssl) + assert.is_true(db:close()) end) @@ -717,11 +760,13 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().ssl) end - assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:close()) end) @@ -744,13 +789,14 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", - db.connector:get_stored_connection().sock_type) - --elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer + assert.equal("luasocket", db.connector:get_stored_connection().sock_type) + assert.is_true(db.connector:get_stored_connection().config.ssl) + + elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer + assert.is_true(db.connector:get_stored_connection().ssl) end - assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:close()) end) @@ -803,8 +849,14 @@ for _, strategy in helpers.each_strategy() do assert.equal("nginx", db.connector:get_stored_connection("read").sock_type) assert.equal("nginx", db.connector:get_stored_connection("write").sock_type) - assert.is_false(db.connector:get_stored_connection("read").ssl) - assert.is_false(db.connector:get_stored_connection("write").ssl) + if strategy == "postgres" then + assert.is_false(db.connector:get_stored_connection("read").config.ssl) + assert.is_false(db.connector:get_stored_connection("write").config.ssl) + + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("read").ssl) + assert.is_false(db.connector:get_stored_connection("write").ssl) + end assert.is_true(db:close()) @@ -837,7 +889,11 @@ for _, strategy in helpers.each_strategy() do assert.equal("luasocket", db.connector:get_stored_connection("write").sock_type) assert.is_nil(db.connector:get_stored_connection("read")) - assert.is_false(db.connector:get_stored_connection("write").ssl) + if strategy == "postgres" then + assert.is_false(db.connector:get_stored_connection("write").config.ssl) + elseif strategy == "cassandra" then + assert.is_false(db.connector:get_stored_connection("write").ssl) + end assert.is_true(db:close()) From 18874618163eaf9e6613ca5156dc4c77a8133016 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Fri, 18 Feb 2022 16:22:28 -0300 Subject: [PATCH 14/74] fix(declarative) initialize hash for empty config (#8425) * fix(declarative) initialize hash for empty config * docs(CHANGELOG) feature description --- CHANGELOG.md | 7 +++++++ kong/clustering/control_plane.lua | 3 ++- kong/clustering/data_plane.lua | 3 ++- kong/constants.lua | 1 + kong/db/declarative/init.lua | 12 +++++------- .../04-admin_api/02-kong_routes_spec.lua | 6 +++++- .../08-status_api/01-core_routes_spec.lua | 12 ++++++++---- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 954ca93fbd7b..fc88aa72d9fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,6 +118,13 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). Thanks, [@andrewgknew](https://github.com/andrewgknew)! [#8337](https://github.com/Kong/kong/pull/8337) +#### Admin API + +- The current declarative configuration hash is now returned by the `status` + endpoint when Kong node is running in dbless or data-plane mode. + [#8214](https://github.com/Kong/kong/pull/8214) + [#8425](https://github.com/Kong/kong/pull/8425) + ### Fixes #### Core diff --git a/kong/clustering/control_plane.lua b/kong/clustering/control_plane.lua index 1f7e760e2c63..8da305490d3c 100644 --- a/kong/clustering/control_plane.lua +++ b/kong/clustering/control_plane.lua @@ -54,6 +54,7 @@ local PING_INTERVAL = constants.CLUSTERING_PING_INTERVAL local PING_WAIT = PING_INTERVAL * 1.5 local OCSP_TIMEOUT = constants.CLUSTERING_OCSP_TIMEOUT local CLUSTERING_SYNC_STATUS = constants.CLUSTERING_SYNC_STATUS +local DECLARATIVE_EMPTY_CONFIG_HASH = constants.DECLARATIVE_EMPTY_CONFIG_HASH local PONG_TYPE = "PONG" local RECONFIGURE_TYPE = "RECONFIGURE" local MAJOR_MINOR_PATTERN = "^(%d+)%.(%d+)%.%d+" @@ -598,7 +599,7 @@ function _M:handle_cp_websocket() end local dp_plugins_map = plugins_list_to_map(data.plugins) - local config_hash = string.rep("0", 32) -- initial hash + local config_hash = DECLARATIVE_EMPTY_CONFIG_HASH -- initial hash local last_seen = ngx_time() local sync_status = CLUSTERING_SYNC_STATUS.UNKNOWN local purge_delay = self.conf.cluster_data_plane_purge_delay diff --git a/kong/clustering/data_plane.lua b/kong/clustering/data_plane.lua index c866afa453ee..584d09aa61d9 100644 --- a/kong/clustering/data_plane.lua +++ b/kong/clustering/data_plane.lua @@ -43,6 +43,7 @@ local WS_OPTS = { local PING_INTERVAL = constants.CLUSTERING_PING_INTERVAL local PING_WAIT = PING_INTERVAL * 1.5 local _log_prefix = "[clustering] " +local DECLARATIVE_EMPTY_CONFIG_HASH = constants.DECLARATIVE_EMPTY_CONFIG_HASH local function is_timeout(err) @@ -187,7 +188,7 @@ local function send_ping(c, log_suffix) local hash = declarative.get_current_hash() if hash == true then - hash = string.rep("0", 32) + hash = DECLARATIVE_EMPTY_CONFIG_HASH end local _, err = c:send_ping(hash) diff --git a/kong/constants.lua b/kong/constants.lua index 5a78583c829f..f38bb11fe28f 100644 --- a/kong/constants.lua +++ b/kong/constants.lua @@ -187,6 +187,7 @@ local constants = { DECLARATIVE_PAGE_KEY = "declarative:page", DECLARATIVE_LOAD_KEY = "declarative_config:loaded", DECLARATIVE_HASH_KEY = "declarative_config:hash", + DECLARATIVE_EMPTY_CONFIG_HASH = string.rep("0", 32), CLUSTER_ID_PARAM_KEY = "cluster_id", diff --git a/kong/db/declarative/init.lua b/kong/db/declarative/init.lua index dcf3d06ef50c..37a03da151f6 100644 --- a/kong/db/declarative/init.lua +++ b/kong/db/declarative/init.lua @@ -38,14 +38,13 @@ local PREFIX = ngx.config.prefix() local SUBSYS = ngx.config.subsystem local WORKER_COUNT = ngx.worker.count() local DECLARATIVE_HASH_KEY = constants.DECLARATIVE_HASH_KEY +local DECLARATIVE_EMPTY_CONFIG_HASH = constants.DECLARATIVE_EMPTY_CONFIG_HASH local DECLARATIVE_LOCK_KEY = "declarative:lock" local DECLARATIVE_LOCK_TTL = 60 local GLOBAL_QUERY_OPTS = { nulls = true, workspace = null } -local EMPTY_CONFIGURATION_HASH = string.rep("0", 32) - local declarative = {} @@ -608,6 +607,10 @@ function declarative.load_into_cache(entities, meta, hash, shadow) assert(type(fallback_workspace) == "string") + if not hash or hash == "" then + hash = DECLARATIVE_EMPTY_CONFIG_HASH + end + -- Keys: tag name, like "admin" -- Values: array of encoded tags, similar to the `tags` variable, -- but filtered for a given tag @@ -847,11 +850,6 @@ function declarative.load_into_cache(entities, meta, hash, shadow) return nil, err end - -- mask any default hash to indicate no hash is available. - if hash == EMPTY_CONFIGURATION_HASH or hash == "" then - hash = null - end - -- set the value of the configuration hash. The value can be nil, which -- indicates that no configuration has been applied yet to the Gateway. local ok, err = ngx.shared.kong:safe_set(DECLARATIVE_HASH_KEY, hash) diff --git a/spec/02-integration/04-admin_api/02-kong_routes_spec.lua b/spec/02-integration/04-admin_api/02-kong_routes_spec.lua index a7db6e2fd077..d2356072c7b5 100644 --- a/spec/02-integration/04-admin_api/02-kong_routes_spec.lua +++ b/spec/02-integration/04-admin_api/02-kong_routes_spec.lua @@ -207,7 +207,11 @@ describe("Admin API - Kong routes with strategy #" .. strategy, function() assert.is_number(json.server.connections_writing) assert.is_number(json.server.connections_waiting) assert.is_number(json.server.total_requests) - assert.is_nil(json.server.configuration_hash) -- not present in DB mode, or in DBLESS mode until configuration is applied + if strategy == "off" then + assert.is_equal(string.rep("0", 32), json.configuration_hash) -- all 0 in DBLESS mode until configuration is applied + else + assert.is_nil(json.configuration_hash) -- not present in DB mode + end end) it("returns status info including a configuration_hash in DBLESS mode if an initial configuration has been provided #off", function() diff --git a/spec/02-integration/08-status_api/01-core_routes_spec.lua b/spec/02-integration/08-status_api/01-core_routes_spec.lua index cd28b4f7362c..f8fb31285c47 100644 --- a/spec/02-integration/08-status_api/01-core_routes_spec.lua +++ b/spec/02-integration/08-status_api/01-core_routes_spec.lua @@ -21,7 +21,7 @@ describe("Status API - with strategy #" .. strategy, function() end) describe("core", function() - it("/status returns status info without configuration_hash", function() + it("/status returns status info with blank configuration_hash (declarative config) or without it (db mode)", function() local res = assert(client:send { method = "GET", path = "/status" @@ -40,7 +40,11 @@ describe("Status API - with strategy #" .. strategy, function() assert.is_number(json.server.connections_writing) assert.is_number(json.server.connections_waiting) assert.is_number(json.server.total_requests) - assert.is_nil(json.server.configuration_hash) -- no hash in DB mode, or in DBLESS mode until configuration has been applied + if strategy == "off" then + assert.is_equal(string.rep("0", 32), json.configuration_hash) -- all 0 in DBLESS mode until configuration is applied + else + assert.is_nil(json.configuration_hash) -- not present in DB mode + end end) it("/status starts providing a config_hash once an initial configuration has been pushed in dbless mode #off", function() @@ -77,8 +81,8 @@ describe("Status API - with strategy #" .. strategy, function() assert.is_number(json.server.connections_writing) assert.is_number(json.server.connections_waiting) assert.is_number(json.server.total_requests) - assert.is_string(json.server.configuration_hash) - assert.equal(32, #json.server.configuration_hash) + assert.is_string(json.configuration_hash) + assert.equal(32, #json.configuration_hash) end) end) From 79adae5eb46173cd8581841e1ddc7d52b6a66e6d Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Mon, 21 Feb 2022 11:02:05 +0200 Subject: [PATCH 15/74] fix(pdk) fill default values with vault config required fields (#8427) ### Summary This fixes the vault to fill default values for configuration based on a config field schema in case the field is required and has a default value, when there is no configuration for the field already. --- kong/pdk/vault.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kong/pdk/vault.lua b/kong/pdk/vault.lua index c21f3dfda727..77be23caeb11 100644 --- a/kong/pdk/vault.lua +++ b/kong/pdk/vault.lua @@ -160,12 +160,14 @@ local function process_secret(reference, opts) local fields = field.fields local env_name = gsub(name, "-", "_") for i = 1, #fields do - local k = next(fields[i]) + local k, f = next(fields[i]) if config[k] == nil then local n = lower(fmt("vault_%s_%s", env_name, k)) local v = configuration[n] if v ~= nil then config[k] = v + elseif f.required and f.default ~= nil then + config[k] = f.default end end end From 309671c21ee59c84fc5b97c5fc315761956aa182 Mon Sep 17 00:00:00 2001 From: Jakob Strande Langgaard Date: Mon, 21 Feb 2022 15:58:59 +0100 Subject: [PATCH 16/74] fix(cors) don't send vary header with * origin (#8401) --- kong/plugins/cors/handler.lua | 17 ++++++----------- spec/03-plugins/13-cors/01-access_spec.lua | 14 +++++++------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/kong/plugins/cors/handler.lua b/kong/plugins/cors/handler.lua index a6bef366775e..8a04a319ae44 100644 --- a/kong/plugins/cors/handler.lua +++ b/kong/plugins/cors/handler.lua @@ -64,22 +64,16 @@ local function configure_origin(conf, header_filter) local n_origins = conf.origins ~= nil and #conf.origins or 0 local set_header = kong.response.set_header - -- always set Vary header (it can be used for calculating cache key) - -- https://github.com/rs/cors/issues/10 - add_vary_header(header_filter) - - if n_origins == 0 then + if n_origins == 0 or (n_origins == 1 and conf.origins[1] == "*") then set_header("Access-Control-Allow-Origin", "*") return true end - if n_origins == 1 then - if conf.origins[1] == "*" then - set_header("Access-Control-Allow-Origin", "*") - return true - end - + -- always set Vary header (it can be used for calculating cache key) + -- https://github.com/rs/cors/issues/10 + add_vary_header(header_filter) + if n_origins == 1 then -- if this doesnt look like a regex, set the ACAO header directly -- otherwise, we'll fall through to an iterative search and -- set the ACAO header based on the client Origin @@ -183,6 +177,7 @@ local function configure_credentials(conf, allow_all, header_filter) -- be 'true' if ACAO is '*'. local req_origin = kong.request.get_header("origin") if req_origin then + add_vary_header(header_filter) set_header("Access-Control-Allow-Origin", req_origin) set_header("Access-Control-Allow-Credentials", true) end diff --git a/spec/03-plugins/13-cors/01-access_spec.lua b/spec/03-plugins/13-cors/01-access_spec.lua index 8b3fbad8c405..fcdbfa510186 100644 --- a/spec/03-plugins/13-cors/01-access_spec.lua +++ b/spec/03-plugins/13-cors/01-access_spec.lua @@ -570,7 +570,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(res.headers["Access-Control-Expose-Headers"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) assert.is_nil(res.headers["Access-Control-Max-Age"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("gives * wildcard when config.origins is empty", function() @@ -596,7 +596,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(res.headers["Access-Control-Expose-Headers"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) assert.is_nil(res.headers["Access-Control-Max-Age"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("gives appropriate defaults when origin is explicitly set to *", function() @@ -722,7 +722,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(res.headers["Access-Control-Expose-Headers"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) assert.is_nil(res.headers["Access-Control-Max-Age"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("proxies a non-preflight OPTIONS request", function() @@ -742,7 +742,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(res.headers["Access-Control-Expose-Headers"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) assert.is_nil(res.headers["Access-Control-Max-Age"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("accepts config options", function() @@ -811,7 +811,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(res.headers["Access-Control-Expose-Headers"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) assert.is_nil(res.headers["Access-Control-Max-Age"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("works with 40x responses returned by another plugin", function() @@ -828,7 +828,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(res.headers["Access-Control-Expose-Headers"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) assert.is_nil(res.headers["Access-Control-Max-Age"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("sets CORS orgin based on origin host", function() @@ -1015,7 +1015,7 @@ for _, strategy in helpers.each_strategy() do assert.res_status(200, res) assert.equals("*", res.headers["Access-Control-Allow-Origin"]) assert.is_nil(res.headers["Access-Control-Allow-Credentials"]) - assert.equal("Origin", res.headers["Vary"]) + assert.is_nil(res.headers["Vary"]) end) it("removes upstream ACAO header when no match is found", function() From 5717254416d7fa3ca60a075e750dcf83d8d5c737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Mon, 21 Feb 2022 16:25:25 +0100 Subject: [PATCH 17/74] docs(changelog) add missing fix in the changelog. Related #8401 --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc88aa72d9fe..956c1ee3f1f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -170,8 +170,12 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). Thanks, [@raptium](https://github.com/raptium)! [#8280](https://github.com/Kong/kong/pull/8280) - **AWS-Lambda**: Fixed incorrect behavior when configured to use an http proxy - and deprecated the `proxy_scheme` config attribute for removal in 3.0 - [#8406](https://github.com/Kong/kong/pull/8406) + and deprecated the `proxy_scheme` config attribute for removal in 3.0 + [#8406](https://github.com/Kong/kong/pull/8406) +- **CORS**: The CORS plugin does not send the `Vary: Origin` header any more when + the header `Access-Control-Allow-Origin` is set to `*`. + Thanks, [@jkla-dr](https://github.com/jkla-dr)! + [#8401](https://github.com/Kong/kong/pull/8401) ## [2.7.1] From 9e990da473706db267aa5d717bee648de36873a5 Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 16 Feb 2022 10:19:32 +0200 Subject: [PATCH 18/74] fix(oauth2) clear authenticated oauth2 headers with multi-auth ### Summary It was reported that when Kong OAuth 2.0 plugin is configured together with some other authentication plugin with `conf.anonymous` (logical OR), the OAuth 2.0 plugin does not clear `X-Authenticated-UserId` and `X-Authenticated-Scope` headers that it normally only sets on successful authentication (aka when plugin runs). This can lead to potential issue on upstream if upstream rely on these headers and trust that they came from OAuth 2.0 plugin. This change makes OAuth 2.0 plugin to clear such headers in logical OR scenario. It is to be noted that Kong itself worked as expected, it is just about the expectations that upstream service may have made. It is probably harmless to remove these headers when OAuth 2.0 plugin is configured in logical OR. --- kong/plugins/oauth2/access.lua | 4 ++ spec/03-plugins/25-oauth2/03-access_spec.lua | 72 +++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/kong/plugins/oauth2/access.lua b/kong/plugins/oauth2/access.lua index 902844ba4e14..b0ede38aa509 100644 --- a/kong/plugins/oauth2/access.lua +++ b/kong/plugins/oauth2/access.lua @@ -1083,9 +1083,13 @@ function _M.execute(conf) if conf.anonymous and kong.client.get_credential() then -- we're already authenticated, and we're configured for using anonymous, -- hence we're in a logical OR between auth methods and we're already done. + local clear_header = kong.service.request.clear_header + clear_header("X-Authenticated-Scope") + clear_header("X-Authenticated-UserId") return end + local ok, err = do_authentication(conf) if not ok then if conf.anonymous then diff --git a/spec/03-plugins/25-oauth2/03-access_spec.lua b/spec/03-plugins/25-oauth2/03-access_spec.lua index 28f822f3ee7e..50724b8859eb 100644 --- a/spec/03-plugins/25-oauth2/03-access_spec.lua +++ b/spec/03-plugins/25-oauth2/03-access_spec.lua @@ -3,6 +3,8 @@ local helpers = require "spec.helpers" local utils = require "kong.tools.utils" local admin_api = require "spec.fixtures.admin_api" local sha256 = require "resty.sha256" +local jwt_encoder = require "kong.plugins.jwt.jwt_parser" + local math_random = math.random local string_char = string.char @@ -13,6 +15,14 @@ local string_rep = string.rep local ngx_encode_base64 = ngx.encode_base64 +local PAYLOAD = { + iss = nil, + nbf = os.time(), + iat = os.time(), + exp = os.time() + 3600 +} + + local kong = { table = require("kong.pdk.table").new() } @@ -141,6 +151,7 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() "consumers", "plugins", "keyauth_credentials", + "jwt_secrets", "oauth2_credentials", "oauth2_authorization_codes", "oauth2_tokens", @@ -3624,6 +3635,7 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() local user2 local anonymous local keyauth + local jwt_secret lazy_setup(function() local service1 = admin_api.services:insert({ @@ -3668,6 +3680,12 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() service = service2 })) + local route3 = assert(admin_api.routes:insert({ + hosts = { "logical-or-jwt.com" }, + protocols = { "http", "https" }, + service = service2 + })) + admin_api.oauth2_plugins:insert({ route = { id = route2.id }, config = { @@ -3676,6 +3694,14 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() }, }) + admin_api.oauth2_plugins:insert({ + route = { id = route3.id }, + config = { + scopes = { "email", "profile", "user.email" }, + anonymous = anonymous.id, + }, + }) + admin_api.plugins:insert { name = "key-auth", route = { id = route2.id }, @@ -3684,11 +3710,23 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() }, } + admin_api.plugins:insert { + name = "jwt", + route = { id = route3.id }, + config = { + anonymous = anonymous.id, + }, + } + keyauth = admin_api.keyauth_credentials:insert({ key = "Mouse", consumer = { id = user1.id }, }) + jwt_secret = admin_api.jwt_secrets:insert({ + consumer = { id = user1.id } + }) + admin_api.oauth2_credentials:insert { client_id = "clientid4567", client_secret = "secret4567", @@ -3798,15 +3836,18 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() assert.request(res).has.no.header("x-credential-username") end) - it("passes with only the first credential provided", function() + it("passes with only the first credential provided (higher priority)", function() local res = assert(proxy_client:send { method = "GET", path = "/request", headers = { ["Host"] = "logical-or.com", ["apikey"] = "Mouse", + ["X-Authenticated-Scope"] = "all-access", + ["X-Authenticated-UserId"] = "admin", } }) + assert.response(res).has.status(200) assert.request(res).has.no.header("x-anonymous-consumer") local id = assert.request(res).has.header("x-consumer-id") @@ -3815,6 +3856,35 @@ describe("Plugin: oauth2 [#" .. strategy .. "]", function() local client_id = assert.request(res).has.header("x-credential-identifier") assert.equal(keyauth.id, client_id) assert.request(res).has.no.header("x-credential-username") + assert.request(res).has.no.header("x-authenticated-scope") + assert.request(res).has.no.header("x-authenticated-userid") + end) + + it("passes with only the first credential provided (lower priority)", function() + PAYLOAD.iss = jwt_secret.key + local jwt = jwt_encoder.encode(PAYLOAD, jwt_secret.secret) + local authorization = "Bearer " .. jwt + local res = assert(proxy_client:send { + method = "GET", + path = "/request", + headers = { + ["Host"] = "logical-or-jwt.com", + ["Authorization"] = authorization, + ["X-Authenticated-Scope"] = "all-access", + ["X-Authenticated-UserId"] = "admin", + } + }) + + assert.response(res).has.status(200) + assert.request(res).has.no.header("x-anonymous-consumer") + local id = assert.request(res).has.header("x-consumer-id") + assert.not_equal(id, anonymous.id) + assert.equal(user1.id, id) + local client_id = assert.request(res).has.header("x-credential-identifier") + assert.equal(jwt_secret.key, client_id) + assert.request(res).has.no.header("x-credential-username") + assert.request(res).has.no.header("x-authenticated-scope") + assert.request(res).has.no.header("x-authenticated-userid") end) it("passes with only the second credential provided", function() From 734de310d3c662fe3938767519af27c147d7e19f Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Mon, 21 Feb 2022 20:23:09 +0200 Subject: [PATCH 19/74] fix(datadog) default value for metrics specified twice (#8315) --- kong/plugins/datadog/schema.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/kong/plugins/datadog/schema.lua b/kong/plugins/datadog/schema.lua index 8e3b7dfd8e37..b6d9f7eb9a59 100644 --- a/kong/plugins/datadog/schema.lua +++ b/kong/plugins/datadog/schema.lua @@ -72,7 +72,6 @@ return { { protocols = typedefs.protocols }, { config = { type = "record", - default = { metrics = DEFAULT_METRICS }, fields = { { host = typedefs.host({ default = "localhost" }), }, { port = typedefs.port({ default = 8125 }), }, From 9cf81448cb60da4a450d4f96078f43441f105b12 Mon Sep 17 00:00:00 2001 From: Guilherme Salazar Date: Mon, 21 Feb 2022 14:28:26 -0300 Subject: [PATCH 20/74] chore(deprecation) add deprecation warning The properties `go_pluginserver_exe` and `go_pluginserver` are deprecated in favor of new multi-pluginservers implementation. Compatibility code will remain in place until 3.0, when it will be removed. --- kong/runloop/plugin_servers/process.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kong/runloop/plugin_servers/process.lua b/kong/runloop/plugin_servers/process.lua index 248277055606..a44021274f57 100644 --- a/kong/runloop/plugin_servers/process.lua +++ b/kong/runloop/plugin_servers/process.lua @@ -70,7 +70,8 @@ local function get_server_defs() end elseif config.go_plugins_dir ~= "off" then - kong.log.info("old go_pluginserver style") + kong.log.deprecation("Properties go_pluginserver_exe and go_plugins_dir are deprecated. Please refer to https://docs.konghq.com/gateway/latest/reference/external-plugins/", {after = "2.8", removal = "3.0"}) + _servers[1] = { name = "go-pluginserver", socket = config.prefix .. "/go_pluginserver.sock", From 698e7e6f9413303e5b79aa6b5cdfc8c7a33f55bc Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 23 Feb 2022 14:53:58 +0200 Subject: [PATCH 21/74] docs(admin) add docs for vault_beta entity (#8441) ### Summary Adds "autogen" docs to vault_beta entity. Co-authored-by: Joshua Schmid --- autodoc/admin-api/data/admin-api.lua | 62 +++++++++++++++++++++++++++- autodoc/admin-api/generate.lua | 7 +++- autodoc/admin-api/openapi-gen.lua | 4 +- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/autodoc/admin-api/data/admin-api.lua b/autodoc/admin-api/data/admin-api.lua index 11a99abd85b2..501c19e425a7 100644 --- a/autodoc/admin-api/data/admin-api.lua +++ b/autodoc/admin-api/data/admin-api.lua @@ -31,6 +31,7 @@ return { "snis", "upstreams", "targets", + "vaults_beta", }, nodoc_entities = { }, @@ -1884,7 +1885,66 @@ return { }, }, }, - } + }, + + vaults_beta = { + title = "Vaults Beta Entity", + entity_title = "Vault", + entity_title_plural = "Vaults", + description = [[ + Vault entities are used to configure different Vault connectors. Examples of + Vaults are Environment Variables, Hashicorp Vault and AWS Secrets Manager. + + Configuring a Vault allows referencing the secrets with other entities. For + example a certificate entity can store a reference to a certificate and key, + stored in a vault, instead of storing the certificate and key within the + entity. This allows a proper separation of secrets and configuration and + prevents secret sprawl. + ]], + + fields = { + id = { skip = true }, + created_at = { skip = true }, + updated_at = { skip = true }, + name = { + description = [[ + The name of the Vault that's going to be added. Currently, the Vault implementation + must be installed in every Kong instance. + ]], + example = "env", + }, + prefix = { + description = [[ + The unique prefix (or identifier) for this Vault configuration. The prefix + is used to load the right Vault configuration and implementation when referencing + secrets with the other entities. + ]], + example = "env", + }, + description = { + description = [[ + The description of the Vault entity. + ]], + example = "This vault is used to retrieve redis database access credentials", + }, + config = { + description = [[ + The configuration properties for the Vault which can be found on + the vaults' documentation page. + ]], + example = { prefix = "SSL_" }, + }, + tags = { + description = [[ + An optional set of strings associated with the Vault for grouping and filtering. + ]], + examples = { + { "database-credentials", "data-plane" }, + { "certificates", "critical" }, + }, + }, + }, + }, }, -------------------------------------------------------------------------------- diff --git a/autodoc/admin-api/generate.lua b/autodoc/admin-api/generate.lua index 9d0fa4e3341b..c6380fb6ee90 100755 --- a/autodoc/admin-api/generate.lua +++ b/autodoc/admin-api/generate.lua @@ -93,12 +93,14 @@ _KONG = require("kong.meta") -- luacheck: ignore kong = require("kong.global").new() -- luacheck: ignore kong.configuration = { -- luacheck: ignore loaded_plugins = {}, + loaded_vaults = {}, } kong.db = require("kong.db").new({ -- luacheck: ignore database = "postgres", }) kong.configuration = { -- luacheck: ignore - loaded_plugins = {} + loaded_plugins = {}, + loaded_vaults = {}, } -------------------------------------------------------------------------------- @@ -196,6 +198,9 @@ do "0c61e164-6171-4837-8836-8f5298726d53", "5027BBC1-508C-41F8-87F2-AB1801E9D5C3", "68FDB05B-7B08-47E9-9727-AF7F897CFF1A", + "B2A30E8F-C542-49CF-8015-FB674987D1A5", + "518BBE43-2454-4559-99B0-8E7D1CD3E8C8", + "7C4747E9-E831-4ED8-9377-83A6F8A37603", } local ctr = 0 diff --git a/autodoc/admin-api/openapi-gen.lua b/autodoc/admin-api/openapi-gen.lua index b7dd8460efa0..205c3b16df75 100644 --- a/autodoc/admin-api/openapi-gen.lua +++ b/autodoc/admin-api/openapi-gen.lua @@ -33,12 +33,14 @@ _KONG = require("kong.meta") -- luacheck: ignore kong = require("kong.global").new() -- luacheck: ignore kong.configuration = { -- luacheck: ignore loaded_plugins = {}, + loaded_vaults = {}, } kong.db = require("kong.db").new({ -- luacheck: ignore database = "postgres", }) kong.configuration = { -- luacheck: ignore - loaded_plugins = {} + loaded_plugins = {}, + loaded_vaults = {}, } From ea9c4da49baeeafdd746a077e5236c2eacbf3025 Mon Sep 17 00:00:00 2001 From: Kevin Lim <35480603+limkevinkuan@users.noreply.github.com> Date: Wed, 23 Feb 2022 06:27:25 -0800 Subject: [PATCH 22/74] feat(prometheus) add nginx timer metrics (#8387) * feat(prometheus) add nginx timer metrics This adds gauges to track ngx.timer.running_count() and ngx.timer.pending_count() as requested in #7670. * style(prometheus) rename metrics from current timers to just timers Per suggestion, to avoid confusion. * fix(prometheus) fix timer tests failing The tests were accidentally matching in plain mode so '%d+' was not understood. * perf(prometheus) localize ngx timer functions --- kong/plugins/prometheus/exporter.lua | 9 ++++++++- spec/03-plugins/26-prometheus/04-status_api_spec.lua | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/kong/plugins/prometheus/exporter.lua b/kong/plugins/prometheus/exporter.lua index 05ddf8d4983a..e59376e84203 100644 --- a/kong/plugins/prometheus/exporter.lua +++ b/kong/plugins/prometheus/exporter.lua @@ -4,6 +4,8 @@ local find = string.find local lower = string.lower local concat = table.concat local select = select +local ngx_timer_pending_count = ngx.timer.pending_count +local ngx_timer_running_count = ngx.timer.running_count local balancer = require("kong.runloop.balancer") local get_all_upstreams = balancer.get_all_upstreams if not balancer.get_all_upstreams then -- API changed since after Kong 2.5 @@ -48,6 +50,9 @@ local function init() "Number of Stream connections", {"state"}) end + metrics.timers = prometheus:gauge("nginx_timers", + "Number of nginx timers", + {"state"}) metrics.db_reachable = prometheus:gauge("datastore_reachable", "Datastore reachable from Kong, " .. "0 is unreachable") @@ -102,7 +107,6 @@ local function init() "HTTP status codes for customer per service/route in Kong", {"service", "route", "code", "consumer"}) - -- Hybrid mode status if role == "control_plane" then metrics.data_plane_last_seen = prometheus:gauge("data_plane_last_seen", @@ -314,6 +318,9 @@ local function metric_data() metrics.connections:set(ngx.var.connections_writing or 0, { "writing" }) metrics.connections:set(ngx.var.connections_waiting or 0, { "waiting" }) + metrics.timers:set(ngx_timer_running_count(), {"running"}) + metrics.timers:set(ngx_timer_pending_count(), {"pending"}) + -- db reachable? local ok, err = kong.db.connector:connect() if ok then diff --git a/spec/03-plugins/26-prometheus/04-status_api_spec.lua b/spec/03-plugins/26-prometheus/04-status_api_spec.lua index 150fdb2d463a..237a892a5c95 100644 --- a/spec/03-plugins/26-prometheus/04-status_api_spec.lua +++ b/spec/03-plugins/26-prometheus/04-status_api_spec.lua @@ -286,6 +286,16 @@ describe("Plugin: prometheus (access via status API)", function() assert.matches('kong_datastore_reachable 1', body, nil, true) end) + it("exposes nginx timer metrics", function() + local res = assert(status_client:send { + method = "GET", + path = "/metrics", + }) + local body = assert.res_status(200, res) + assert.matches('kong_nginx_timers{state="running"} %d+', body) + assert.matches('kong_nginx_timers{state="pending"} %d+', body) + end) + it("exposes upstream's target health metrics - healthchecks-off", function() local body helpers.wait_until(function() From 491181e3fde7614150cf417cf9c8d05cfc66d008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garc=C3=ADa=20Cota?= Date: Thu, 24 Feb 2022 13:04:39 +0100 Subject: [PATCH 23/74] chore(plugins) bump some plugin versions due to changes (#8457) --- kong/plugins/acme/handler.lua | 2 +- kong/plugins/cors/handler.lua | 2 +- kong/plugins/datadog/handler.lua | 2 +- kong/plugins/oauth2/handler.lua | 2 +- kong/plugins/prometheus/handler.lua | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kong/plugins/acme/handler.lua b/kong/plugins/acme/handler.lua index 93c66bc358f5..105046523378 100644 --- a/kong/plugins/acme/handler.lua +++ b/kong/plugins/acme/handler.lua @@ -13,7 +13,7 @@ local ACMEHandler = {} -- otherwise acme-challenges endpoints may be blocked by auth plugins -- causing validation failures ACMEHandler.PRIORITY = 1007 -ACMEHandler.VERSION = "0.3.0" +ACMEHandler.VERSION = "0.4.0" local function build_domain_matcher(domains) local domains_plain = {} diff --git a/kong/plugins/cors/handler.lua b/kong/plugins/cors/handler.lua index 8a04a319ae44..8bdc9b8f87dc 100644 --- a/kong/plugins/cors/handler.lua +++ b/kong/plugins/cors/handler.lua @@ -17,7 +17,7 @@ local CorsHandler = {} CorsHandler.PRIORITY = 2000 -CorsHandler.VERSION = "2.0.0" +CorsHandler.VERSION = "2.1.1" -- per-plugin cache of normalized origins for runtime comparison diff --git a/kong/plugins/datadog/handler.lua b/kong/plugins/datadog/handler.lua index 392702487ef0..dad6d2c7d047 100644 --- a/kong/plugins/datadog/handler.lua +++ b/kong/plugins/datadog/handler.lua @@ -95,7 +95,7 @@ end local DatadogHandler = { PRIORITY = 10, - VERSION = "3.1.0", + VERSION = "3.1.1", } diff --git a/kong/plugins/oauth2/handler.lua b/kong/plugins/oauth2/handler.lua index d3ebe9a36584..fbef4efbe1ed 100644 --- a/kong/plugins/oauth2/handler.lua +++ b/kong/plugins/oauth2/handler.lua @@ -3,7 +3,7 @@ local access = require "kong.plugins.oauth2.access" local OAuthHandler = { PRIORITY = 1004, - VERSION = "2.1.1", + VERSION = "2.1.2", } diff --git a/kong/plugins/prometheus/handler.lua b/kong/plugins/prometheus/handler.lua index 3e622f7576d3..386ee757a956 100644 --- a/kong/plugins/prometheus/handler.lua +++ b/kong/plugins/prometheus/handler.lua @@ -7,7 +7,7 @@ prometheus.init() local PrometheusHandler = { PRIORITY = 13, - VERSION = "1.5.0", + VERSION = "1.6.0", } function PrometheusHandler.init_worker() From 40f1c1d9cb2811cd524dee533703c3f6abb24712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garc=C3=ADa=20Cota?= Date: Thu, 24 Feb 2022 13:53:41 +0100 Subject: [PATCH 24/74] docs(changelog) include commits for 2.8.0 release (#8453) Co-authored-by: Guilherme Salazar --- CHANGELOG.md | 56 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 956c1ee3f1f0..ac39cb830fc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,8 +76,10 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). [#8191](https://github.com/Kong/kong/pull/8191) - Bumped resty.session from 3.8 to 3.10 [#8294](https://github.com/Kong/kong/pull/8294) -- Bump lua-resty-openssl to 0.8.5 +- Bumped lua-resty-openssl to 0.8.5 [#8368](https://github.com/Kong/kong/pull/8368) +- Bumped pgmoon from 1.13.0 to 1.14.0 + [#8429](https://github.com/Kong/kong/pull/8429) ### Additions @@ -89,16 +91,26 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). - Routes now support matching headers with regular expressions Thanks, [@vanhtuan0409](https://github.com/vanhtuan0409)! [#6079](https://github.com/Kong/kong/pull/6079) -- Targets keep their health status when upstreams are updated. - [#8394](https://github.com/Kong/kong/pull/8394) + +#### Beta + +- Secrets Management and Vault support as been introduced as a Beta feature. + This means it is intended for testing in staging environments. It not intended + for use in Production environments. + You can read more about Secrets Management in + [our docs page](https://docs.konghq.com/gateway/latest/plan-and-deploy/security/secrets-management/backends-overview). + [#8403](https://github.com/Kong/kong/pull/8403) #### Performance - Improved the calculation of declarative configuration hash for big configurations The new method is faster and uses less memory [#8204](https://github.com/Kong/kong/pull/8204) -- Several improvements in the Router decreased routing time and rebuild time. This should be - particularly noticeable when rebuilding on db-less environments +- Multiple improvements in the Router. Amongst others: + - The router builds twice as faster + - Failures are cached and discarded faster (negative caching) + - Routes with header matching are cached + These changes should be particularly noticeable when rebuilding on db-less environments [#8087](https://github.com/Kong/kong/pull/8087) [#8010](https://github.com/Kong/kong/pull/8010) @@ -106,11 +118,14 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). - **Response-ratelimiting**: Redis ACL support, and genenarized Redis connection support for usernames. - Thanks, [@27ascii](https://github.com/27ascii) for the origina contribution! + Thanks, [@27ascii](https://github.com/27ascii) for the original contribution! [#8213](https://github.com/Kong/kong/pull/8213) - **ACME**: Add rsa_key_size config option Thanks, [lodrantl](https://github.com/lodrantl)! [#8114](https://github.com/Kong/kong/pull/8114) +- **Prometheus**: Added gauges to track `ngx.timer.running_count()` and + `ngx.timer.pending_count()` + [#8387](https://github.com/Kong/kong/pull/8387) #### Clustering @@ -145,6 +160,14 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). Thanks, [@mpenick](https://github.com/mpenick)! [#8226](https://github.com/Kong/kong/pull/8226) +#### Balancer + +- Targets keep their health status when upstreams are updated. + [#8394](https://github.com/Kong/kong/pull/8394) +- One debug message which was erroneously using the `error` log level + has been downgraded to the appropiate `debug` log level. + [#8410](https://github.com/Kong/kong/pull/8410) + #### Clustering - Replaced cryptic error message with more useful one when @@ -160,6 +183,10 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). - Phase names are correctly selected when performing phase checks [#8208](https://github.com/Kong/kong/pull/8208) +- Fixed a bug in the go-PDK where if `kong.request.getrawbody` was + big enough to be buffered into a temporary file, it would return an + an empty string. + [#8390](https://github.com/Kong/kong/pull/8390) #### Plugins @@ -169,13 +196,24 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). - **External Plugins**: Unwrap `ConsumerSpec` and `AuthenticateArgs`. Thanks, [@raptium](https://github.com/raptium)! [#8280](https://github.com/Kong/kong/pull/8280) -- **AWS-Lambda**: Fixed incorrect behavior when configured to use an http proxy - and deprecated the `proxy_scheme` config attribute for removal in 3.0 - [#8406](https://github.com/Kong/kong/pull/8406) +- **External Plugins**: Fixed a problem in the stream subsystem would attempt to load + HTTP headers. + [#8414](https://github.com/Kong/kong/pull/8414) - **CORS**: The CORS plugin does not send the `Vary: Origin` header any more when the header `Access-Control-Allow-Origin` is set to `*`. Thanks, [@jkla-dr](https://github.com/jkla-dr)! [#8401](https://github.com/Kong/kong/pull/8401) +- **AWS-Lambda**: Fixed incorrect behavior when configured to use an http proxy + and deprecated the `proxy_scheme` config attribute for removal in 3.0 + [#8406](https://github.com/Kong/kong/pull/8406) +- **oauth2**: The plugin clears the `X-Authenticated-UserId` and + `X-Authenticated-Scope` headers when it configured in logical OR and + is used in conjunction with another authentication plugin. + [#8422](https://github.com/Kong/kong/pull/8422) +- **Datadog**: The plugin schema now lists the default values + for configuration options in a single place instead of in two + separate places. + [#8315](https://github.com/Kong/kong/pull/8315) ## [2.7.1] From d6af4f91c7b1484f1057aa9d1c02cd68217c12c5 Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Thu, 24 Feb 2022 21:03:02 +0200 Subject: [PATCH 25/74] hotfix(schema) fix dereferencing array and set values ### Summary See the code, it is obvious bug. --- kong/db/schema/init.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kong/db/schema/init.lua b/kong/db/schema/init.lua index 7b642ab21030..625bb0c63a85 100644 --- a/kong/db/schema/init.lua +++ b/kong/db/schema/init.lua @@ -1750,14 +1750,14 @@ function Schema:process_auto_fields(data, context, nulls, opts) if count > 0 then for i = 1, count do if is_reference(value[i]) then - local deref, err = dereference(value) + local deref, err = dereference(value[i]) if deref then - value = deref + value[i] = deref else if err then - kong.log.warn("unable to resolve reference ", value, " (", err, ")") + kong.log.warn("unable to resolve reference ", value[i], " (", err, ")") else - kong.log.warn("unable to resolve reference ", value) + kong.log.warn("unable to resolve reference ", value[i]) end value[i] = nil From 64cf416a23a0dd418f344631f95a642d020073d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Mon, 28 Feb 2022 15:57:30 +0100 Subject: [PATCH 26/74] Revert "chore(deps) bump pgmoon from 1.13.0 to 1.14.0 (#8429)" This reverts commit cd9dbb1404d66dbcd151967cd5bcdf40a4c4c861. --- kong-2.7.0-0.rockspec | 2 +- spec/02-integration/03-db/01-db_spec.lua | 172 ++++++++--------------- 2 files changed, 59 insertions(+), 115 deletions(-) diff --git a/kong-2.7.0-0.rockspec b/kong-2.7.0-0.rockspec index 0f307d517b83..92f96ca74266 100644 --- a/kong-2.7.0-0.rockspec +++ b/kong-2.7.0-0.rockspec @@ -23,7 +23,7 @@ dependencies = { "version == 1.0.1", "kong-lapis == 1.8.3.1", "lua-cassandra == 1.5.1", - "pgmoon == 1.14.0", + "pgmoon == 1.13.0", "luatz == 0.4", "lua_system_constants == 0.1.4", "lyaml == 6.2.7", diff --git a/spec/02-integration/03-db/01-db_spec.lua b/spec/02-integration/03-db/01-db_spec.lua index 10af4723125d..10d58fcd3840 100644 --- a/spec/02-integration/03-db/01-db_spec.lua +++ b/spec/02-integration/03-db/01-db_spec.lua @@ -285,13 +285,11 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_false(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_false(db.connector:get_stored_connection().ssl) db:close() end) @@ -310,14 +308,14 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_false(db.connector:get_stored_connection().ssl) + assert.equal("luasocket", + db.connector:get_stored_connection().sock_type) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_false(db.connector:get_stored_connection().ssl) + db:close() end) @@ -341,13 +339,12 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - assert.is_true(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_true(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_true(db.connector:get_stored_connection().ssl) + db:close() end) @@ -370,14 +367,14 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_true(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_true(db.connector:get_stored_connection().ssl) + assert.equal("luasocket", + db.connector:get_stored_connection().sock_type) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_true(db.connector:get_stored_connection().ssl) + db:close() end) @@ -401,12 +398,7 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(db.connector:get_stored_connection()) -- empty defaults to "write" assert.equal("nginx", db.connector:get_stored_connection("read").sock_type) - - if strategy == "postgres" then - assert.is_false(db.connector:get_stored_connection("read").config.ssl) - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("read").ssl) - end + assert.is_false(db.connector:get_stored_connection("read").ssl) db:close() end) @@ -431,20 +423,10 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(db.connector:get_stored_connection("read")) assert.equal("luasocket", db.connector:get_stored_connection("write").sock_type) - - if strategy == "portgres" then - assert.is_false(db.connector:get_stored_connection("write").config.ssl) - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("write").ssl) - end + assert.is_false(db.connector:get_stored_connection("write").ssl) assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - - if strategy == "portgres" then - assert.is_false(db.connector:get_stored_connection("write").config.ssl) - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("write").ssl) - end + assert.is_false(db.connector:get_stored_connection().ssl) db:close() end) @@ -469,16 +451,13 @@ for _, strategy in helpers.each_strategy() do assert.is_nil(err) assert.is_table(conn) - if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_false(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_false(db.connector:get_stored_connection().ssl) assert.is_true(db:setkeepalive()) db:close() @@ -498,15 +477,13 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_false(db.connector:get_stored_connection().ssl) + assert.equal("luasocket", + db.connector:get_stored_connection().sock_type) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end - + assert.is_false(db.connector:get_stored_connection().ssl) assert.is_true(db:setkeepalive()) db:close() @@ -532,13 +509,11 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - assert.is_true(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_true(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:setkeepalive()) db:close() @@ -563,15 +538,13 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_true(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_true(db.connector:get_stored_connection().ssl) + assert.equal("luasocket", + db.connector:get_stored_connection().sock_type) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end - + assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:setkeepalive()) db:close() @@ -626,14 +599,8 @@ for _, strategy in helpers.each_strategy() do assert.equal("nginx", db.connector:get_stored_connection("read").sock_type) assert.equal("nginx", db.connector:get_stored_connection("write").sock_type) - if strategy == "postgres" then - assert.is_false(db.connector:get_stored_connection("read").config.ssl) - assert.is_false(db.connector:get_stored_connection("write").config.ssl) - - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("read").ssl) - assert.is_false(db.connector:get_stored_connection("write").ssl) - end + assert.is_false(db.connector:get_stored_connection("read").ssl) + assert.is_false(db.connector:get_stored_connection("write").ssl) assert.is_true(db:setkeepalive()) @@ -667,11 +634,7 @@ for _, strategy in helpers.each_strategy() do assert.equal("luasocket", db.connector:get_stored_connection("write").sock_type) assert.is_nil(db.connector:get_stored_connection("read")) - if strategy == "postgres" then - assert.is_false(db.connector:get_stored_connection("write").config.ssl) - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("write").ssl) - end + assert.is_false(db.connector:get_stored_connection("write").ssl) assert.is_true(db:setkeepalive()) @@ -703,14 +666,11 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_false(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end - + assert.is_false(db.connector:get_stored_connection().ssl) assert.is_true(db:close()) end) @@ -729,14 +689,11 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_false(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_false(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end - + assert.is_false(db.connector:get_stored_connection().ssl) assert.is_true(db:close()) end) @@ -760,13 +717,11 @@ for _, strategy in helpers.each_strategy() do if strategy == "postgres" then assert.equal("nginx", db.connector:get_stored_connection().sock_type) - assert.is_true(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_true(db.connector:get_stored_connection().ssl) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:close()) end) @@ -789,14 +744,13 @@ for _, strategy in helpers.each_strategy() do assert.is_table(conn) if strategy == "postgres" then - assert.equal("luasocket", db.connector:get_stored_connection().sock_type) - assert.is_true(db.connector:get_stored_connection().config.ssl) - - elseif strategy == "cassandra" then - --TODO: cassandra forces luasocket on timer - assert.is_true(db.connector:get_stored_connection().ssl) + assert.equal("luasocket", + db.connector:get_stored_connection().sock_type) + --elseif strategy == "cassandra" then + --TODO: cassandra forces luasocket on timer end + assert.is_true(db.connector:get_stored_connection().ssl) assert.is_true(db:close()) end) @@ -849,14 +803,8 @@ for _, strategy in helpers.each_strategy() do assert.equal("nginx", db.connector:get_stored_connection("read").sock_type) assert.equal("nginx", db.connector:get_stored_connection("write").sock_type) - if strategy == "postgres" then - assert.is_false(db.connector:get_stored_connection("read").config.ssl) - assert.is_false(db.connector:get_stored_connection("write").config.ssl) - - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("read").ssl) - assert.is_false(db.connector:get_stored_connection("write").ssl) - end + assert.is_false(db.connector:get_stored_connection("read").ssl) + assert.is_false(db.connector:get_stored_connection("write").ssl) assert.is_true(db:close()) @@ -889,11 +837,7 @@ for _, strategy in helpers.each_strategy() do assert.equal("luasocket", db.connector:get_stored_connection("write").sock_type) assert.is_nil(db.connector:get_stored_connection("read")) - if strategy == "postgres" then - assert.is_false(db.connector:get_stored_connection("write").config.ssl) - elseif strategy == "cassandra" then - assert.is_false(db.connector:get_stored_connection("write").ssl) - end + assert.is_false(db.connector:get_stored_connection("write").ssl) assert.is_true(db:close()) From 56de67a93b546151a7ec822d3c29d27f4dcaf3e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Mon, 28 Feb 2022 15:59:03 +0100 Subject: [PATCH 27/74] docs(changelog) remove pgmoon bump from 2.8 --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac39cb830fc6..9abebedc8f9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,8 +78,6 @@ the [docs](https://docs.konghq.com/gateway/2.7.x/reference/external-plugins/). [#8294](https://github.com/Kong/kong/pull/8294) - Bumped lua-resty-openssl to 0.8.5 [#8368](https://github.com/Kong/kong/pull/8368) -- Bumped pgmoon from 1.13.0 to 1.14.0 - [#8429](https://github.com/Kong/kong/pull/8429) ### Additions From 4e83553d8f8dd4369b5165c7fe4d6d687b74834e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Tue, 1 Mar 2022 11:58:36 +0100 Subject: [PATCH 28/74] docs(COPYRIGHT) update copyright for 2.8.0 --- COPYRIGHT | 932 +----------------------------------------------------- 1 file changed, 6 insertions(+), 926 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 5a1ecbdac481..93d0ec803d85 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -255,636 +255,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -%%%%%%%%% - -kong-plugin-azure-functions - -https://github.com/kong/kong-plugin-azure-functions -https://github.com/kong/kong-plugin-azure-functions/blob/master/LICENSE - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -%%%%%%%%% - -kong-plugin-request-transformer - -https://github.com/Kong/kong-plugin-request-transformer -https://github.com/Kong/kong-plugin-request-transformer/blob/master/LICENSE - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2019 Kong Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -%%%%%%%%% - -kong-plugin-zipkin - -https://github.com/kong/kong-plugin-zipkin -https://github.com/kong/kong-plugin-zipkin/blob/master/LICENSE - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018-2019 Kong Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - %%%%%%%%% loadkit @@ -898,39 +268,12 @@ MIT, Copyright (C) 2014 by Leaf Corcoran %%%%%%%%% -LPeg - -http://www.inf.puc-rio.br/~roberto/lpeg.html -http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html#license - -Copyright © 2007-2019 Lua.org, PUC-Rio. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -%%%%%%%%% - -lrandom +LPeg -http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/ -http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/install.html#license +http://www.inf.puc-rio.br/~roberto/lpeg.html +http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html#license -Copyright (C) 2018 Luiz Henrique de Figueiredo +Copyright © 2007-2019 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -981,35 +324,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -%%%%%%%%% - -lua-cjson - -http://www.kyne.com.au/~mark/software/lua-cjson.php -https://github.com/openresty/lua-cjson/blob/master/LICENSE - -Copyright (c) 2010-2012 Mark Pulford - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - %%%%%%%%% lua-ffi-zlib @@ -1119,30 +433,6 @@ Redistribution and use in source and binary forms, with or without modification, THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -%%%%%%%%% - -lua-resty-cookie - -https://github.com/cloudflare/lua-resty-cookie -https://github.com/cloudflare/lua-resty-cookie#copyright-and-license - -This module is licensed under the BSD license. - -Copyright (C) 2013, by Jiale Zhi , CloudFlare Inc. - -Copyright (C) 2013, by Yichun Zhang , CloudFlare Inc. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - %%%%%%%%% lua-resty-counter @@ -1157,216 +447,6 @@ Copyright (C) 2019, Kong Inc. All rights reserved. -%%%%%%%%% - -lua-resty-dns-client - -https://github.com/Kong/lua-resty-dns-client -https://github.com/Kong/lua-resty-dns-client/blob/master/LICENSE - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - %%%%%%%%% lua-resty-healthcheck @@ -1943,7 +1023,7 @@ lua-resty-session https://github.com/bungle/lua-resty-session https://github.com/bungle/lua-resty-session/blob/master/LICENSE -Copyright (c) 2014 – 2021, Aapo Talvensaari +Copyright (c) 2014 – 2022, Aapo Talvensaari All rights reserved. Redistribution and use in source and binary forms, with or without @@ -2730,7 +1810,7 @@ the terms of the MIT license (the same license as Lua itself), unless noted otherwise in the body of that file. ==================================================================== -Copyright (C) 2013-2020 Gary V. Vaughan +Copyright (C) 2013-2022 Gary V. Vaughan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation From 6cc376df343d08aabb451a79ed19ef93f26082fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Tue, 1 Mar 2022 11:59:06 +0100 Subject: [PATCH 29/74] docs(kong-admin-api.yml) update Admin API definition for 2.8.0 --- kong-admin-api.yml | 790 +++++++++++++++++++++++---------------------- 1 file changed, 409 insertions(+), 381 deletions(-) diff --git a/kong-admin-api.yml b/kong-admin-api.yml index 177fb8a1552b..fa6206867e31 100644 --- a/kong-admin-api.yml +++ b/kong-admin-api.yml @@ -1,219 +1,5 @@ -servers: -- description: 8001 is the default port on which the Admin API listens. - url: http://localhost:8001 -- description: 8444 is the default port for HTTPS traffic to the Admin API. - url: https://localhost:8444 -paths: - /cache: - delete: - description: This method is not available when using DB-less mode. - /upstreams/{upstreams}/targets: - get: [] - post: - description: This method is not available when using DB-less mode. - /upstreams/{upstreams}/targets/{targets}: - delete: - description: This method is not available when using DB-less mode. - summary: Delete Target - patch: - description: This method is not available when using DB-less mode. - summary: Update Target - put: - description: This method is not available when using DB-less mode. - get: [] - /targets/{targets}/upstream: [] - /certificates/{certificates}: - patch: - description: This method is not available when using DB-less mode. - put: - description: This method is not available when using DB-less mode. - get: [] - /certificates/{certificates}/snis: [] - /schemas/plugins/validate: - post: - description: This method is not available when using DB-less mode. - summary: Validate a plugin configuration against the schema - /tags/{tags}: - get: - summary: ' List entity IDs by tag ' - /upstreams/{upstreams}/targets/all: - get: - summary: List all Targets - /services/{services}/plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. - /upstreams/{upstreams}/health: - get: - summary: Show Upstream health for node - /upstreams/{upstreams}/targets/{targets}/healthy: - post: - description: This method is not available when using DB-less mode. - summary: Set target as healthy - /status: - get: - summary: Retrieve node status - /upstreams/{upstreams}/targets/{targets}/{address}/healthy: - post: - description: This method is not available when using DB-less mode. - summary: Set target address as healthy - /targets: [] - /consumers: - get: [] - /schemas/{db_entity_name}/validate: - post: - description: This method is not available when using DB-less mode. - summary: Validate a configuration against a schema - /endpoints: - get: - summary: List available endpoints - /snis/{snis}/certificate: [] - /certificates/{certificates}/snis/{snis}: [] - /upstreams/{upstreams}/targets/{targets}/unhealthy: - post: - description: This method is not available when using DB-less mode. - summary: Set target as unhealthy - /schemas/{name}: - get: - summary: Retrieve Entity Schema - /clustering/data-planes: [] - /upstreams/{upstreams}/targets/{targets}/{address}/unhealthy: - post: - description: This method is not available when using DB-less mode. - summary: Set target address as unhealthy - /plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. - /clustering/status: [] - /routes/{routes}/plugins: - post: - description: This method is not available when using DB-less mode. - /targets/{targets}: [] - /plugins/enabled: - get: - summary: Retrieve Enabled Plugins - /services/{services}/plugins: - post: - description: This method is not available when using DB-less mode. - /routes/{routes}/plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. - /cache/{key}: - delete: - description: This method is not available when using DB-less mode. - get: [] - /consumers/{consumers}/plugins: - post: - description: This method is not available when using DB-less mode. - /consumers/{consumers}/plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. - /plugins: - post: - description: This method is not available when using DB-less mode. - /schemas/plugins/{name}: - get: - summary: Retrieve Plugin Schema - /config: - get: - description: This method is only available when using DB-less mode. - post: - description: This method is only available when using DB-less mode. - /plugins/schema/{name}: - get: [] - /: - get: - summary: Retrieve node information components: schemas: - clustering_data_planes: - required: - - id - - ip - - hostname - - sync_status - type: object - properties: - last_seen: - format: int32 - type: integer - config_hash: - type: string - hostname: - type: string - ip: - type: string - id: - type: string - version: - type: string - sync_status: - type: string - default: unknown - parameters: - required: - - key - - value - type: object - properties: - key: - type: string - created_at: - format: int32 - type: integer - value: - type: string - services: - required: - - protocol - - host - - port - type: object - properties: - tls_verify: - type: boolean - tls_verify_depth: - default: ~ - type: integer - nullable: true - tags: - type: array - created_at: - format: int32 - type: integer - updated_at: - format: int32 - type: integer - protocol: - type: string - default: http - path: - type: string - host: - type: string - port: - type: integer - default: 80 - retries: - type: integer - default: 5 - connect_timeout: - type: integer - default: 60000 - ca_certificates: - type: array - write_timeout: - type: integer - default: 60000 - name: - type: string - read_timeout: - type: integer - default: 60000 - id: - format: uuid - type: string - client_certificate: - $ref: '#/components/schemas/certificates' tags: required: - tag @@ -221,28 +7,28 @@ components: - entity_id type: object properties: - entity_name: + entity_id: type: string tag: type: string - entity_id: + entity_name: type: string consumers: required: [] type: object properties: - created_at: - format: int32 - type: integer - id: - format: uuid - type: string - username: - type: string tags: type: array + username: + type: string + id: + type: string + format: uuid custom_id: type: string + created_at: + type: integer + format: int32 plugins: required: - name @@ -250,169 +36,156 @@ components: - enabled type: object properties: - protocols: - enum: - - http - - https - - tcp - - tls - - udp - - grpc - - grpcs - type: array - default: - - grpc - - grpcs - - http - - https tags: type: array enabled: type: boolean default: true - config: - type: array - created_at: - format: int32 - type: integer - id: - format: uuid - type: string - route: - $ref: '#/components/schemas/routes' - default: ~ - nullable: true - name: - type: string service: $ref: '#/components/schemas/services' default: ~ nullable: true + route: + $ref: '#/components/schemas/routes' + default: ~ + nullable: true + created_at: + type: integer + format: int32 consumer: $ref: '#/components/schemas/consumers' default: ~ nullable: true + name: + type: string + id: + type: string + format: uuid + protocols: + default: + - grpc + - grpcs + - http + - https + enum: + - http + - https + - tcp + - tls + - udp + - grpc + - grpcs + type: array + config: + type: array certificates: required: - cert - key type: object properties: + tags: + type: array key: type: string cert_alt: type: string - created_at: - format: int32 - type: integer key_alt: type: string - id: - format: uuid - type: string - tags: - type: array cert: type: string + created_at: + type: integer + format: int32 + id: + type: string + format: uuid ca_certificates: required: - cert type: object properties: - created_at: - format: int32 - type: integer - id: - format: uuid - type: string tags: type: array - cert_digest: + id: type: string + format: uuid cert: type: string + created_at: + type: integer + format: int32 + cert_digest: + type: string snis: required: - name - certificate type: object properties: - created_at: - format: int32 - type: integer - id: - format: uuid - type: string - certificate: - $ref: '#/components/schemas/certificates' tags: type: array name: type: string + id: + type: string + format: uuid + created_at: + type: integer + format: int32 + certificate: + $ref: '#/components/schemas/certificates' upstreams: required: - name type: object properties: - hash_fallback: + tags: + type: array + created_at: + type: integer + format: int32 + slots: + type: integer + default: 10000 + host_header: type: string - default: none + algorithm: + type: string + default: round-robin hash_on_header: type: string - name: + hash_on: type: string + default: none hash_fallback_header: type: string - host_header: + name: type: string - hash_on_cookie: + id: type: string - tags: - type: array + format: uuid + client_certificate: + $ref: '#/components/schemas/certificates' hash_on_cookie_path: type: string default: / + hash_on_cookie: + type: string healthchecks: type: array default: - active: + passive: unhealthy: - http_statuses: - - 429 - - 404 - - 500 - - 501 - - 502 - - 503 - - 504 - - 505 - timeouts: 0 http_failures: 0 tcp_failures: 0 - interval: 0 - healthy: - http_statuses: - - 200 - - 302 - interval: 0 - successes: 0 - https_verify_certificate: true - http_path: / - concurrency: 10 - timeout: 1 - type: http - passive: - unhealthy: http_statuses: - 429 - 500 - 503 - tcp_failures: 0 timeouts: 0 - http_failures: 0 type: http healthy: - successes: 0 http_statuses: - 200 - 201 @@ -433,44 +206,138 @@ components: - 306 - 307 - 308 - created_at: - format: int32 - type: integer - slots: - type: integer - default: 10000 - id: - format: uuid - type: string - algorithm: - type: string - default: round-robin - hash_on: + successes: 0 + active: + http_path: / + unhealthy: + tcp_failures: 0 + timeouts: 0 + http_failures: 0 + interval: 0 + http_statuses: + - 429 + - 404 + - 500 + - 501 + - 502 + - 503 + - 504 + - 505 + https_verify_certificate: true + concurrency: 10 + timeout: 1 + type: http + healthy: + successes: 0 + interval: 0 + http_statuses: + - 200 + - 302 + hash_fallback: type: string default: none - client_certificate: - $ref: '#/components/schemas/certificates' targets: required: - upstream - target type: object properties: + upstream: + $ref: '#/components/schemas/upstreams' target: type: string - created_at: - format: float - type: number + id: + type: string + format: uuid weight: type: integer default: 100 + created_at: + type: number + format: float + tags: + type: array + vaults_beta: + required: + - prefix + - name + type: object + properties: + tags: + type: array + name: + type: string + id: + type: string + format: uuid + config: + type: array + created_at: + type: integer + format: int32 + prefix: + type: string + description: + type: string + updated_at: + type: integer + format: int32 + clustering_data_planes: + required: + - id + - ip + - hostname + - sync_status + type: object + properties: + version: + type: string + id: + type: string + last_seen: + type: integer + format: int32 + config_hash: + type: string + ip: + type: string + sync_status: + type: string + default: unknown + hostname: + type: string + workspaces: + required: + - name + type: object + properties: + name: + type: string id: + type: string format: uuid + config: + type: array + meta: + type: array + created_at: + type: integer + format: int32 + comment: + type: string + parameters: + required: + - key + - value + type: object + properties: + value: + type: string + created_at: + type: integer + format: int32 + key: type: string - tags: - type: array - upstream: - $ref: '#/components/schemas/upstreams' routes: required: - protocols @@ -481,82 +348,122 @@ components: - response_buffering type: object properties: - methods: + tags: type: array - paths: + response_buffering: + type: boolean + default: true + regex_priority: + type: integer + default: 0 + service: + $ref: '#/components/schemas/services' + https_redirect_status_code: + type: integer + default: 426 + headers: type: array - protocols: + destinations: type: array - default: - - http - - https - sources: + hosts: type: array - tags: + snis: type: array - headers: + strip_path: + type: boolean + default: true + methods: type: array created_at: - format: int32 type: integer - updated_at: format: int32 + updated_at: type: integer + format: int32 + paths: + type: array + name: + type: string id: - format: uuid type: string - strip_path: - type: boolean - default: true - destinations: - type: array + format: uuid path_handling: type: string default: v0 - snis: + protocols: type: array + default: + - http + - https preserve_host: type: boolean default: false - https_redirect_status_code: - type: integer - default: 426 + sources: + type: array request_buffering: type: boolean default: true - name: - type: string - response_buffering: - type: boolean - default: true - regex_priority: - type: integer - default: 0 - service: - $ref: '#/components/schemas/services' - hosts: - type: array - workspaces: + services: required: - - name + - protocol + - host + - port + - enabled type: object properties: - meta: + tags: type: array - created_at: - format: int32 + retries: + type: integer + default: 5 + ca_certificates: + type: array + connect_timeout: + type: integer + default: 60000 + write_timeout: + type: integer + default: 60000 + read_timeout: + type: integer + default: 60000 + client_certificate: + $ref: '#/components/schemas/certificates' + tls_verify: + type: boolean + port: + type: integer + default: 80 + tls_verify_depth: + default: ~ + type: integer + nullable: true + enabled: + type: boolean + default: true + path: + type: string + updated_at: type: integer + format: int32 + protocol: + type: string + default: http id: + type: string format: uuid + host: type: string - config: - type: array name: type: string - comment: - type: string -openapi: 3.1.0 + created_at: + type: integer + format: int32 info: + contact: + url: https://github.com/Kong/kong + name: Kong + version: 2.7.0 title: Kong Admin API summary: Kong RESTful Admin API for administration purposes. description: " {{site.base_gateway}} comes with an **internal** RESTful Admin @@ -569,9 +476,130 @@ info: to avoid undue public\n exposure of this API. See [this document][secure-admin-api] for a discussion\n of methods to secure the Admin API.\n " license: - name: Apache 2.0 url: https://github.com/Kong/kong/blob/master/LICENSE - version: 2.6.0 - contact: - name: Kong - url: https://github.com/Kong/kong + name: Apache 2.0 +paths: + /clustering/status: [] + /upstreams/{upstreams}/targets/{targets}/{address}/unhealthy: + post: + description: This method is not available when using DB-less mode. + summary: Set target address as unhealthy + /: + get: + summary: Retrieve node information + /cache/{key}: + delete: + description: This method is not available when using DB-less mode. + get: [] + /certificates/{certificates}/snis: [] + /upstreams/{upstreams}/targets/{targets}/unhealthy: + post: + description: This method is not available when using DB-less mode. + summary: Set target as unhealthy + /certificates/{certificates}: + put: + description: This method is not available when using DB-less mode. + get: [] + patch: + description: This method is not available when using DB-less mode. + /upstreams/{upstreams}/targets: + post: + description: This method is not available when using DB-less mode. + get: [] + /targets/:targets: [] + /upstreams/{upstreams}/targets/{targets}/healthy: + post: + description: This method is not available when using DB-less mode. + summary: Set target as healthy + /upstreams/{upstreams}/targets/{targets}: + put: + description: This method is not available when using DB-less mode. + get: [] + delete: + description: This method is not available when using DB-less mode. + summary: Delete Target + patch: + description: This method is not available when using DB-less mode. + summary: Update Target + /tags/{tags}: + get: + summary: ' List entity IDs by tag ' + /plugins/enabled: + get: + summary: Retrieve Enabled Plugins + /upstreams/{upstreams}/targets/all: + get: + summary: List all Targets + /targets/{targets}/upstream: [] + /certificates/{certificates}/snis/{snis}: [] + /routes/:routes/plugins: + post: [] + /plugins: + post: + description: This method is not available when using DB-less mode. + /cache: + delete: + description: This method is not available when using DB-less mode. + /targets: [] + /config: + post: + description: This method is only available when using DB-less mode. + get: + description: This method is only available when using DB-less mode. + /consumers/{consumers}/plugins/{plugins}: + patch: + description: This method is not available when using DB-less mode. + /schemas/{name}: + get: + summary: Retrieve Entity Schema + /status: + get: + summary: Retrieve node status + /plugins/schema/{name}: + get: [] + /schemas/plugins/{name}: + get: + summary: Retrieve Plugin Schema + /upstreams/{upstreams}/health: + get: + summary: Show Upstream health for node + /schemas/{db_entity_name}/validate: + post: + description: This method is not available when using DB-less mode. + summary: Validate a configuration against a schema + /plugins/{plugins}: + patch: + description: This method is not available when using DB-less mode. + /snis/{snis}/certificate: [] + /upstreams/{upstreams}/targets/{targets}/{address}/healthy: + post: + description: This method is not available when using DB-less mode. + summary: Set target address as healthy + /routes/{routes}/plugins/{plugins}: + patch: + description: This method is not available when using DB-less mode. + /clustering/data-planes: [] + /schemas/plugins/validate: + post: + description: This method is not available when using DB-less mode. + summary: Validate a plugin configuration against the schema + /services/{services}/plugins: + post: + description: This method is not available when using DB-less mode. + /services/{services}/plugins/{plugins}: + patch: + description: This method is not available when using DB-less mode. + /consumers: + get: [] + /consumers/{consumers}/plugins: + post: + description: This method is not available when using DB-less mode. + /endpoints: + get: + summary: List available endpoints +servers: +- description: 8001 is the default port on which the Admin API listens. + url: http://localhost:8001 +- description: 8444 is the default port for HTTPS traffic to the Admin API. + url: https://localhost:8444 +openapi: 3.1.0 From 064f00deba27075e9954eeef9a9d4768ad7f2ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Tue, 1 Mar 2022 12:06:59 +0100 Subject: [PATCH 30/74] docs(upgrade.md) add upgrade instructions for 2.8.0 --- UPGRADE.md | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index 8d59ef134122..68c64841d24a 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -24,7 +24,196 @@ $ kong migrations up [-c configuration_file] If the command is successful, and no migration ran (no output), then you only have to -[reload](https://docs.konghq.com/gateway-oss/2.7.x/cli/#kong-reload) Kong: +[reload](https://docs.konghq.com/gateway-oss/2.8.x/cli/#kong-reload) Kong: + +```shell +$ kong reload [-c configuration_file] +``` + +**Reminder**: `kong reload` leverages the Nginx `reload` signal that seamlessly +starts new workers, which take over from old workers before those old workers +are terminated. In this way, Kong will serve new requests via the new +configuration, without dropping existing in-flight connections. + +## Upgrade to `2.8.x` + +Kong adheres to [semantic versioning](https://semver.org/), which makes a +distinction between "major", "minor", and "patch" versions. The upgrade path +will be different depending on which previous version from which you are migrating. + +If you are migrating from 2.x.x, upgrading into 2.8.x is a +minor upgrade, but read below for important instructions on database migration, +especially for Cassandra users. + +If you are migrating from 1.x, upgrading into 2.8.x is a major upgrade, +so, in addition, be aware of any [breaking changes](https://github.com/Kong/kong/blob/master/UPGRADE.md#breaking-changes-2.0) +between the 1.x and 2.x series below, further detailed in the +[CHANGELOG.md](https://github.com/Kong/kong/blob/2.0.0/CHANGELOG.md#200) document. + + +### Dependencies + +If you are using the provided binary packages, all necessary dependencies +for the gateway are bundled and you can skip this section. + +If you are building your dependencies by hand, there are changes since the +previous release, so you will need to rebuild them with the latest patches. + +The required OpenResty version for kong 2.8.x is +[1.19.9.1](https://openresty.org/en/changelog-1019003.html). This is more recent +than the version in Kong 2.5.0 (which used `1.19.3.2`). In addition to an upgraded +OpenResty, you will need the correct [OpenResty patches](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools/openresty-patches) +for this new version, including the latest release of [lua-kong-nginx-module](https://github.com/Kong/lua-kong-nginx-module). +The [kong-build-tools](https://github.com/Kong/kong-build-tools) +repository contains [openresty-build-tools](https://github.com/Kong/kong-build-tools/tree/master/openresty-build-tools), +which allows you to more easily build OpenResty with the necessary patches and modules. + +There is a new way to deploy Go using Plugin Servers. +For more information, see [Developing Go plugins](https://docs.konghq.com/gateway-oss/2.6.x/external-plugins/#developing-go-plugins). + +### Template changes + +There are **Changes in the Nginx configuration file**, between kong 2.0.x, +2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x, 2.7.x and 2.8.x + +To view the configuration changes between versions, clone the +[Kong repository](https://github.com/kong/kong) and run `git diff` +on the configuration templates, using `-w` for greater readability. + +Here's how to see the differences between previous versions and 2.8.x: + +``` +git clone https://github.com/kong/kong +cd kong +git diff -w 2.0.0 2.8.0 kong/templates/nginx_kong*.lua +``` + +**Note:** Adjust the starting version number +(2.0.x, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x, 2.7.x) to the version number you are currently using. + +To produce a patch file, use the following command: + +``` +git diff 2.0.0 2.8.0 kong/templates/nginx_kong*.lua > kong_config_changes.diff +``` + +**Note:** Adjust the starting version number +(2.0.x, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x, 2.7.x) to the version number you are currently using. + + +### Suggested upgrade path + +**Version prerequisites for migrating to version 2.8.x** + +The lowest version that Kong 2.8.x supports migrating from is 1.0.x. +If you are migrating from a version lower than 0.14.1, you need to +migrate to 0.14.1 first. Then, once you are migrating from 0.14.1, +please migrate to 1.5.x first. + +The steps for upgrading from 0.14.1 to 1.5.x are the same as upgrading +from 0.14.1 to Kong 1.0. Please follow the steps described in the +"Migration Steps from 0.14" in the + +[Suggested Upgrade Path for Kong 1.0](https://github.com/Kong/kong/blob/master/UPGRADE.md#kong-1-0-upgrade-path) +with the addition of the `kong migrations migrate-apis` command, +which you can use to migrate legacy `apis` configurations. + +Once you migrated to 1.5.x, you can follow the instructions in the section +below to migrate to 2.8.x. + +### Upgrade from `1.0.x` - `2.2.x` to `2.8.x` + +**Postgres** + +Kong 2.8.x supports a no-downtime migration model. This means that while the +migration is ongoing, you will have two Kong clusters running, sharing the +same database. (This is sometimes called the Blue/Green migration model.) + +The migrations are designed so that the new version of Kong is able to use +the database as it is migrated while the old Kong cluster keeps working until +it is time to decommission it. For this reason, the migration is split into +two steps, performed via commands `kong migrations up` (which does +only non-destructive operations) and `kong migrations finish` (which puts the +database in the final expected state for Kong 2.8.x). + +1. Download 2.8.x, and configure it to point to the same datastore + as your old (1.0 to 2.0) cluster. Run `kong migrations up`. +2. After that finishes running, both the old (2.x.x) and new (2.8.x) + clusters can now run simultaneously. Start provisioning 2.8.x nodes, + but do not use their Admin API yet. If you need to perform Admin API + requests, these should be made to the old cluster's nodes. The reason + is to prevent the new cluster from generating data that is not understood + by the old cluster. +3. Gradually divert traffic away from your old nodes, and into + your 2.8.x cluster. Monitor your traffic to make sure everything + is going smoothly. +4. When your traffic is fully migrated to the 2.8.x cluster, + decommission your old nodes. +5. From your 2.8.x cluster, run: `kong migrations finish`. + From this point on, it will not be possible to start + nodes in the old cluster pointing to the same datastore anymore. Only run + this command when you are confident that your migration + was successful. From now on, you can safely make Admin API + requests to your 2.8.x nodes. + +**Cassandra** + +Deprecation notice: +Cassandra as a backend database for Kong Gateway is deprecated. This means the feature will eventually be removed. Our target for Cassandra removal is the Kong Gateway 4.0 release, and some new features might not be supported with Cassandra in the Kong Gateway 3.0 release. + +Due to internal changes, the table schemas used by Kong 2.8.x on Cassandra +are incompatible with those used by Kong 2.1.x (or lower). Migrating using the usual commands +`kong migrations up` and `kong migrations finish` will require a small +window of downtime, since the old and new versions cannot use the +database at the same time. Alternatively, to keep your previous version fully +operational while the new one initializes, you will need to transfer the +data to a new keyspace via a database dump, as described below: + +1. Download 2.8.x, and configure it to point to a new keyspace. + Run `kong migrations bootstrap`. +2. Once that finishes running, both the old (pre-2.1) and new (2.8.x) + clusters can now run simultaneously, but the new cluster does not + have any data yet. +3. On the old cluster, run `kong config db_export`. This will create + a file `kong.yml` with a database dump. +4. Transfer the file to the new cluster and run + `kong config db_import kong.yml`. This will load the data into the new cluster. +5. Gradually divert traffic away from your old nodes, and into + your 2.8.x cluster. Monitor your traffic to make sure everything + is going smoothly. +6. When your traffic is fully migrated to the 2.8.x cluster, + decommission your old nodes. + +### Installing 2.8.x on a fresh datastore + +The following commands should be used to prepare a new 2.8.x cluster from a +fresh datastore. By default the `kong` CLI tool will load the configuration +from `/etc/kong/kong.conf`, but you can optionally use the flag `-c` to +indicate the path to your configuration file: + +``` +$ kong migrations bootstrap [-c /path/to/your/kong.conf] +$ kong start [-c /path/to/your/kong.conf] +``` +Unless indicated otherwise in one of the upgrade paths of this document, it is +possible to upgrade Kong **without downtime**. + +Assuming that Kong is already running on your system, acquire the latest +version from any of the available [installation methods](https://getkong.org/install/) +and proceed to install it, overriding your previous installation. + +**If you are planning to make modifications to your configuration, this is a +good time to do so**. + +Then, run migration to upgrade your database schema: + +```shell +$ kong migrations up [-c configuration_file] +``` + +If the command is successful, and no migration ran +(no output), then you only have to +[reload](https://docs.konghq.com/gateway-oss/2.8.x/cli/#kong-reload) Kong: ```shell $ kong reload [-c configuration_file] From 40db59701d6724703dbf6318aa28219e42902e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Tue, 1 Mar 2022 12:08:01 +0100 Subject: [PATCH 31/74] release: 2.8.0 --- kong-2.7.0-0.rockspec => kong-2.8.0-0.rockspec | 4 ++-- kong/meta.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename kong-2.7.0-0.rockspec => kong-2.8.0-0.rockspec (99%) diff --git a/kong-2.7.0-0.rockspec b/kong-2.8.0-0.rockspec similarity index 99% rename from kong-2.7.0-0.rockspec rename to kong-2.8.0-0.rockspec index 92f96ca74266..53cae6ac4fdf 100644 --- a/kong-2.7.0-0.rockspec +++ b/kong-2.8.0-0.rockspec @@ -1,10 +1,10 @@ package = "kong" -version = "2.7.0-0" +version = "2.8.0-0" rockspec_format = "3.0" supported_platforms = {"linux", "macosx"} source = { url = "git://github.com/Kong/kong", - tag = "2.7.0" + tag = "2.8.0" } description = { summary = "Kong is a scalable and customizable API Management Layer built on top of Nginx.", diff --git a/kong/meta.lua b/kong/meta.lua index d31f28eb9043..36a96b45b036 100644 --- a/kong/meta.lua +++ b/kong/meta.lua @@ -1,6 +1,6 @@ local version = setmetatable({ major = 2, - minor = 7, + minor = 8, patch = 0, --suffix = "rc.1" }, { From 7ea02bc284c95d3c5b10bf80b70166525b7d1a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Tue, 1 Mar 2022 16:09:27 +0100 Subject: [PATCH 32/74] chore(scripts) include jenkins steps Our jenkins server expects and uses some steps in scripts/make-patch-release that were removed in #8078. This commit adds them back as a temporary way of releasing 2.8.0 --- scripts/make-patch-release | 98 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/scripts/make-patch-release b/scripts/make-patch-release index 88846910d1fe..cd82e12c1157 100755 --- a/scripts/make-patch-release +++ b/scripts/make-patch-release @@ -34,6 +34,15 @@ function usage() { step "merge_vagrant" "humans approve and merge machine PR to kong-vagrant" step "merge_pongo" "humans approve and merge machine PR to kong-pongo" step "announce" "Get announcement messages for Kong Nation and Slack #general" + + #---------------------------------------------------------------------------------------- + # The following steps are run by Jenkins, they should not be run by a human + # However we need to keep them here because Jenkins expects them to be here + step "update_docker" "(ran by Jenkins now) update and submit a PR to Kong's docker-kong repo" + step "homebrew" "(ran by Jenkins now) bump version and submit a PR to homebrew-kong" + step "vagrant" "(ran by Jenkins now) bump version and submit a PR to kong-vagrant" + step "pongo" "(ran by Jenkins now) bump version and submit a PR to kong-pongo" + exit 0 } @@ -181,6 +190,95 @@ case "$step" in merge_vagrant) merge_vagrant ;; upload_luarock) upload_luarock "$rockspec" "$3" ;; announce) announce "$major" "$minor" "$patch" ;; + + # JENKINS-ONLY STEPS: ----------------------------------------------------- + + update_docker) + update_docker "$version" + + SUCCESS "Make sure you get the PR above approved and merged" \ + "before continuing to the step 'merge_docker'." + ;; + + homebrew) + if [ -d ../homebrew-kong ] + then + cd ../homebrew-kong + else + cd .. + git clone git@github.com:Kong/homebrew-kong.git + cd homebrew-kong + fi + + git checkout master + git pull + git checkout -B "$branch" + bump_homebrew + + git diff + + CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:Kong/homebrew-kong" \ + "or Ctrl-C to cancel." + + set -e + git add Formula/kong.rb + git commit -m "chore(kong) bump kong to $version" + + git push --set-upstream origin "$branch" + hub pull-request -b master -h "$branch" -m "Release: $version" + + SUCCESS "Make sure you get the PR above approved and merged." + ;; + + pongo) + if [ -d ../kong-pongo ] + then + cd ../kong-pongo + else + cd .. + git clone git@github.com:Kong/kong-pongo.git + cd kong-pongo + fi + + git checkout master + git pull + ./assets/add_version.sh CE "$version" + if [[ ! $? -eq 0 ]]; then + exit 1 + fi + SUCCESS "Make sure you get the PR above approved and merged." + ;; + + vagrant) + if [ -d ../kong-vagrant ] + then + cd ../kong-vagrant + else + cd .. + git clone git@github.com:Kong/kong-vagrant.git + cd kong-vagrant + fi + + git checkout master + git pull + git checkout -B "$branch" + bump_vagrant + + git diff + + CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:Kong/kong-vagrant" \ + "or Ctrl-C to cancel." + + set -e + git add README.md Vagrantfile + git commit -m "chore(*) bump Kong to $version" + + git push --set-upstream origin "$branch" + hub pull-request -b master -h "$branch" -m "Release: $version" + + SUCCESS "Make sure you get the PR above approved and merged." + ;; + *) die "Unknown step!" ;; From 77daaa69d0b3eae64cc06449f5a8b86446fccf33 Mon Sep 17 00:00:00 2001 From: chronolaw Date: Wed, 2 Mar 2022 09:26:41 +0800 Subject: [PATCH 33/74] 2.8.0 has been released --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9abebedc8f9a..6a9c6ed55d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,7 +62,7 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) -## [2.8.0] (UNRELEASED) +## [2.8.0] ### Deprecations From e2565d8b35a23a75794c91e85acde493f44c496a Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Wed, 23 Mar 2022 18:41:12 -0300 Subject: [PATCH 34/74] chore(rockspec) bump lua-resty-healthcheck 1.5.1 --- kong-2.8.0-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kong-2.8.0-0.rockspec b/kong-2.8.0-0.rockspec index 53cae6ac4fdf..40e27c00957d 100644 --- a/kong-2.8.0-0.rockspec +++ b/kong-2.8.0-0.rockspec @@ -33,7 +33,7 @@ dependencies = { "luaxxhash >= 1.0", "lua-protobuf == 0.3.3", "lua-resty-worker-events == 1.0.0", - "lua-resty-healthcheck == 1.5.0", + "lua-resty-healthcheck == 1.5.1", "lua-resty-mlcache == 2.5.0", "lua-messagepack == 0.5.2", "lua-resty-openssl == 0.8.5", From 88b78dac55f75312fbf156344edb1100e57751f5 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Wed, 23 Mar 2022 18:48:54 -0300 Subject: [PATCH 35/74] chore(CHANGELOG) unreleased section and healthcheck bump --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a9c6ed55d9d..f65cbafa36ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,15 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) +## Unreleased + +### Dependencies + +- Bumped lua-resty-healthcheck from 1.5.0 to 1.5.1 + [#8584](https://github.com/Kong/kong/pull/8584) + +### Fixes + ## [2.8.0] ### Deprecations From 1575371f99094f8d68f95462455856778242d866 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Tue, 22 Mar 2022 10:41:40 -0300 Subject: [PATCH 36/74] fix(runloop) reschedule rebuild timers after running them --- kong/runloop/handler.lua | 34 ++++++++++++++++++++++++------- kong/runloop/plugins_iterator.lua | 5 ++++- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/kong/runloop/handler.lua b/kong/runloop/handler.lua index b07b08297246..182494f85588 100644 --- a/kong/runloop/handler.lua +++ b/kong/runloop/handler.lua @@ -36,7 +36,6 @@ local exit = ngx.exit local exec = ngx.exec local header = ngx.header local timer_at = ngx.timer.at -local timer_every = ngx.timer.every local subsystem = ngx.config.subsystem local clear_header = ngx.req.clear_header local http_version = ngx.req.http_version @@ -1113,7 +1112,7 @@ return { on_timeout = "return_true", } - timer_every(worker_state_update_frequency, function(premature) + local function rebuild_router_timer(premature) if premature then return end @@ -1126,7 +1125,17 @@ return { if not ok then log(ERR, "could not rebuild router via timer: ", err) end - end) + + local _, err = timer_at(worker_state_update_frequency, rebuild_router_timer) + if err then + log(ERR, "could not schedule timer to rebuild router: ", err) + end + end + + local _, err = timer_at(worker_state_update_frequency, rebuild_router_timer) + if err then + log(ERR, "could not schedule timer to rebuild router: ", err) + end local plugins_iterator_async_opts = { name = "plugins_iterator", @@ -1134,16 +1143,27 @@ return { on_timeout = "return_true", } - timer_every(worker_state_update_frequency, function(premature) + local function rebuild_plugins_iterator_timer(premature) if premature then return end - local ok, err = rebuild_plugins_iterator(plugins_iterator_async_opts) - if not ok then + local _, err = rebuild_plugins_iterator(plugins_iterator_async_opts) + if err then log(ERR, "could not rebuild plugins iterator via timer: ", err) end - end) + + local _, err = timer_at(worker_state_update_frequency, rebuild_plugins_iterator_timer) + if err then + log(ERR, "could not schedule timer to rebuild plugins iterator: ", err) + end + end + + local _, err = timer_at(worker_state_update_frequency, rebuild_plugins_iterator_timer) + if err then + log(ERR, "could not schedule timer to rebuild plugins iterator: ", err) + end + end end, after = NOOP, diff --git a/kong/runloop/plugins_iterator.lua b/kong/runloop/plugins_iterator.lua index d59c5b051d96..6e2341c57873 100644 --- a/kong/runloop/plugins_iterator.lua +++ b/kong/runloop/plugins_iterator.lua @@ -466,7 +466,10 @@ function PluginsIterator.new(version) end if new_version ~= version then - return nil, "plugins iterator was changed while rebuilding it" + -- the plugins iterator rebuild is being done by a different process at + -- the same time, stop here and let the other one go for it + kong.log.info("plugins iterator was changed while rebuilding it") + return end end From 59fd1d2a0ee7ae0fd1332fe9e7580a7d39e29d1d Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Mon, 4 Apr 2022 15:11:44 -0300 Subject: [PATCH 37/74] chore(CHANGELOG) timer rescheduling fix changelog entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f65cbafa36ff..eeed46c547cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,12 @@ ### Fixes +#### Core + +- Only reschedule router and plugin iterator timers after finishing previous + execution, avoiding unnecessary concurrent executions. + [#8634](https://github.com/Kong/kong/pull/8634) + ## [2.8.0] ### Deprecations From 9334a590063e177fb7589e80488db67e6d7a39e6 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Mon, 4 Apr 2022 15:16:14 -0300 Subject: [PATCH 38/74] chore(requirements) bump OpenSSL to 1.1.1n --- .requirements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.requirements b/.requirements index a8fd76b06332..43b242843c1e 100644 --- a/.requirements +++ b/.requirements @@ -4,7 +4,7 @@ KONG_LICENSE="ASL 2.0" RESTY_VERSION=1.19.9.1 RESTY_LUAROCKS_VERSION=3.8.0 -RESTY_OPENSSL_VERSION=1.1.1m +RESTY_OPENSSL_VERSION=1.1.1n RESTY_PCRE_VERSION=8.45 LIBYAML_VERSION=0.2.5 KONG_GO_PLUGINSERVER_VERSION=v0.6.1 From c1c80188bc309732c2a1aee8e8f7c35390e835a4 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Mon, 4 Apr 2022 15:19:27 -0300 Subject: [PATCH 39/74] docs(CHANGELOG) dependencies section updated --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f65cbafa36ff..f28be8ac948e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,8 @@ - Bumped lua-resty-healthcheck from 1.5.0 to 1.5.1 [#8584](https://github.com/Kong/kong/pull/8584) +- Bumped `OpenSSL` from 1.1.1l to 1.1.1n + [#8635](https://github.com/Kong/kong/pull/8635) ### Fixes From 7b4ecbc79e02d322760bac65bfc61777b6ef8bab Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 23 Mar 2022 14:22:07 +0200 Subject: [PATCH 40/74] perf(clustering) conditional rebuilding of router, plugins iterator and balancer on dp (#8519) ### Summary Implements conditional rebuilding of `router`, `plugins iterator` and `balancer` on data planes. This means that DPs will not rebuild router if there were no changes in routes or services. Similarly, the plugins iterator will not be rebuild if there were no changes to plugins, and finally balancer in not reinitialized if there are no changes to upstreams or targets. --- kong/clustering/control_plane.lua | 14 ++--- kong/clustering/data_plane.lua | 25 ++++++--- kong/clustering/init.lua | 51 +++++++++++++++++-- kong/db/declarative/init.lua | 30 +++++++++-- kong/runloop/handler.lua | 43 +++++++++++++--- spec/01-unit/19-hybrid/02-clustering_spec.lua | 9 ++-- 6 files changed, 137 insertions(+), 35 deletions(-) diff --git a/kong/clustering/control_plane.lua b/kong/clustering/control_plane.lua index 8da305490d3c..07de520ada1d 100644 --- a/kong/clustering/control_plane.lua +++ b/kong/clustering/control_plane.lua @@ -185,7 +185,7 @@ local function get_removed_fields(dp_version_number) unknown_fields[plugin] = {} end for _, k in ipairs(fields) do - table.insert(unknown_fields[plugin], k) + table_insert(unknown_fields[plugin], k) end end end @@ -199,12 +199,10 @@ _M._get_removed_fields = get_removed_fields -- returns has_update, modified_deflated_payload, err local function update_compatible_payload(payload, dp_version, log_suffix) local fields = get_removed_fields(dp_version_num(dp_version)) - if fields then payload = utils.deep_copy(payload, false) local config_table = payload["config_table"] local has_update = invalidate_keys_from_config(config_table["plugins"], fields) - if has_update then local deflated_payload, err = deflate_gzip(cjson_encode(payload)) if deflated_payload then @@ -234,24 +232,21 @@ function _M:export_deflated_reconfigure_payload() end end - -- store serialized plugins map for troubleshooting purposes local shm_key_name = "clustering:cp_plugins_configured:worker_" .. ngx.worker.id() kong_dict:set(shm_key_name, cjson_encode(self.plugins_configured)); ngx_log(ngx_DEBUG, "plugin configuration map key: " .. shm_key_name .. " configuration: ", kong_dict:get(shm_key_name)) - local config_hash = self:calculate_config_hash(config_table) + local config_hash, hashes = self:calculate_config_hash(config_table) local payload = { type = "reconfigure", timestamp = ngx_now(), config_table = config_table, config_hash = config_hash, + hashes = hashes, } - if not payload then - return nil, err - end self.reconfigure_payload = payload payload, err = deflate_gzip(cjson_encode(payload)) @@ -259,6 +254,7 @@ function _M:export_deflated_reconfigure_payload() return nil, err end + self.current_hashes = hashes self.current_config_hash = config_hash self.deflated_reconfigure_payload = payload @@ -752,7 +748,7 @@ function _M:handle_cp_websocket() deflated_payload = self.deflated_reconfigure_payload elseif err then ngx_log(ngx_WARN, "unable to update compatible payload: ", err, ", the unmodified config ", - "is returned", log_suffix) + "is returned", log_suffix) deflated_payload = self.deflated_reconfigure_payload end diff --git a/kong/clustering/data_plane.lua b/kong/clustering/data_plane.lua index 584d09aa61d9..ce661572c5d1 100644 --- a/kong/clustering/data_plane.lua +++ b/kong/clustering/data_plane.lua @@ -74,20 +74,27 @@ function _M:decode_config(config) end -function _M:update_config(config_table, config_hash, update_cache) +function _M:update_config(config_table, config_hash, update_cache, hashes) assert(type(config_table) == "table") if not config_hash then - config_hash = self:calculate_config_hash(config_table) + config_hash, hashes = self:calculate_config_hash(config_table) + end + + local current_hash = declarative.get_current_hash() + if current_hash == config_hash then + ngx_log(ngx_DEBUG, _log_prefix, "same config received from control plane, ", + "no need to reload") + return true end local entities, err, _, meta, new_hash = - self.declarative_config:parse_table(config_table, config_hash) + self.declarative_config:parse_table(config_table, config_hash) if not entities then return nil, "bad config received from control plane " .. err end - if declarative.get_current_hash() == new_hash then + if current_hash == new_hash then ngx_log(ngx_DEBUG, _log_prefix, "same config received from control plane, ", "no need to reload") return true @@ -95,8 +102,9 @@ function _M:update_config(config_table, config_hash, update_cache) -- NOTE: no worker mutex needed as this code can only be -- executed by worker 0 + local res, err = - declarative.load_into_cache_with_events(entities, meta, new_hash) + declarative.load_into_cache_with_events(entities, meta, new_hash, hashes) if not res then return nil, err end @@ -289,10 +297,12 @@ function _M:communicate(premature) local ok, err = config_semaphore:wait(1) if ok then local config_table = self.next_config - local config_hash = self.next_hash if config_table then + local config_hash = self.next_hash + local hashes = self.next_hashes + local pok, res - pok, res, err = pcall(self.update_config, self, config_table, config_hash, true) + pok, res, err = pcall(self.update_config, self, config_table, config_hash, true, hashes) if pok then if not res then ngx_log(ngx_ERR, _log_prefix, "unable to update running config: ", err) @@ -370,6 +380,7 @@ function _M:communicate(premature) self.next_config = assert(msg.config_table) self.next_hash = msg.config_hash + self.next_hashes = msg.hashes if config_semaphore:count() <= 0 then -- the following line always executes immediately after the `if` check diff --git a/kong/clustering/init.lua b/kong/clustering/init.lua index 01202aafa78a..d859a6dbdda9 100644 --- a/kong/clustering/init.lua +++ b/kong/clustering/init.lua @@ -1,6 +1,6 @@ local _M = {} - +local constants = require("kong.constants") local pl_file = require("pl.file") local pl_tablex = require("pl.tablex") local ssl = require("ngx.ssl") @@ -21,6 +21,9 @@ local sort = table.sort local type = type +local DECLARATIVE_EMPTY_CONFIG_HASH = constants.DECLARATIVE_EMPTY_CONFIG_HASH + + local MT = { __index = _M, } @@ -104,7 +107,7 @@ local function to_sorted_string(value) end else - error("invalid type to be sorted (JSON types are supported") + error("invalid type to be sorted (JSON types are supported)") end end @@ -134,7 +137,49 @@ end function _M:calculate_config_hash(config_table) - return ngx_md5(to_sorted_string(config_table)) + if type(config_table) ~= "table" then + local config_hash = ngx_md5(to_sorted_string(config_table)) + return config_hash, { config = config_hash } + end + + local routes = config_table.routes + local services = config_table.services + local plugins = config_table.plugins + local upstreams = config_table.upstreams + local targets = config_table.targets + + local routes_hash = routes and ngx_md5(to_sorted_string(routes)) or DECLARATIVE_EMPTY_CONFIG_HASH + local services_hash = services and ngx_md5(to_sorted_string(services)) or DECLARATIVE_EMPTY_CONFIG_HASH + local plugins_hash = plugins and ngx_md5(to_sorted_string(plugins)) or DECLARATIVE_EMPTY_CONFIG_HASH + local upstreams_hash = upstreams and ngx_md5(to_sorted_string(upstreams)) or DECLARATIVE_EMPTY_CONFIG_HASH + local targets_hash = targets and ngx_md5(to_sorted_string(targets)) or DECLARATIVE_EMPTY_CONFIG_HASH + + config_table.routes = nil + config_table.services = nil + config_table.plugins = nil + config_table.upstreams = nil + config_table.targets = nil + + local config_hash = ngx_md5(to_sorted_string(config_table) .. routes_hash + .. services_hash + .. plugins_hash + .. upstreams_hash + .. targets_hash) + + config_table.routes = routes + config_table.services = services + config_table.plugins = plugins + config_table.upstreams = upstreams + config_table.targets = targets + + return config_hash, { + config = config_hash, + routes = routes_hash, + services = services_hash, + plugins = plugins_hash, + upstreams = upstreams_hash, + targets = targets_hash, + } end diff --git a/kong/db/declarative/init.lua b/kong/db/declarative/init.lua index 37a03da151f6..6fe730ee9f7f 100644 --- a/kong/db/declarative/init.lua +++ b/kong/db/declarative/init.lua @@ -865,7 +865,7 @@ end do local DECLARATIVE_PAGE_KEY = constants.DECLARATIVE_PAGE_KEY - function declarative.load_into_cache_with_events(entities, meta, hash) + function declarative.load_into_cache_with_events(entities, meta, hash, hashes) if exiting() then return nil, "exiting" end @@ -926,7 +926,31 @@ do local default_ws ok, err, default_ws = declarative.load_into_cache(entities, meta, hash, SHADOW) if ok then - ok, err = worker_events.post("declarative", "flip_config", default_ws) + local router_hash + local plugins_hash + local balancer_hash + if hashes then + if hashes.routes ~= DECLARATIVE_EMPTY_CONFIG_HASH then + router_hash = md5(hashes.services .. hashes.routes) + else + router_hash = DECLARATIVE_EMPTY_CONFIG_HASH + end + + plugins_hash = hashes.plugins + + if hashes.upstreams ~= DECLARATIVE_EMPTY_CONFIG_HASH or hashes.targets ~= DECLARATIVE_EMPTY_CONFIG_HASH then + balancer_hash = md5(hashes.upstreams .. hashes.targets) + else + balancer_hash = DECLARATIVE_EMPTY_CONFIG_HASH + end + end + + ok, err = worker_events.post("declarative", "flip_config", { + default_ws, + router_hash, + plugins_hash, + balancer_hash + }) if ok ~= "done" then kong_shm:delete(DECLARATIVE_LOCK_KEY) return nil, "failed to flip declarative config cache pages: " .. (err or ok) @@ -983,7 +1007,7 @@ do end --- prevent POST /config (declarative.load_into_cache_with_events eary-exits) +-- prevent POST /config (declarative.load_into_cache_with_events early-exits) -- only "succeeds" the first time it gets called. -- successive calls return nil, "exists" function declarative.try_lock() diff --git a/kong/runloop/handler.lua b/kong/runloop/handler.lua index 182494f85588..68f91adafd96 100644 --- a/kong/runloop/handler.lua +++ b/kong/runloop/handler.lua @@ -321,8 +321,8 @@ local function register_balancer_events(core_cache, worker_events, cluster_event return end - singletons.core_cache:invalidate_local("balancer:upstreams") - singletons.core_cache:invalidate_local("balancer:upstreams:" .. upstream.id) + core_cache:invalidate_local("balancer:upstreams") + core_cache:invalidate_local("balancer:upstreams:" .. upstream.id) -- => to balancer update balancer.on_upstream_event(operation, upstream) @@ -359,14 +359,33 @@ local function register_events() -- declarative config updates - worker_events.register(function(default_ws) + local current_router_hash + local current_plugins_hash + local current_balancer_hash + + worker_events.register(function(data) if ngx.worker.exiting() then log(NOTICE, "declarative flip config canceled: process exiting") return true end + local default_ws + local router_hash + local plugins_hash + local balancer_hash + + if type(data) == "table" then + default_ws = data[1] + router_hash = data[2] + plugins_hash = data[3] + balancer_hash = data[4] + end + local ok, err = concurrency.with_coroutine_mutex(FLIP_CONFIG_OPTS, function() - balancer.stop_healthcheckers(CLEAR_HEALTH_STATUS_DELAY) + local rebuild_balancer = balancer_hash == nil or balancer_hash ~= current_balancer_hash + if rebuild_balancer then + balancer.stop_healthcheckers(CLEAR_HEALTH_STATUS_DELAY) + end kong.cache:flip() core_cache:flip() @@ -374,10 +393,20 @@ local function register_events() kong.default_workspace = default_ws ngx.ctx.workspace = kong.default_workspace - rebuild_plugins_iterator(PLUGINS_ITERATOR_SYNC_OPTS) - rebuild_router(ROUTER_SYNC_OPTS) + if plugins_hash == nil or plugins_hash ~= current_plugins_hash then + rebuild_plugins_iterator(PLUGINS_ITERATOR_SYNC_OPTS) + current_plugins_hash = plugins_hash + end - balancer.init() + if router_hash == nil or router_hash ~= current_router_hash then + rebuild_router(ROUTER_SYNC_OPTS) + current_router_hash = router_hash + end + + if rebuild_balancer then + balancer.init() + current_balancer_hash = balancer_hash + end declarative.lock() diff --git a/spec/01-unit/19-hybrid/02-clustering_spec.lua b/spec/01-unit/19-hybrid/02-clustering_spec.lua index 43080a2c71cd..8cb589b5bb0a 100644 --- a/spec/01-unit/19-hybrid/02-clustering_spec.lua +++ b/spec/01-unit/19-hybrid/02-clustering_spec.lua @@ -167,16 +167,13 @@ describe("kong.clustering", function() for _ = 1, 10 do local hash = clustering.calculate_config_hash(clustering, value) assert.is_string(hash) - assert.equal("99914b932bd37a50b983c5e7c90ae93b", hash) + assert.equal("aaf38faf0b5851d711027bb4d812d50d", hash) end - local correct = ngx.md5("{}") - assert.equal("99914b932bd37a50b983c5e7c90ae93b", correct) - for _ = 1, 10 do local hash = clustering.calculate_config_hash(clustering, value) assert.is_string(hash) - assert.equal(correct, hash) + assert.equal("aaf38faf0b5851d711027bb4d812d50d", hash) end end) @@ -207,7 +204,7 @@ describe("kong.clustering", function() for _ = 1, 10 do local hash = clustering.calculate_config_hash(clustering, value) assert.is_string(hash) - assert.equal("e287bdd83a30b3c83c498e6e524f619b", hash) + assert.equal("cb83c48d5b2932d1bc9d13672b433365", hash) assert.equal(h, hash) end end) From f9d5b99338372f6bcfd47f61b2379c05eeb6f4ec Mon Sep 17 00:00:00 2001 From: Wangchong Zhou Date: Tue, 5 Apr 2022 18:26:42 +0200 Subject: [PATCH 41/74] fix(env) localize environ pointer ffi.C.environ's address can change during realloc, this patch avoid globalize it to prevent pointing to wrong memory address --- kong/cmd/utils/env.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kong/cmd/utils/env.lua b/kong/cmd/utils/env.lua index e8131da849ce..d1f3a0f472f9 100644 --- a/kong/cmd/utils/env.lua +++ b/kong/cmd/utils/env.lua @@ -12,14 +12,12 @@ ffi.cdef [[ ]] -local environ = ffi.C.environ - - local function read_all() log.debug("reading environment variables") local env = {} + local environ = ffi.C.environ if not environ then log.warn("could not access **environ") return env From 8a1dc05a69db4b1a7da6ef9092879a96c4e40415 Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Thu, 24 Mar 2022 23:03:49 +0200 Subject: [PATCH 42/74] chore(deps) bump resty.openssl from 0.8.6 to 0.8.7 - **x509.crl:** add functions to find and inspect revoked list in CRL [37c1661](https://github.com/fffonion/lua-resty-openssl/commit/37c1661fbebebad3b804f602f631e4ba65b80e07) --- kong-2.8.0-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kong-2.8.0-0.rockspec b/kong-2.8.0-0.rockspec index 40e27c00957d..8279817368ca 100644 --- a/kong-2.8.0-0.rockspec +++ b/kong-2.8.0-0.rockspec @@ -36,7 +36,7 @@ dependencies = { "lua-resty-healthcheck == 1.5.1", "lua-resty-mlcache == 2.5.0", "lua-messagepack == 0.5.2", - "lua-resty-openssl == 0.8.5", + "lua-resty-openssl == 0.8.7", "lua-resty-counter == 0.2.1", "lua-resty-ipmatcher == 0.6.1", "lua-resty-acme == 0.7.2", From 2e48b0501e8106f614ba0b374d607c42e3b56603 Mon Sep 17 00:00:00 2001 From: Tyler Ball Date: Tue, 5 Apr 2022 20:26:55 -0700 Subject: [PATCH 43/74] docs(changelog) add 2.8.1 changes --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 740d1284749b..52d7d45f0155 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Table of Contents +- [2.8.1](#281) - [2.8.0](#280) - [2.7.1](#271) - [2.7.0](#270) @@ -62,7 +63,7 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) -## Unreleased +## [2.8.1] ### Dependencies @@ -78,6 +79,12 @@ - Only reschedule router and plugin iterator timers after finishing previous execution, avoiding unnecessary concurrent executions. [#8634](https://github.com/Kong/kong/pull/8634) +- Implements conditional rebuilding of router, plugins iterator and balancer on + data planes. This means that DPs will not rebuild router if there were no + changes in routes or services. Similarly, the plugins iterator will not be + rebuilt if there were no changes to plugins, and, finally, the balancer will not be + reinitialized if there are no changes to upstreams or targets. + [#8639](https://github.com/Kong/kong/pull/8639) ## [2.8.0] @@ -6854,6 +6861,7 @@ First version running with Cassandra. [Back to TOC](#table-of-contents) +[2.8.1]: https://github.com/Kong/kong/compare/2.8.0...2.8.1 [2.8.0]: https://github.com/Kong/kong/compare/2.7.0...2.8.0 [2.7.1]: https://github.com/Kong/kong/compare/2.7.0...2.7.1 [2.7.0]: https://github.com/Kong/kong/compare/2.6.0...2.7.0 From 0855e00304459d10df5b208c3b8eb0cf58e3c90f Mon Sep 17 00:00:00 2001 From: Tyler Ball Date: Tue, 5 Apr 2022 20:30:39 -0700 Subject: [PATCH 44/74] docs(kong-admin-api.yml) update Admin API definition for 2.8.1 --- kong-admin-api.yml | 731 +++++++++++++++++++++++---------------------- 1 file changed, 366 insertions(+), 365 deletions(-) diff --git a/kong-admin-api.yml b/kong-admin-api.yml index fa6206867e31..beeb7c561de5 100644 --- a/kong-admin-api.yml +++ b/kong-admin-api.yml @@ -1,189 +1,125 @@ +servers: +- description: 8001 is the default port on which the Admin API listens. + url: http://localhost:8001 +- description: 8444 is the default port for HTTPS traffic to the Admin API. + url: https://localhost:8444 +openapi: 3.1.0 components: schemas: - tags: + snis: required: - - tag - - entity_name - - entity_id + - name + - certificate type: object properties: - entity_id: - type: string - tag: + id: + format: uuid type: string - entity_name: + name: type: string - consumers: - required: [] - type: object - properties: tags: type: array - username: - type: string - id: - type: string - format: uuid - custom_id: - type: string + certificate: + $ref: '#/components/schemas/certificates' created_at: - type: integer format: int32 - plugins: + type: integer + vaults_beta: required: + - prefix - name - - protocols - - enabled type: object properties: - tags: - type: array - enabled: - type: boolean - default: true - service: - $ref: '#/components/schemas/services' - default: ~ - nullable: true - route: - $ref: '#/components/schemas/routes' - default: ~ - nullable: true + id: + format: uuid + type: string created_at: - type: integer format: int32 - consumer: - $ref: '#/components/schemas/consumers' - default: ~ - nullable: true - name: - type: string - id: + type: integer + description: type: string - format: uuid - protocols: - default: - - grpc - - grpcs - - http - - https - enum: - - http - - https - - tcp - - tls - - udp - - grpc - - grpcs + updated_at: + format: int32 + type: integer + tags: type: array config: type: array - certificates: - required: - - cert - - key - type: object - properties: - tags: - type: array - key: - type: string - cert_alt: - type: string - key_alt: - type: string - cert: + name: type: string - created_at: - type: integer - format: int32 - id: + prefix: type: string - format: uuid - ca_certificates: + tags: required: - - cert + - tag + - entity_name + - entity_id type: object properties: - tags: - type: array - id: + entity_name: type: string - format: uuid - cert: + entity_id: type: string - created_at: - type: integer - format: int32 - cert_digest: + tag: type: string - snis: + parameters: required: - - name - - certificate + - key + - value type: object properties: - tags: - type: array - name: + value: type: string - id: + key: type: string - format: uuid created_at: - type: integer format: int32 - certificate: - $ref: '#/components/schemas/certificates' + type: integer upstreams: required: - name type: object properties: - tags: - type: array - created_at: - type: integer - format: int32 - slots: - type: integer - default: 10000 - host_header: - type: string - algorithm: - type: string - default: round-robin - hash_on_header: - type: string - hash_on: - type: string - default: none - hash_fallback_header: - type: string - name: - type: string id: - type: string format: uuid - client_certificate: - $ref: '#/components/schemas/certificates' - hash_on_cookie_path: - type: string - default: / - hash_on_cookie: type: string healthchecks: - type: array default: - passive: + active: + timeout: 1 + healthy: + http_statuses: + - 200 + - 302 + interval: 0 + successes: 0 unhealthy: + interval: 0 + http_statuses: + - 429 + - 404 + - 500 + - 501 + - 502 + - 503 + - 504 + - 505 + tcp_failures: 0 + timeouts: 0 http_failures: 0 + concurrency: 10 + https_verify_certificate: true + type: http + http_path: / + passive: + unhealthy: + timeouts: 0 tcp_failures: 0 http_statuses: - 429 - 500 - 503 - timeouts: 0 + http_failures: 0 type: http healthy: http_statuses: @@ -207,81 +143,78 @@ components: - 307 - 308 successes: 0 - active: - http_path: / - unhealthy: - tcp_failures: 0 - timeouts: 0 - http_failures: 0 - interval: 0 - http_statuses: - - 429 - - 404 - - 500 - - 501 - - 502 - - 503 - - 504 - - 505 - https_verify_certificate: true - concurrency: 10 - timeout: 1 - type: http - healthy: - successes: 0 - interval: 0 - http_statuses: - - 200 - - 302 + type: array + name: + type: string hash_fallback: + default: none type: string + hash_on: default: none - targets: - required: - - upstream - - target - type: object - properties: - upstream: - $ref: '#/components/schemas/upstreams' - target: type: string - id: + hash_on_header: + type: string + host_header: + type: string + hash_fallback_header: type: string - format: uuid - weight: - type: integer - default: 100 - created_at: - type: number - format: float tags: type: array - vaults_beta: + created_at: + format: int32 + type: integer + algorithm: + default: round-robin + type: string + hash_on_cookie_path: + default: / + type: string + hash_on_cookie: + type: string + slots: + default: 10000 + type: integer + client_certificate: + $ref: '#/components/schemas/certificates' + ca_certificates: required: - - prefix - - name + - cert type: object properties: + id: + format: uuid + type: string + cert_digest: + type: string tags: type: array - name: + cert: type: string + created_at: + format: int32 + type: integer + certificates: + required: + - cert + - key + type: object + properties: id: - type: string format: uuid - config: - type: array + type: string created_at: - type: integer format: int32 - prefix: + type: integer + cert: type: string - description: + tags: + type: array + key: + type: string + cert_alt: + type: string + key_alt: type: string - updated_at: - type: integer - format: int32 clustering_data_planes: required: - id @@ -290,54 +223,78 @@ components: - sync_status type: object properties: - version: - type: string id: type: string + ip: + type: string + version: + type: string last_seen: - type: integer format: int32 + type: integer config_hash: type: string - ip: - type: string sync_status: - type: string default: unknown + type: string hostname: type: string - workspaces: + services: required: - - name + - protocol + - host + - port + - enabled type: object properties: name: type: string - id: - type: string - format: uuid - config: - type: array - meta: + tags: type: array - created_at: + retries: + default: 5 type: integer - format: int32 - comment: + connect_timeout: + default: 60000 + type: integer + write_timeout: + default: 60000 + type: integer + read_timeout: + default: 60000 + type: integer + client_certificate: + $ref: '#/components/schemas/certificates' + id: + format: uuid type: string - parameters: - required: - - key - - value - type: object - properties: - value: + tls_verify: + type: boolean + port: + default: 80 + type: integer + tls_verify_depth: + type: integer + nullable: true + default: ~ + enabled: + default: true + type: boolean + path: type: string created_at: + format: int32 type: integer + updated_at: format: int32 - key: + type: integer + protocol: + default: http type: string + host: + type: string + ca_certificates: + type: array routes: required: - protocols @@ -348,123 +305,167 @@ components: - response_buffering type: object properties: + protocols: + default: + - http + - https + type: array + preserve_host: + default: false + type: boolean + name: + type: string + request_buffering: + default: true + type: boolean tags: type: array response_buffering: - type: boolean default: true + type: boolean regex_priority: - type: integer default: 0 + type: integer service: $ref: '#/components/schemas/services' https_redirect_status_code: - type: integer default: 426 + type: integer + id: + format: uuid + type: string headers: type: array destinations: type: array - hosts: + sources: type: array snis: type: array - strip_path: - type: boolean - default: true - methods: + paths: type: array created_at: - type: integer format: int32 - updated_at: type: integer + updated_at: format: int32 - paths: + type: integer + hosts: type: array - name: + strip_path: + default: true + type: boolean + methods: + type: array + path_handling: + default: v0 type: string + consumers: + required: [] + type: object + properties: id: - type: string format: uuid - path_handling: type: string - default: v0 - protocols: - type: array - default: - - http - - https - preserve_host: - type: boolean - default: false - sources: + created_at: + format: int32 + type: integer + tags: type: array - request_buffering: - type: boolean - default: true - services: + username: + type: string + custom_id: + type: string + plugins: required: - - protocol - - host - - port + - name + - protocols - enabled type: object properties: + id: + format: uuid + type: string + name: + type: string tags: type: array - retries: - type: integer - default: 5 - ca_certificates: - type: array - connect_timeout: - type: integer - default: 60000 - write_timeout: - type: integer - default: 60000 - read_timeout: - type: integer - default: 60000 - client_certificate: - $ref: '#/components/schemas/certificates' - tls_verify: + enabled: + default: true type: boolean - port: - type: integer - default: 80 - tls_verify_depth: + service: + $ref: '#/components/schemas/services' + default: ~ + nullable: true + route: + $ref: '#/components/schemas/routes' default: ~ + nullable: true + created_at: + format: int32 type: integer + consumer: + $ref: '#/components/schemas/consumers' + default: ~ nullable: true - enabled: - type: boolean - default: true - path: + config: + type: array + protocols: + type: array + default: + - grpc + - grpcs + - http + - https + enum: + - http + - https + - tcp + - tls + - udp + - grpc + - grpcs + targets: + required: + - upstream + - target + type: object + properties: + id: + format: uuid type: string - updated_at: - type: integer - format: int32 - protocol: + created_at: + format: float + type: number + upstream: + $ref: '#/components/schemas/upstreams' + target: type: string - default: http + tags: + type: array + weight: + default: 100 + type: integer + workspaces: + required: + - name + type: object + properties: id: - type: string format: uuid - host: - type: string - name: type: string created_at: - type: integer format: int32 + type: integer + comment: + type: string + config: + type: array + meta: + type: array + name: + type: string info: - contact: - url: https://github.com/Kong/kong - name: Kong - version: 2.7.0 - title: Kong Admin API summary: Kong RESTful Admin API for administration purposes. description: " {{site.base_gateway}} comes with an **internal** RESTful Admin API for administration purposes.\n Requests to the Admin API can be sent @@ -475,131 +476,131 @@ info: over Kong, so\n care should be taken when setting up Kong environments to avoid undue public\n exposure of this API. See [this document][secure-admin-api] for a discussion\n of methods to secure the Admin API.\n " + version: 2.8.0 + contact: + name: Kong + url: https://github.com/Kong/kong + title: Kong Admin API license: - url: https://github.com/Kong/kong/blob/master/LICENSE name: Apache 2.0 + url: https://github.com/Kong/kong/blob/master/LICENSE paths: - /clustering/status: [] - /upstreams/{upstreams}/targets/{targets}/{address}/unhealthy: + /status: + get: + summary: Retrieve node status + /schemas/plugins/{name}: + get: + summary: Retrieve Plugin Schema + /plugins/schema/{name}: + get: [] + /upstreams/{upstreams}/health: + get: + summary: Show Upstream health for node + /upstreams/{upstreams}/targets: post: description: This method is not available when using DB-less mode. - summary: Set target address as unhealthy - /: + get: [] + /cache: + delete: + description: This method is not available when using DB-less mode. + /config: + post: + description: This method is only available when using DB-less mode. get: - summary: Retrieve node information - /cache/{key}: + description: This method is only available when using DB-less mode. + /clustering/data-planes: [] + /services/{services}/plugins/{plugins}: + patch: + description: This method is not available when using DB-less mode. + /upstreams/{upstreams}/targets/all: + get: + summary: List all Targets + /upstreams/{upstreams}/targets/{targets}: + patch: + description: This method is not available when using DB-less mode. + summary: Update Target + put: + description: This method is not available when using DB-less mode. delete: description: This method is not available when using DB-less mode. + summary: Delete Target get: [] - /certificates/{certificates}/snis: [] /upstreams/{upstreams}/targets/{targets}/unhealthy: post: description: This method is not available when using DB-less mode. summary: Set target as unhealthy - /certificates/{certificates}: - put: + /cache/{key}: + delete: description: This method is not available when using DB-less mode. get: [] + /consumers/{consumers}/plugins/{plugins}: patch: description: This method is not available when using DB-less mode. - /upstreams/{upstreams}/targets: + /plugins: post: description: This method is not available when using DB-less mode. - get: [] - /targets/:targets: [] - /upstreams/{upstreams}/targets/{targets}/healthy: + /consumers/{consumers}/plugins: post: description: This method is not available when using DB-less mode. - summary: Set target as healthy - /upstreams/{upstreams}/targets/{targets}: - put: - description: This method is not available when using DB-less mode. - get: [] - delete: + /upstreams/{upstreams}/targets/{targets}/{address}/healthy: + post: description: This method is not available when using DB-less mode. - summary: Delete Target + summary: Set target address as healthy + /plugins/{plugins}: patch: description: This method is not available when using DB-less mode. - summary: Update Target + /targets/{targets}: [] + /endpoints: + get: + summary: List available endpoints + /targets/{targets}/upstream: [] + /routes/{routes}/plugins: + post: + description: This method is not available when using DB-less mode. + /consumers: + get: [] /tags/{tags}: get: summary: ' List entity IDs by tag ' - /plugins/enabled: - get: - summary: Retrieve Enabled Plugins - /upstreams/{upstreams}/targets/all: + /: get: - summary: List all Targets - /targets/{targets}/upstream: [] + summary: Retrieve node information + /certificates/{certificates}: + patch: + description: This method is not available when using DB-less mode. + put: + description: This method is not available when using DB-less mode. + get: [] + /certificates/{certificates}/snis: [] /certificates/{certificates}/snis/{snis}: [] - /routes/:routes/plugins: - post: [] - /plugins: + /upstreams/{upstreams}/targets/{targets}/healthy: post: description: This method is not available when using DB-less mode. - /cache: - delete: - description: This method is not available when using DB-less mode. - /targets: [] - /config: + summary: Set target as healthy + /upstreams/{upstreams}/targets/{targets}/{address}/unhealthy: post: - description: This method is only available when using DB-less mode. - get: - description: This method is only available when using DB-less mode. - /consumers/{consumers}/plugins/{plugins}: + description: This method is not available when using DB-less mode. + summary: Set target address as unhealthy + /routes/{routes}/plugins/{plugins}: patch: description: This method is not available when using DB-less mode. /schemas/{name}: get: summary: Retrieve Entity Schema - /status: - get: - summary: Retrieve node status - /plugins/schema/{name}: - get: [] - /schemas/plugins/{name}: - get: - summary: Retrieve Plugin Schema - /upstreams/{upstreams}/health: - get: - summary: Show Upstream health for node /schemas/{db_entity_name}/validate: post: description: This method is not available when using DB-less mode. summary: Validate a configuration against a schema - /plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. + /plugins/enabled: + get: + summary: Retrieve Enabled Plugins /snis/{snis}/certificate: [] - /upstreams/{upstreams}/targets/{targets}/{address}/healthy: + /clustering/status: [] + /targets: [] + /services/{services}/plugins: post: description: This method is not available when using DB-less mode. - summary: Set target address as healthy - /routes/{routes}/plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. - /clustering/data-planes: [] /schemas/plugins/validate: post: description: This method is not available when using DB-less mode. summary: Validate a plugin configuration against the schema - /services/{services}/plugins: - post: - description: This method is not available when using DB-less mode. - /services/{services}/plugins/{plugins}: - patch: - description: This method is not available when using DB-less mode. - /consumers: - get: [] - /consumers/{consumers}/plugins: - post: - description: This method is not available when using DB-less mode. - /endpoints: - get: - summary: List available endpoints -servers: -- description: 8001 is the default port on which the Admin API listens. - url: http://localhost:8001 -- description: 8444 is the default port for HTTPS traffic to the Admin API. - url: https://localhost:8444 -openapi: 3.1.0 From bca5b02af85b1b6d82953cbbc26a3269ed499ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garc=C3=ADa=20Cota?= Date: Tue, 29 Mar 2022 13:29:43 +0200 Subject: [PATCH 45/74] docs(api) document header regex in autodocs admin api (#8572) Co-authored-by: lena-larionova <54370747+lena-larionova@users.noreply.github.com> --- autodoc/admin-api/data/admin-api.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autodoc/admin-api/data/admin-api.lua b/autodoc/admin-api/data/admin-api.lua index 501c19e425a7..3ed54153272e 100644 --- a/autodoc/admin-api/data/admin-api.lua +++ b/autodoc/admin-api/data/admin-api.lua @@ -984,6 +984,8 @@ return { match if present in the request. The `Host` header cannot be used with this attribute: hosts should be specified using the `hosts` attribute. + When `headers` contains only one value and that value starts with + the special prefix `~*`, the value is interpreted as a regular expression. ]], examples = { { ["x-my-header"] = {"foo", "bar"}, ["x-another-header"] = {"bla"} }, nil }, skip_in_example = true, -- hack so we get HTTP fields in the first example and Stream fields in the second From 05b7a4a01600520e29341107a6da69faa1da6b33 Mon Sep 17 00:00:00 2001 From: Tyler Ball Date: Tue, 5 Apr 2022 20:32:07 -0700 Subject: [PATCH 46/74] release: 2.8.1 --- kong-2.8.0-0.rockspec => kong-2.8.1-0.rockspec | 4 ++-- kong/meta.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename kong-2.8.0-0.rockspec => kong-2.8.1-0.rockspec (99%) diff --git a/kong-2.8.0-0.rockspec b/kong-2.8.1-0.rockspec similarity index 99% rename from kong-2.8.0-0.rockspec rename to kong-2.8.1-0.rockspec index 8279817368ca..a758f03add31 100644 --- a/kong-2.8.0-0.rockspec +++ b/kong-2.8.1-0.rockspec @@ -1,10 +1,10 @@ package = "kong" -version = "2.8.0-0" +version = "2.8.1-0" rockspec_format = "3.0" supported_platforms = {"linux", "macosx"} source = { url = "git://github.com/Kong/kong", - tag = "2.8.0" + tag = "2.8.1" } description = { summary = "Kong is a scalable and customizable API Management Layer built on top of Nginx.", diff --git a/kong/meta.lua b/kong/meta.lua index 36a96b45b036..0a82752f9a18 100644 --- a/kong/meta.lua +++ b/kong/meta.lua @@ -1,7 +1,7 @@ local version = setmetatable({ major = 2, minor = 8, - patch = 0, + patch = 1, --suffix = "rc.1" }, { -- our Makefile during certain releases adjusts this line. Any changes to From c2b80cdcf156c6a41a884bab7a1956c63f8a0d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garci=CC=81a=20Cota?= Date: Fri, 8 Apr 2022 22:04:01 +0200 Subject: [PATCH 47/74] chore(scripts) add missing update_docker function This function was removed by mistake on a script refactor (#8078). It was cherry-picked back into the master branch (#8495) but not to the release/2.8.x branch. It is not needed for kong to work, but it might be needed in order to do the post-release steps of a hypothetical 2.8.2 release. --- scripts/common.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/scripts/common.sh b/scripts/common.sh index d741b6165814..ede58fe4e677 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -604,6 +604,26 @@ function merge_docker() { " $0 $version submit_docker" } + +#------------------------------------------------------------------------------- +function update_docker { + if [ -d ../docker-kong ] + then + cd ../docker-kong + else + cd .. + git clone https://github.com/kong/docker-kong + cd docker-kong + fi + + git pull + git checkout -B "release/$1" + + set -e + ./update.sh "$1" +} + + #------------------------------------------------------------------------------- function submit_docker() { version=$1 From d6a8d04ff6a3e91e20c3bdb9aa6fc55b729bf155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garc=C3=ADa=20Cota?= Date: Wed, 13 Apr 2022 09:33:18 +0200 Subject: [PATCH 48/74] chore(rockspec) replace git protocol by https (#8672) --- kong-2.8.1-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kong-2.8.1-0.rockspec b/kong-2.8.1-0.rockspec index a758f03add31..e8aaafc0d19f 100644 --- a/kong-2.8.1-0.rockspec +++ b/kong-2.8.1-0.rockspec @@ -3,7 +3,7 @@ version = "2.8.1-0" rockspec_format = "3.0" supported_platforms = {"linux", "macosx"} source = { - url = "git://github.com/Kong/kong", + url = "https://github.com/Kong/kong.git", tag = "2.8.1" } description = { From 47de05507dcacba1c8d1fd4e17cb9e94a9326265 Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 4 May 2022 15:19:43 +0300 Subject: [PATCH 49/74] chore(deps) bump openssl from 1.1.1n to 1.1.1o (#8752) Fixed a bug in the c_rehash script which was not properly sanitising shell metacharacters to prevent command injection ([CVE-2022-1292](https://www.openssl.org/news/vulnerabilities.html#CVE-2022-1292)). --- .requirements | 2 +- CHANGELOG.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.requirements b/.requirements index 43b242843c1e..bba3bf1757c2 100644 --- a/.requirements +++ b/.requirements @@ -4,7 +4,7 @@ KONG_LICENSE="ASL 2.0" RESTY_VERSION=1.19.9.1 RESTY_LUAROCKS_VERSION=3.8.0 -RESTY_OPENSSL_VERSION=1.1.1n +RESTY_OPENSSL_VERSION=1.1.1o RESTY_PCRE_VERSION=8.45 LIBYAML_VERSION=0.2.5 KONG_GO_PLUGINSERVER_VERSION=v0.6.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 52d7d45f0155..86d7c6097c18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Table of Contents +- [2.8.2](#282) - [2.8.1](#281) - [2.8.0](#280) - [2.7.1](#271) @@ -63,6 +64,13 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) +## [2.8.2] + +### Dependencies + +- Bumped `OpenSSL` from 1.1.1n to 1.1.1o + [#8635](https://github.com/Kong/kong/pull/8809) + ## [2.8.1] ### Dependencies From fd4a1594beaeb9ff55725de586505b70350201f3 Mon Sep 17 00:00:00 2001 From: Xumin <100666470+StarlightIbuki@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:21:13 +0800 Subject: [PATCH 50/74] fix(core) support route migration (#9376) support blue/green migration from 2.8.x to 3.0.x. This PR needs #9334 to cooperate. Fix FT-3293 --- kong-dp-spec | 1 + kong/router.lua | 23 ++++++++++++++++--- spec/01-unit/08-router_spec.lua | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) create mode 160000 kong-dp-spec diff --git a/kong-dp-spec b/kong-dp-spec new file mode 160000 index 000000000000..f9432f8c80b4 --- /dev/null +++ b/kong-dp-spec @@ -0,0 +1 @@ +Subproject commit f9432f8c80b419892b3479178e8c3779b3b1f258 diff --git a/kong/router.lua b/kong/router.lua index 3ed96cc4a1a8..2fd83b2d6457 100644 --- a/kong/router.lua +++ b/kong/router.lua @@ -504,7 +504,23 @@ local function marshall_route(r) for i = 1, count do local path = paths[i] - if re_find(path, [[[a-zA-Z0-9\.\-_~/%]*$]], "ajo") then + -- we are supporting boths 2.x route path and 3.0 route paths + -- for a path not starting with ~, we assume it is a 2.x route path + -- it's safe because even if it's a 3.0 prefix path, we can normalize a prefix path + -- more than once and get the same result + -- and for a path start with ~ we just do what 3.0 do + local is_prefix + local need_normalize = true + if path:sub(1, 1) == "~" then + is_prefix, need_normalize = false, false + path = normalize_regex(path:sub(2)) + + + else + is_prefix = not not re_find(path, [[[a-zA-Z0-9\.\-_~/%]*$]], "ajo") + end + + if is_prefix then -- plain URI or URI prefix local uri_t = { @@ -517,9 +533,10 @@ local function marshall_route(r) max_uri_length = max(max_uri_length, #path) else - local path = normalize_regex(path) - -- regex URI + if need_normalize then + path = normalize_regex(path) + end local strip_regex = REGEX_PREFIX .. path .. [[(?.*)]] local uri_t = { diff --git a/spec/01-unit/08-router_spec.lua b/spec/01-unit/08-router_spec.lua index a7cb4c339c63..3b9be2255d7e 100644 --- a/spec/01-unit/08-router_spec.lua +++ b/spec/01-unit/08-router_spec.lua @@ -3626,3 +3626,43 @@ describe("[both regex and prefix with regex_priority]", function() end) end) + +describe("support 3.0 #migration", function () + it("works for 3.0 path", function() + local use_case = { + -- regex + { + service = service, + route = { + paths = { + [[~/v\d+]] + }, + hosts = { + "domain-1.org", + }, + }, + }, + -- normalized prefix + { + service = service, + route = { + paths = { + [[/中文]] + }, + }, + }, + } + local router = assert(Router.new(use_case)) + local match_t = router.select("GET", "/v1", "domain-1.org") + assert.truthy(match_t) + assert.same(use_case[1].route, match_t.route) + + match_t = router.select("GET", "/v12", "domain-1.org") + assert.truthy(match_t) + assert.same(use_case[1].route, match_t.route) + + match_t = router.select("GET", "/中文", "domain-2.org") + assert.truthy(match_t) + assert.same(use_case[2].route, match_t.route) + end) +end) From daa5af1d52131363ff2c9ac383efa09de92b62a3 Mon Sep 17 00:00:00 2001 From: Qi Date: Fri, 30 Sep 2022 15:19:03 +0800 Subject: [PATCH 51/74] perf(router): dynamic router lru cache size based on number of routes --- kong/router.lua | 18 ++++-------------- kong/runloop/handler.lua | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/kong/router.lua b/kong/router.lua index 2fd83b2d6457..2e5b9790d5b4 100644 --- a/kong/router.lua +++ b/kong/router.lua @@ -239,17 +239,7 @@ do end ---[[ -Hypothesis ----------- - -Item size: 1024 bytes -Max memory limit: 5 MiBs - -LRU size must be: (5 * 2^20) / 1024 = 5120 -Floored: 5000 items should be a good default ---]] -local MATCH_LRUCACHE_SIZE = 5e3 +local DEFAULT_MATCH_LRUCACHE_SIZE = 5000 local MATCH_RULES = { @@ -1471,7 +1461,7 @@ local function find_match(ctx) end -local _M = { MATCH_LRUCACHE_SIZE = MATCH_LRUCACHE_SIZE } +local _M = { DEFAULT_MATCH_LRUCACHE_SIZE = DEFAULT_MATCH_LRUCACHE_SIZE } -- for unit-testing purposes only @@ -1516,11 +1506,11 @@ function _M.new(routes, cache, cache_neg) local routes_by_id = {} if not cache then - cache = lrucache.new(MATCH_LRUCACHE_SIZE) + cache = lrucache.new(DEFAULT_MATCH_LRUCACHE_SIZE) end if not cache_neg then - cache_neg = lrucache.new(MATCH_LRUCACHE_SIZE) + cache_neg = lrucache.new(DEFAULT_MATCH_LRUCACHE_SIZE) end -- index routes diff --git a/kong/runloop/handler.lua b/kong/runloop/handler.lua index 68f91adafd96..20a43270d256 100644 --- a/kong/runloop/handler.lua +++ b/kong/runloop/handler.lua @@ -646,10 +646,17 @@ end do + local max = math.max + local min = math.min + local ceil = math.ceil + + local DEFAULT_MATCH_LRUCACHE_SIZE = Router.DEFAULT_MATCH_LRUCACHE_SIZE + local router local router_version - local router_cache = lrucache.new(Router.MATCH_LRUCACHE_SIZE) - local router_cache_neg = lrucache.new(Router.MATCH_LRUCACHE_SIZE) + local router_cache_size = DEFAULT_MATCH_LRUCACHE_SIZE + local router_cache = lrucache.new(router_cache_size) + local router_cache_neg = lrucache.new(router_cache_size) -- Given a protocol, return the subsystem that handles it @@ -774,8 +781,8 @@ do return nil, "could not load routes: " .. err end - if db.strategy ~= "off" then - if kong.core_cache and counter > 0 and counter % page_size == 0 then + if db.strategy ~= "off" and kong.core_cache then + if counter > 0 and counter % page_size == 0 then local new_version, err = get_router_version() if err then return nil, "failed to retrieve router version: " .. err @@ -785,6 +792,7 @@ do return nil, "router was changed while rebuilding it" end end + counter = counter + 1 end if should_process_route(route) then @@ -805,8 +813,14 @@ do routes[i] = r end end + end + + local n = DEFAULT_MATCH_LRUCACHE_SIZE + local cache_size = min(ceil(max(i / n, 1)) * n, n * 20) - counter = counter + 1 + if cache_size ~= router_cache_size then + router_cache = lrucache.new(cache_size) + router_cache_size = cache_size end local new_router, err = Router.new(routes, router_cache, router_cache_neg) From cc26f3a171d75ab5a168cbbe5978b5c892298af2 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Mon, 18 Apr 2022 15:54:35 -0300 Subject: [PATCH 52/74] fix(balancer) start only needed upstream update timers --- kong/runloop/balancer/init.lua | 11 +-- kong/runloop/balancer/upstreams.lua | 23 ++++- .../04-admin_api/15-off_spec.lua | 93 +++++++++++++++++++ 3 files changed, 115 insertions(+), 12 deletions(-) diff --git a/kong/runloop/balancer/init.lua b/kong/runloop/balancer/init.lua index 6d368cf4aa75..5ea736b657ea 100644 --- a/kong/runloop/balancer/init.lua +++ b/kong/runloop/balancer/init.lua @@ -25,7 +25,6 @@ local pairs = pairs local tostring = tostring local table = table local table_concat = table.concat -local timer_at = ngx.timer.at local run_hook = hooks.run_hook local var = ngx.var @@ -33,7 +32,6 @@ local var = ngx.var local CRIT = ngx.CRIT local ERR = ngx.ERR local WARN = ngx.WARN -local DEBUG = ngx.DEBUG local EMPTY_T = pl_tablex.readonly {} @@ -189,14 +187,7 @@ local function init() end end - local _ - local frequency = kong.configuration.worker_state_update_frequency or 1 - _, err = timer_at(frequency, upstreams.update_balancer_state) - if err then - log(CRIT, "unable to start update proxy state timer: ", err) - else - log(DEBUG, "update proxy state timer scheduled") - end + upstreams.update_balancer_state() end diff --git a/kong/runloop/balancer/upstreams.lua b/kong/runloop/balancer/upstreams.lua index 834413ebdf80..c23555a3b8d0 100644 --- a/kong/runloop/balancer/upstreams.lua +++ b/kong/runloop/balancer/upstreams.lua @@ -20,6 +20,7 @@ local timer_at = ngx.timer.at local CRIT = ngx.CRIT +local DEBUG = ngx.DEBUG local ERR = ngx.ERR local GLOBAL_QUERY_OPTS = { workspace = null, show_ws_id = true } @@ -232,11 +233,13 @@ local function set_upstream_events_queue(operation, upstream_data) end -function upstreams_M.update_balancer_state(premature) +local update_balancer_state_running +local function update_balancer_state_timer(premature) if premature then return end + update_balancer_state_running = true while upstream_events_queue[1] do local event = upstream_events_queue[1] @@ -250,14 +253,30 @@ function upstreams_M.update_balancer_state(premature) end local frequency = kong.configuration.worker_state_update_frequency or 1 - local _, err = timer_at(frequency, upstreams_M.update_balancer_state) + local _, err = timer_at(frequency, update_balancer_state_timer) if err then + update_balancer_state_running = false log(CRIT, "unable to reschedule update proxy state timer: ", err) end end +function upstreams_M.update_balancer_state() + if update_balancer_state_running then + return + end + + local frequency = kong.configuration.worker_state_update_frequency or 1 + local _, err = timer_at(frequency, update_balancer_state_timer) + if err then + log(CRIT, "unable to start update proxy state timer: ", err) + else + log(DEBUG, "update proxy state timer scheduled") + end +end + + -------------------------------------------------------------------------------- diff --git a/spec/02-integration/04-admin_api/15-off_spec.lua b/spec/02-integration/04-admin_api/15-off_spec.lua index 30f4fd68288e..b6c4b23ad32b 100644 --- a/spec/02-integration/04-admin_api/15-off_spec.lua +++ b/spec/02-integration/04-admin_api/15-off_spec.lua @@ -1108,3 +1108,96 @@ describe("Admin API #off with Unique Foreign #unique", function() assert.equal(references.data[1].unique_foreign.id, unique_reference.unique_foreign.id) end) end) + +describe("Admin API #off worker_consistency=eventual", function() + + local client + + lazy_setup(function() + assert(helpers.start_kong({ + database = "off", + worker_consistency = "eventual", + worker_state_update_frequency = 0.1, + })) + end) + + lazy_teardown(function() + helpers.stop_kong(nil, true) + end) + + before_each(function() + client = assert(helpers.admin_client()) + end) + + after_each(function() + if client then + client:close() + end + end) + + it("does not increase timer usage (regression)", function() + -- 1. configure a simple service + local res = assert(client:send { + method = "POST", + path = "/config", + body = helpers.unindent([[ + _format_version: '1.1' + services: + - name: konghq + url: http://konghq.com + path: / + plugins: + - name: prometheus + ]]), + headers = { + ["Content-Type"] = "text/yaml" + }, + }) + assert.response(res).has.status(201) + + -- 2. check the timer count + res = assert(client:send { + method = "GET", + path = "/metrics", + }) + local res_body = assert.res_status(200, res) + local req1_pending_timers = assert.matches('kong_nginx_timers{state="pending"} %d+', res_body) + local req1_running_timers = assert.matches('kong_nginx_timers{state="running"} %d+', res_body) + req1_pending_timers = assert(tonumber(string.match(req1_pending_timers, "%d"))) + req1_running_timers = assert(tonumber(string.match(req1_running_timers, "%d"))) + + -- 3. update the service + res = assert(client:send { + method = "POST", + path = "/config", + body = helpers.unindent([[ + _format_version: '1.1' + services: + - name: konghq + url: http://konghq.com + path: /install#kong-community + plugins: + - name: prometheus + ]]), + headers = { + ["Content-Type"] = "text/yaml" + }, + }) + assert.response(res).has.status(201) + + -- 4. check if timer count is still the same + res = assert(client:send { + method = "GET", + path = "/metrics", + }) + local res_body = assert.res_status(200, res) + local req2_pending_timers = assert.matches('kong_nginx_timers{state="pending"} %d+', res_body) + local req2_running_timers = assert.matches('kong_nginx_timers{state="running"} %d+', res_body) + req2_pending_timers = assert(tonumber(string.match(req2_pending_timers, "%d"))) + req2_running_timers = assert(tonumber(string.match(req2_running_timers, "%d"))) + + assert.equal(req1_pending_timers, req2_pending_timers) + assert.equal(req1_running_timers, req2_running_timers) + end) + +end) From 24a1084e8b0bd085d03747d59fd3632a66cb9edf Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Wed, 25 May 2022 17:27:13 -0300 Subject: [PATCH 53/74] fix(upstreams) mark the update timer as scheduled when the balancer state timer is running, it updates the flag that avoids it to be started again. this commit adds this same behavior to scheduling the update timer, instead of waiting for the first run --- kong/runloop/balancer/upstreams.lua | 1 + spec/02-integration/04-admin_api/15-off_spec.lua | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/kong/runloop/balancer/upstreams.lua b/kong/runloop/balancer/upstreams.lua index c23555a3b8d0..000759811a11 100644 --- a/kong/runloop/balancer/upstreams.lua +++ b/kong/runloop/balancer/upstreams.lua @@ -272,6 +272,7 @@ function upstreams_M.update_balancer_state() if err then log(CRIT, "unable to start update proxy state timer: ", err) else + update_balancer_state_running = true log(DEBUG, "update proxy state timer scheduled") end end diff --git a/spec/02-integration/04-admin_api/15-off_spec.lua b/spec/02-integration/04-admin_api/15-off_spec.lua index b6c4b23ad32b..cd4b4fed1173 100644 --- a/spec/02-integration/04-admin_api/15-off_spec.lua +++ b/spec/02-integration/04-admin_api/15-off_spec.lua @@ -1112,12 +1112,13 @@ end) describe("Admin API #off worker_consistency=eventual", function() local client + local WORKER_STATE_UPDATE_FREQ = 0.1 lazy_setup(function() assert(helpers.start_kong({ database = "off", worker_consistency = "eventual", - worker_state_update_frequency = 0.1, + worker_state_update_frequency = WORKER_STATE_UPDATE_FREQ, })) end) From 9a22da1f017361d6afa289d961a83ed05580a86f Mon Sep 17 00:00:00 2001 From: Yusheng Li Date: Wed, 12 Oct 2022 14:07:27 +0800 Subject: [PATCH 54/74] fix(admin): increase max uri and post arguments to 1000 (#9530) Admin API will quietly truncate the request post arguments if reach the limit(100), which might cause data inconsistency issues. This is a backport of #9510 to the 2.8 release branch. FTI-4417 --- CHANGELOG.md | 9 +++ kong/api/arguments.lua | 13 +++- .../21-truncated_arguments_spec.lua | 70 +++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 spec/02-integration/04-admin_api/21-truncated_arguments_spec.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d7c6097c18..aba8ca680944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,15 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) +## Unreleased + +### Fixes + +#### Admin API + +- Increase the maximum request argument number from 100 to 1000, and return 400 error if request parameters reach the limitation to avoid being truncated. + [#9510](https://github.com/Kong/kong/pull/9510) + ## [2.8.2] ### Dependencies diff --git a/kong/api/arguments.lua b/kong/api/arguments.lua index 859e72d6e8cf..e58c042a7da6 100644 --- a/kong/api/arguments.lua +++ b/kong/api/arguments.lua @@ -25,6 +25,7 @@ local get_uri_args = req.get_uri_args local get_body_data = req.get_body_data local get_post_args = req.get_post_args local json_decode = cjson.decode +local kong = kong local NOTICE = ngx.NOTICE @@ -60,8 +61,8 @@ local defaults = { multipart = true, timeout = 1000, chunk_size = 4096, - max_uri_args = 100, - max_post_args = 100, + max_uri_args = 1000, + max_post_args = 1000, max_line_size = nil, max_part_size = nil, } @@ -631,7 +632,10 @@ local function load(opts) post = {}, }, arguments_mt) - local uargs = get_uri_args(options.max_uri_args) + local uargs, err = get_uri_args(options.max_uri_args) + if err == "truncated" then + return kong.response.exit(400, { message = "Too many arguments" }) + end if options.decode then args.uri = decode(uargs, options.schema) @@ -650,6 +654,9 @@ local function load(opts) if find(content_type_lower, "application/x-www-form-urlencoded", 1, true) == 1 then req_read_body() local pargs, err = get_post_args(options.max_post_args) + if err == "truncated" then + return kong.response.exit(400, { message = "Too many arguments" }) + end if pargs then if options.decode then args.post = decode(pargs, options.schema) diff --git a/spec/02-integration/04-admin_api/21-truncated_arguments_spec.lua b/spec/02-integration/04-admin_api/21-truncated_arguments_spec.lua new file mode 100644 index 000000000000..03d342edaf3d --- /dev/null +++ b/spec/02-integration/04-admin_api/21-truncated_arguments_spec.lua @@ -0,0 +1,70 @@ +local helpers = require "spec.helpers" + +for _, strategy in helpers.each_strategy() do + + describe("Admin API - truncated arguments #" .. strategy, function() + local max_uri_args_overflow = 1000 + 1 + local max_post_args_overflow = 1000 + 1 + + local client + + lazy_setup(function() + helpers.get_db_utils(strategy) + assert(helpers.start_kong({ + database = strategy, + nginx_conf = "spec/fixtures/custom_nginx.template", + plugins = "bundled", + })) + end) + + lazy_teardown(function() + helpers.stop_kong(nil, true) + end) + + before_each(function() + client = helpers.admin_client() + end) + + after_each(function() + if client then + client:close() + end + end) + + it("return 400 if reach maximum post arguments number", function() + local items = {} + for i = 1, max_post_args_overflow do + table.insert(items, "config.allow=" .. i) + end + local body = "name=ip-restriction&" .. table.concat(items, "&") + local res = assert(client:send { + method = "POST", + path = "/plugins", + headers = { + ["Content-Type"] = "application/x-www-form-urlencoded", + }, + body = body, + }) + assert.response(res).has.status(400) + local json = assert.response(res).has.jsonbody() + assert.same({ message = "Too many arguments" }, json) + end) + + it("return 400 if reach maximum uri arguments number", function() + local items = {} + for i = 1, max_uri_args_overflow do + table.insert(items, "a=" .. i) + end + local querystring = table.concat(items, "&") + local res = assert(client:send { + method = "GET", + path = "/plugins?" .. querystring, + }) + assert.response(res).has.status(400) + local json = assert.response(res).has.jsonbody() + assert.same({ message = "Too many arguments" }, json) + end) + + end) + +end From 3f67662bf7ee10e39be963dcc75d7c6b618bdde8 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Fri, 14 Oct 2022 18:08:40 +0000 Subject: [PATCH 55/74] fix(url): adjust the pulp admin api links (#9555) --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 289f71afaf02..17402bc37ceb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,9 +11,9 @@ pipeline { DOCKER_PASSWORD = "${env.DOCKER_CREDENTIALS_PSW}" KONG_PACKAGE_NAME = "kong" DOCKER_CLI_EXPERIMENTAL = "enabled" - PULP_HOST_PROD = "https://api.pulp.konnect-prod.konghq.com" + PULP_HOST_PROD = "https://api.download.konghq.com" PULP_PROD = credentials('PULP') - PULP_HOST_STAGE = "https://api.pulp.konnect-stage.konghq.com" + PULP_HOST_STAGE = "https://api.download-dev.konghq.com" PULP_STAGE = credentials('PULP_STAGE') GITHUB_TOKEN = credentials('github_bot_access_token') DEBUG = 0 From a1b1497199c3ffdf8285990b1295a081fe632557 Mon Sep 17 00:00:00 2001 From: Isa Farnik Date: Fri, 14 Oct 2022 12:02:42 -0700 Subject: [PATCH 56/74] fix(aws): backport usage of IP access key --- Jenkinsfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 17402bc37ceb..3d2d252af6ae 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -84,8 +84,7 @@ pipeline { environment { KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('AWS_ACCESS_KEY') - AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY') + AWS_ACCESS_KEY = credentials('instanceprofile') } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' @@ -211,8 +210,7 @@ pipeline { USER = 'travis' KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('AWS_ACCESS_KEY') - AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY') + AWS_ACCESS_KEY = credentials('instanceprofile') } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' From ed2119da22086db5fbdc75650157001bb4b80e6e Mon Sep 17 00:00:00 2001 From: Isa Farnik Date: Fri, 14 Oct 2022 12:40:04 -0700 Subject: [PATCH 57/74] fix(kbt): use backport of AWS ENVs --- .requirements | 2 +- Jenkinsfile | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.requirements b/.requirements index bba3bf1757c2..4450aae7f5bd 100644 --- a/.requirements +++ b/.requirements @@ -8,5 +8,5 @@ RESTY_OPENSSL_VERSION=1.1.1o RESTY_PCRE_VERSION=8.45 LIBYAML_VERSION=0.2.5 KONG_GO_PLUGINSERVER_VERSION=v0.6.1 -KONG_BUILD_TOOLS_VERSION=4.25.3 +KONG_BUILD_TOOLS_VERSION=4.25.5 KONG_NGINX_MODULE_BRANCH=0.2.0 diff --git a/Jenkinsfile b/Jenkinsfile index 3d2d252af6ae..d099255aa779 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,8 +33,7 @@ pipeline { KONG_PACKAGE_NAME = "kong" KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('AWS_ACCESS_KEY') - AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY') + AWS_ACCESS_KEY = credentials('instanceprofile') CACHE = "false" UPDATE_CACHE = "true" RELEASE_DOCKER_ONLY="true" @@ -66,8 +65,6 @@ pipeline { environment { KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('AWS_ACCESS_KEY') - AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY') } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' From 87cc5b95def2758dd0c090c6757febc7ff2aafaa Mon Sep 17 00:00:00 2001 From: Isa Farnik Date: Fri, 14 Oct 2022 12:51:09 -0700 Subject: [PATCH 58/74] fix(jenkins): backport release/* condition --- Jenkinsfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index d099255aa779..52bce9c533d6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -22,7 +22,10 @@ pipeline { stage('Release Per Commit') { when { beforeAgent true - anyOf { branch 'master'; } + anyOf { + branch 'master'; + branch 'release/*'; + } } agent { node { From 0ea9ca12a8304a58f5890413cedd6f546950dc52 Mon Sep 17 00:00:00 2001 From: Isa Farnik Date: Fri, 14 Oct 2022 12:55:28 -0700 Subject: [PATCH 59/74] fix(jenkins): proper aws access (literal) --- Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 52bce9c533d6..90b38ffb38f7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -36,7 +36,7 @@ pipeline { KONG_PACKAGE_NAME = "kong" KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('instanceprofile') + AWS_ACCESS_KEY = "instanceprofile" CACHE = "false" UPDATE_CACHE = "true" RELEASE_DOCKER_ONLY="true" @@ -84,7 +84,7 @@ pipeline { environment { KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('instanceprofile') + AWS_ACCESS_KEY = "instanceprofile" } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' @@ -210,7 +210,7 @@ pipeline { USER = 'travis' KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = credentials('instanceprofile') + AWS_ACCESS_KEY = "instanceprofile" } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' From 220c9d93cc8c6e5bb762eb43ea96365b3b00a6bc Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Tue, 18 Oct 2022 16:38:27 +0000 Subject: [PATCH 60/74] fix(relese): group releases by package type and drop some EOL --- Jenkinsfile | 138 ++++++++-------------------------------------------- 1 file changed, 20 insertions(+), 118 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 90b38ffb38f7..6bb726c0df2b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -59,7 +59,7 @@ pipeline { } } parallel { - stage('AmazonLinux') { + stage('RPM') { agent { node { label 'bionic' @@ -68,159 +68,61 @@ pipeline { environment { KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - } - steps { - sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' - sh 'make setup-kong-build-tools' - sh 'PACKAGE_TYPE=rpm RESTY_IMAGE_BASE=amazonlinux RESTY_IMAGE_TAG=2 make release' - } - } - stage('src & Alpine') { - agent { - node { - label 'bionic' - } - } - environment { - KONG_SOURCE_LOCATION = "${env.WORKSPACE}" - KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - AWS_ACCESS_KEY = "instanceprofile" - } - steps { - sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' - sh 'make setup-kong-build-tools' - sh 'PACKAGE_TYPE=src RESTY_IMAGE_BASE=src make release' - sh 'PACKAGE_TYPE=apk RESTY_IMAGE_BASE=alpine RESTY_IMAGE_TAG=3.14 CACHE=false DOCKER_MACHINE_ARM64_NAME="kong-"`cat /proc/sys/kernel/random/uuid` make release' - - } - } - stage('RedHat') { - agent { - node { - label 'bionic' - } - } - environment { - PACKAGE_TYPE = 'rpm' - RESTY_IMAGE_BASE = 'rhel' - KONG_SOURCE_LOCATION = "${env.WORKSPACE}" - KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - PRIVATE_KEY_FILE = credentials('kong.private.gpg-key.asc') - PRIVATE_KEY_PASSPHRASE = credentials('kong.private.gpg-key.asc.password') - } - steps { - sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' - sh 'make setup-kong-build-tools' - sh 'cp $PRIVATE_KEY_FILE ../kong-build-tools/kong.private.gpg-key.asc' - sh 'RESTY_IMAGE_TAG=7 make release' - sh 'RESTY_IMAGE_TAG=8 make release' - } - } - stage('CentOS') { - agent { - node { - label 'bionic' - } - } - environment { - PACKAGE_TYPE = 'rpm' - RESTY_IMAGE_BASE = 'centos' - KONG_SOURCE_LOCATION = "${env.WORKSPACE}" - KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" + PACKAGE_TYPE = "rpm" PRIVATE_KEY_FILE = credentials('kong.private.gpg-key.asc') PRIVATE_KEY_PASSPHRASE = credentials('kong.private.gpg-key.asc.password') + GITHUB_SSH_KEY = credentials('github_bot_ssh_key') } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' sh 'make setup-kong-build-tools' sh 'cp $PRIVATE_KEY_FILE ../kong-build-tools/kong.private.gpg-key.asc' - sh 'RESTY_IMAGE_TAG=7 make release' - sh 'RESTY_IMAGE_TAG=8 make release' - } - } - stage('Debian OldStable') { - agent { - node { - label 'bionic' - } - } - environment { - PACKAGE_TYPE = 'deb' - RESTY_IMAGE_BASE = 'debian' - KONG_SOURCE_LOCATION = "${env.WORKSPACE}" - KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - } - steps { - sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' - sh 'make setup-kong-build-tools' - sh 'RESTY_IMAGE_TAG=stretch make release' - } - } - stage('Debian Stable & Testing') { - agent { - node { - label 'bionic' - } - } - environment { - PACKAGE_TYPE = 'deb' - RESTY_IMAGE_BASE = 'debian' - KONG_SOURCE_LOCATION = "${env.WORKSPACE}" - KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - } - steps { - sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' - sh 'make setup-kong-build-tools' - sh 'RESTY_IMAGE_TAG=buster make release' - sh 'RESTY_IMAGE_TAG=bullseye make release' + sh 'make RESTY_IMAGE_BASE=amazonlinux RESTY_IMAGE_TAG=2 release' + sh 'make RESTY_IMAGE_BASE=centos RESTY_IMAGE_TAG=7 release' + sh 'make RESTY_IMAGE_BASE=rhel RESTY_IMAGE_TAG=7.9 release' + sh 'make RESTY_IMAGE_BASE=rhel RESTY_IMAGE_TAG=8.6 RELEASE_DOCKER=true release' } } - stage('Ubuntu') { + stage('DEB') { agent { node { label 'bionic' } } environment { - PACKAGE_TYPE = 'deb' - RESTY_IMAGE_BASE = 'ubuntu' - RESTY_IMAGE_TAG = 'bionic' KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" + PACKAGE_TYPE = "deb" + GITHUB_SSH_KEY = credentials('github_bot_ssh_key') } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' sh 'make setup-kong-build-tools' - sh 'RESTY_IMAGE_TAG=bionic make release' - sh 'RESTY_IMAGE_TAG=focal make release' + sh 'make RESTY_IMAGE_BASE=debian RESTY_IMAGE_TAG=10 release' + sh 'make RESTY_IMAGE_BASE=debian RESTY_IMAGE_TAG=11 RELEASE_DOCKER=true release' + sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=16.04 DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` release' + sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=18.04 release' + sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=20.04 RELEASE_DOCKER=true release' } } - stage('Ubuntu Xenial') { + stage('SRC & Alpine') { agent { node { label 'bionic' } } environment { - PACKAGE_TYPE = 'deb' - RESTY_IMAGE_BASE = 'ubuntu' - RESTY_IMAGE_TAG = 'xenial' - CACHE = 'false' - UPDATE_CACHE = 'true' - USER = 'travis' KONG_SOURCE_LOCATION = "${env.WORKSPACE}" KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" + PACKAGE_TYPE = "rpm" + GITHUB_SSH_KEY = credentials('github_bot_ssh_key') AWS_ACCESS_KEY = "instanceprofile" } steps { sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' sh 'make setup-kong-build-tools' - sh 'DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` make release' - } - post { - cleanup { - dir('../kong-build-tools'){ sh 'make cleanup-build' } - } + sh 'make RESTY_IMAGE_BASE=src RESTY_IMAGE_TAG=src PACKAGE_TYPE=src release' + sh 'make RESTY_IMAGE_BASE=alpine RESTY_IMAGE_TAG=3.10 PACKAGE_TYPE=apk DOCKER_MACHINE_ARM64_NAME="kong-"`cat /proc/sys/kernel/random/uuid` RELEASE_DOCKER=true release' } } } From a1210cf6c24b20eabab2a4388ea2e57ff3fe1ea3 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Tue, 18 Oct 2022 19:24:17 +0000 Subject: [PATCH 61/74] fix(rhel): use the redhat major number only --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6bb726c0df2b..0da16c926b99 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -79,8 +79,8 @@ pipeline { sh 'cp $PRIVATE_KEY_FILE ../kong-build-tools/kong.private.gpg-key.asc' sh 'make RESTY_IMAGE_BASE=amazonlinux RESTY_IMAGE_TAG=2 release' sh 'make RESTY_IMAGE_BASE=centos RESTY_IMAGE_TAG=7 release' - sh 'make RESTY_IMAGE_BASE=rhel RESTY_IMAGE_TAG=7.9 release' - sh 'make RESTY_IMAGE_BASE=rhel RESTY_IMAGE_TAG=8.6 RELEASE_DOCKER=true release' + sh 'make RESTY_IMAGE_BASE=rhel RESTY_IMAGE_TAG=7 release' + sh 'make RESTY_IMAGE_BASE=rhel RESTY_IMAGE_TAG=8 RELEASE_DOCKER=true release' } } stage('DEB') { From 35264641039f05b1c594e9e5ea796a51ee096cd2 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Tue, 18 Oct 2022 19:39:48 +0000 Subject: [PATCH 62/74] fix(release): ubuntu arm64 build can't hit cache --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0da16c926b99..52e0efa40f6f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -100,7 +100,7 @@ pipeline { sh 'make setup-kong-build-tools' sh 'make RESTY_IMAGE_BASE=debian RESTY_IMAGE_TAG=10 release' sh 'make RESTY_IMAGE_BASE=debian RESTY_IMAGE_TAG=11 RELEASE_DOCKER=true release' - sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=16.04 DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` release' + sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=16.04 AWS_ACCESS_KEY=instanceprofile CACHE=false DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` release' sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=18.04 release' sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=20.04 RELEASE_DOCKER=true release' } From 651d4fef45666c28b695fa8e32fb06f442417905 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 19 Oct 2022 13:28:54 +0000 Subject: [PATCH 63/74] fix(release): drop ubuntu 16.04 --- Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 52e0efa40f6f..e3092e8a0d9a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -100,8 +100,7 @@ pipeline { sh 'make setup-kong-build-tools' sh 'make RESTY_IMAGE_BASE=debian RESTY_IMAGE_TAG=10 release' sh 'make RESTY_IMAGE_BASE=debian RESTY_IMAGE_TAG=11 RELEASE_DOCKER=true release' - sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=16.04 AWS_ACCESS_KEY=instanceprofile CACHE=false DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` release' - sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=18.04 release' + sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=18.04 AWS_ACCESS_KEY=instanceprofile CACHE=false DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` release' sh 'make RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=20.04 RELEASE_DOCKER=true release' } } From a3503a64e49612e93af0b449363a632de3b72b5c Mon Sep 17 00:00:00 2001 From: VicYP <31416378@qq.com> Date: Thu, 20 Oct 2022 13:24:59 +0000 Subject: [PATCH 64/74] chore(release): update release scripts Signed-off-by: VicYP <31416378@qq.com> --- scripts/make-final-release | 204 ------------------- scripts/{make-patch-release => make-release} | 119 +++++++---- scripts/{common.sh => release-lib.sh} | 74 ++++--- 3 files changed, 118 insertions(+), 279 deletions(-) delete mode 100755 scripts/make-final-release rename scripts/{make-patch-release => make-release} (71%) rename scripts/{common.sh => release-lib.sh} (88%) diff --git a/scripts/make-final-release b/scripts/make-final-release deleted file mode 100755 index 9b5cd4946c7e..000000000000 --- a/scripts/make-final-release +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env bash - -source "$(dirname "$0")/common.sh" -check_requirements - -#------------------------------------------------------------------------------- -function usage() { - echo "Make a Kong patch release using this script:" - echo "" - echo "Usage:" - if [ "$version" = "" ] - then - echo " List executed steps for a given release" - echo " $0 $version $1 $3" - echo - fi - c=1 - step "check_milestone" "ensure all PRs marked on the release milestone are 100% merged" - step "check_dependencies" "ensure all kong dependencies are bumped in the rockspec" - step "check_perf" "ensure performance tests were executed" - step "check_upgrade_tests" "ensure upgrade tests were executed" - step "check_changelog" "ensure changelog was written in pre-release and is ready for final" - step "check_upgrade" "ensure upgrade.md was updated in pre-release and is ready for final" - step "version_bump" "bump and commit the version number" - step "submit_release_pr" "push and submit a release PR" - step "merge" "merge, tag and sign the release" - step "approve_docker" "humans review and approve machine PR to docker-kong repo" - step "merge_docker" "merge, tag and sign Kong's docker-kong PR" - step "submit_docker" "submit a PR to docker-library/official-images" - step "merge_homebrew" "humans approve and merge machine PR to homebrew-kong" - step "upload_rock" "upload to LuaRocks" "" - step "merge_vagrant" "humans approve and merge machine PR to kong-vagrant" - step "merge_pongo" "humans approve and merge machine PR to kong-pongo" - step "announce" "Get announcement messages for Kong Nation and Slack #general" - exit 0 -} - - -#------------------------------------------------------------------------------- -# Default help -#------------------------------------------------------------------------------- - -if [ "$1" = "-h" ] || [ "$1" = "--help" ] || ! [ "$1" ] -then - version="" - usage "$@" -fi - -#------------------------------------------------------------------------------- -# Variables -#------------------------------------------------------------------------------- - -version="$1" -step="$2" - -major=${version%%.*} -rest=${version#*.} -minor=${rest%%.*} -patch=${rest##*.} -rockspec="kong-$version-0.rockspec" -branch="release/$version" -base="release/$major.$minor.x" - -if ! [[ "$version" =~ ^[0-9]+.[0-9]+.[0-9]$ ]] -then - die "first argument must be a version in x.y.z format" -fi - -if [ "$step" = "" ] -then - usage "$@" -fi - -EDITOR="${EDITOR-$VISUAL}" - -case "$step" in - check_milestone) check_milestone ;; - check_dependencies) check_dependencies ;; - - #--------------------------------------------------------------------------- - check_perf) - CONFIRM "Ensure Kong performance tests were performed. At minimum that requires running the https://github.com/Kong/kong/actions/workflows/perf.yml on the release branch and on the previous release, and compare the results. It can involve more custom tests. If everything looks all right, press Enter to continue or Ctrl+C to quit" - SUCCESS "Proceeding." - ;; - - #--------------------------------------------------------------------------- - check_upgrade_tests) - CONFIRM "Ensure Kong upgrade tests were performed. Current upgrade tests are https://github.com/Kong/kong-upgrade-tests. There should be tests on every release that has migrations, and no stoppers should appear. If everything looks all right, press Enter to continue or Ctrl+C to quit" - SUCCESS "Proceeding." - ;; - - #--------------------------------------------------------------------------- - check_changelog) - echo "Ensure changelog contains all the changes needed the final. Press 'y' to open the CHANGELOG or Ctrl+C to quit" - read - if [ "$REPLY" = "y" ] - then - $EDITOR CHANGELOG.md - fi - - CONFIRM "If everything looks all right, press Enter to continue" - SUCCESS "CHANGELOG is ready. Proceeding!" - ;; - - #--------------------------------------------------------------------------- - check_upgrade) - echo "Ensure UPGRADE.md was written in pre-release and is ready for the final. Press 'y' to open UPGRADE.md or Ctrl+C to quit" - read - if [ "$REPLY" = "y" ] - then - $EDITOR UPGRADE.md - fi - - CONFIRM "If everything looks all right, press Enter to continue" - SUCCESS "UPGRADE.md is ready. Proceeding!" - ;; - - #--------------------------------------------------------------------------- - version_bump) - sed -i.bak 's/major = [0-9]*/major = '$major'/' kong/meta.lua - sed -i.bak 's/minor = [0-9]*/minor = '$minor'/' kong/meta.lua - sed -i.bak 's/patch = [0-9]*/patch = '$patch'/' kong/meta.lua - - if ! grep -q "\-\-suffix" kong/meta.lua; then - sed -i.bak 's/suffix =/--suffix = /' kong/meta.lua - fi - - git add kong/meta.lua - - if ! [ -f "$rockspec" ] - then - git mv kong-*-0.rockspec "$rockspec" - sed -i.bak 's/^version = ".*"/version = "'$version'-0"/' "$rockspec" - sed -i.bak 's/^ tag = ".*"/ tag = "'$version'"/' "$rockspec" - fi - - git status - git diff - - CONFIRM "If everything looks all right, press Enter to make the release commit" \ - "or Ctrl-C to cancel." - - git add $rockspec - - git commit -m "release: $version" - git log -n 1 - - SUCCESS "Version bump for the release is now committed locally." \ - "You are ready to run the next step:" \ - " $0 $version submit_release_pr" - ;; - - #--------------------------------------------------------------------------- - submit_release_pr) submit_release_pr "$base" "$version" merge docs_pr;; - - #--------------------------------------------------------------------------- - merge) - CONFIRM "Press Enter to merge the PR into master and push the tag and Github release" \ - "or Ctrl-C to cancel." - - set -e - git checkout "$base" - git pull - git tag -s "$version" -m "$version" - git push origin "$version" - - make_github_release_file - - hub release create -F release-$version.txt "$version" - rm -f release-$version.txt - - git checkout master - git pull - git merge "$base" - git push - - SUCCESS "Make sure the packages are built and available on download.konghq.com" \ - "before continuing to the following steps." \ - - "They should be visible on https://internal.builds.konghq.com/job/kong/view/tags/. " \ - "An recurrent task checks for new releases every 15 minutes on the server. " \ - "If needed, the link 'Scan Multibranch Pipeline Now' will scan on-demmand. It can be used " \ - "to attempt to rebuild, if there was an error." - - "As the packages are built, you may run the following steps in parallel:" \ - "* 'upload_luarock'" \ - "* 'merge_homebrew'" \ - "* 'merge_vagrant'" \ - "* 'merge_pongo'" \ - "* 'approve_docker', then 'merge_docker', then 'submit_docker'" - ;; - #--------------------------------------------------------------------------- - approve_docker) approve_docker ;; - merge_docker) merge_docker "$branch" "$version" ;; - submit_docker) submit_docker "$version";; - merge_homebrew) merge_homebrew ;; - merge_pongo) merge_pongo ;; - merge_vagrant) merge_vagrant ;; - upload_luarock) upload_luarock "$rockspec" "$3" ;; - announce) announce "$major" "$minor" "$patch" ;; - *) - die "Unknown step!" - ;; -esac diff --git a/scripts/make-patch-release b/scripts/make-release similarity index 71% rename from scripts/make-patch-release rename to scripts/make-release index cd82e12c1157..be51fb753e40 100755 --- a/scripts/make-patch-release +++ b/scripts/make-release @@ -1,22 +1,25 @@ #!/usr/bin/env bash -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/release-lib.sh" check_requirements #------------------------------------------------------------------------------- function usage() { - echo "Make a Kong patch release using this script:" + echo "Make a Kong release using this script:" echo "" echo "Usage:" + echo if [ "$version" = "" ] then echo " List executed steps for a given release" echo " $0 $version $1 $3" echo fi - c=1 - step "check_milestone" "ensure all PRs marked on the release milestone are 100% merged" - step "check_dependencies" "ensure all kong dependencies are bumped in the rockspec" + if ! [[ $prerelease =~ alpha ]] + then + step "check_milestone" "ensure all PRs marked on the release milestone are 100% merged" + step "check_dependencies" "ensure all kong dependencies are bumped in the rockspec" + fi step "create" "create the branch" step "write_changelog" "prepare the changelog" step "commit_changelog" "commit the changelog" @@ -24,8 +27,15 @@ function usage() { step "update_admin_api_def" "update Admin API definition" step "version_bump" "bump and commit the version number" step "submit_release_pr" "push and submit a release PR" - step "docs_pr" "push and submit a docs.konghq.com PR for the release" step "merge" "merge, tag and sign the release" + + if [[ $prerelease =~ alpha ]] + then + echo -e "${red}${bold}Check whether you need any of the following steps for this alpha release${nocolor}" + echo + fi + + step "docs_pr" "push and submit a docs.konghq.com PR for the release" step "approve_docker" "get humans to review and approve machine-provided pull request at docker-kong repo" step "merge_docker" "merge, tag and sign Kong's docker-kong PR" step "submit_docker" "submit a PR to docker-library/official-images" @@ -38,10 +48,10 @@ function usage() { #---------------------------------------------------------------------------------------- # The following steps are run by Jenkins, they should not be run by a human # However we need to keep them here because Jenkins expects them to be here - step "update_docker" "(ran by Jenkins now) update and submit a PR to Kong's docker-kong repo" - step "homebrew" "(ran by Jenkins now) bump version and submit a PR to homebrew-kong" - step "vagrant" "(ran by Jenkins now) bump version and submit a PR to kong-vagrant" - step "pongo" "(ran by Jenkins now) bump version and submit a PR to kong-pongo" + step "update_docker" "(verify that Jenkins ran) update and submit a PR to Kong's docker-kong repo" + step "homebrew" "(verify that Jenkins ran) bump version and submit a PR to homebrew-kong" + step "vagrant" "(verify that Jenkins ran) bump version and submit a PR to kong-vagrant" + step "pongo" "(verify that Jenkins ran) bump version and submit a PR to kong-pongo" exit 0 } @@ -64,18 +74,20 @@ fi version="$1" step="$2" -major=${version%%.*} +if ! [[ "$version" =~ ^([0-9]+)\.([0-9]+)\.([0-9])-?((alpha|beta|rc)\.[0-9]+)?$ ]] +then + die "first argument must be a version in x.y.z format with optional -(alpha|beta|rc).\d suffix" +fi + +major=${BASH_REMATCH[1]} +minor=${BASH_REMATCH[2]} +patch=${BASH_REMATCH[3]} +prerelease=${BASH_REMATCH[4]} rest=${version#*.} -minor=${rest%%.*} -patch=${rest##*.} -rockspec="kong-$version-0.rockspec" +rockspec="kong-$major.$minor.$patch$prerelease-0.rockspec" branch="release/$version" base="release/$major.$minor.x" -if ! [[ "$version" =~ ^[0-9]+.[0-9]+.[0-9]$ ]] -then - die "first argument must be a version in x.y.z format" -fi if [ "$step" = "" ] then @@ -91,20 +103,26 @@ case "$step" in #--------------------------------------------------------------------------- create) - if [ $(git status --untracked-files=no --porcelain | wc -l) != "0" ] + if [ $(git status --untracked-files=no --porcelain | wc -l) != 0 ] then die "Local tree is not clean, please commit or stash before running this." fi set -e - git checkout "$base" + if ! git rev-parse --verify --quiet origin/$base + then + git branch "$base" + git checkout "$base" + git push -u origin "$base" + else + git checkout "$base" + fi + git pull git checkout -B "$branch" SUCCESS "Release branch was created locally." \ "Ensure to cherry-pick all required changes into $branch." \ - "And proceed to the next step:" \ - " $0 $version cherry_pick" ;; #--------------------------------------------------------------------------- write_changelog) write_changelog "$version" ;; @@ -114,16 +132,20 @@ case "$step" in #--------------------------------------------------------------------------- version_bump) - if ! grep -q "patch = $patch" kong/meta.lua + sed -i.bak 's/major = [0-9]*/major = '$major'/' kong/meta.lua + sed -i.bak 's/minor = [0-9]*/minor = '$minor'/' kong/meta.lua + sed -i.bak 's/patch = [0-9]*/patch = '$patch'/' kong/meta.lua + if [ "$prerelease" != "" ] then - sed -i.bak 's/patch = [0-9]*/patch = '$patch'/' kong/meta.lua - git add kong/meta.lua + sed -i.bak 's/--.*suffix.*$/suffix = "'$prerelease'"/' kong/meta.lua fi + git add kong/meta.lua + if ! [ -f "$rockspec" ] then git mv kong-*-0.rockspec "$rockspec" - sed -i.bak 's/^version = ".*"/version = "'$version'-0"/' "$rockspec" - sed -i.bak 's/^ tag = ".*"/ tag = "'$version'"/' "$rockspec" + sed -i.bak 's/^version = ".*"/version = "'"$major.$minor.$patch$prerelease"'-0"/' "$rockspec" + sed -i.bak 's/^ tag = ".*"/ tag = "'"$version"'"/' "$rockspec" fi git status @@ -132,9 +154,9 @@ case "$step" in CONFIRM "If everything looks all right, press Enter to make the release commit" \ "or Ctrl-C to cancel." - git add $rockspec + git add "$rockspec" - git commit -m "release: $version" + git commit --allow-empty -m "release: $version" git log -n 1 SUCCESS "Version bump for the release is now committed locally." \ @@ -143,27 +165,36 @@ case "$step" in ;; #--------------------------------------------------------------------------- - submit_release_pr) submit_release_pr "$branch" "$version" ;; + submit_release_pr) submit_release_pr "$base" "$branch" "$version" "$prerelease" ;; #--------------------------------------------------------------------------- merge) - CONFIRM "Press Enter to merge the PR into master and push the tag and Github release" \ + CONFIRM "Press Enter to merge the PR into $base and push the tag and Github release" \ "or Ctrl-C to cancel." set -e - git checkout "$branch" - git pull - git checkout master + git checkout "$base" git pull git merge "$branch" git push git tag -s "$version" -m "$version" git push origin "$version" + git branch -d "$branch" + git fetch --prune + if git rev-parse --verify -q "origin/$branch" > /dev/null + then + git push origin :"$branch" + fi make_github_release_file - hub release create -F release-$version.txt "$version" - rm -f release-$version.txt + if [ "$prerelease" != "" ] + then + prerelease_option=--prerelease + fi + + hub release create $prerelease_option -F "release-$version.txt" "$version" + rm -f "release-$version.txt" SUCCESS "Make sure the packages are built and available on download.konghq.com" \ "before continuing to the following steps." \ @@ -185,7 +216,7 @@ case "$step" in approve_docker) approve_docker ;; merge_docker) merge_docker "$branch" "$version" ;; submit_docker) submit_docker "$version";; - merge_homebrew)merge_homebrew ;; + merge_homebrew) merge_homebrew ;; merge_pongo) merge_pongo ;; merge_vagrant) merge_vagrant ;; upload_luarock) upload_luarock "$rockspec" "$3" ;; @@ -206,7 +237,7 @@ case "$step" in cd ../homebrew-kong else cd .. - git clone git@github.com:Kong/homebrew-kong.git + git clone git@github.com:$GITHUB_ORG/homebrew-kong.git cd homebrew-kong fi @@ -217,12 +248,12 @@ case "$step" in git diff - CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:Kong/homebrew-kong" \ + CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:$GITHUB_ORG/homebrew-kong" \ "or Ctrl-C to cancel." set -e git add Formula/kong.rb - git commit -m "chore(kong) bump kong to $version" + git commit -m "chore(kong): bump kong to $version" git push --set-upstream origin "$branch" hub pull-request -b master -h "$branch" -m "Release: $version" @@ -236,7 +267,7 @@ case "$step" in cd ../kong-pongo else cd .. - git clone git@github.com:Kong/kong-pongo.git + git clone git@github.com:$GITHUB_ORG/kong-pongo.git cd kong-pongo fi @@ -255,7 +286,7 @@ case "$step" in cd ../kong-vagrant else cd .. - git clone git@github.com:Kong/kong-vagrant.git + git clone git@github.com:$GITHUB_ORG/kong-vagrant.git cd kong-vagrant fi @@ -266,12 +297,12 @@ case "$step" in git diff - CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:Kong/kong-vagrant" \ + CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:$GITHUB_ORG/kong-vagrant" \ "or Ctrl-C to cancel." set -e git add README.md Vagrantfile - git commit -m "chore(*) bump Kong to $version" + git commit -m "chore(*): bump Kong to $version" git push --set-upstream origin "$branch" hub pull-request -b master -h "$branch" -m "Release: $version" diff --git a/scripts/common.sh b/scripts/release-lib.sh similarity index 88% rename from scripts/common.sh rename to scripts/release-lib.sh index ede58fe4e677..6dab94100a20 100644 --- a/scripts/common.sh +++ b/scripts/release-lib.sh @@ -6,6 +6,8 @@ cyan="\033[0;36m" bold="\033[1m" nocolor="\033[0m" +GITHUB_ORG=${GITHUB_ORG:-Kong} + scripts_folder=$(dirname "$0") browser="echo" @@ -52,8 +54,8 @@ function yesno() { #------------------------------------------------------------------------------- function check_milestone() { - if yesno "Visit the milestones page (https://github.com/Kong/kong/milestone) and ensure PRs are merged. Press 'y' to open it or Ctrl-C to quit"; then - $browser https://github.com/Kong/kong/milestones + if yesno "Visit the milestones page (https://github.com/$GITHUB_ORG/kong/milestone) and ensure PRs are merged. Press 'y' to open it or Ctrl-C to quit"; then + $browser https://github.com/$GITHUB_ORG/kong/milestones fi CONFIRM "If everything looks all right, press Enter to continue" @@ -106,7 +108,7 @@ function commit_changelog() { set -e git add CHANGELOG.md - git commit -m "docs(changelog) add $version changes" + git commit -m "docs(changelog): add $version changes" git log -n 1 SUCCESS "The changelog is now committed locally." \ @@ -125,7 +127,7 @@ function update_copyright() { git add COPYRIGHT - git commit -m "docs(COPYRIGHT) update copyright for $version" + git commit -m "docs(COPYRIGHT): update copyright for $version" git log -n 1 SUCCESS "The COPYRIGHT file is updated locally." \ @@ -144,7 +146,7 @@ function update_admin_api_def() { git add kong-admin-api.yml - git commit -m "docs(kong-admin-api.yml) update Admin API definition for $1" + git commit -m "docs(kong-admin-api.yml): update Admin API definition for $1" git log -n 1 SUCCESS "The kong-admin-api.yml file is updated locally." \ @@ -202,7 +204,7 @@ $version - [Docker Image](https://hub.docker.com/_/kong/) Links: -- [$version Changelog](https://github.com/Kong/kong/blob/$version/CHANGELOG.md#$versionlink) +- [$version Changelog](https://github.com/$GITHUB_ORG/kong/blob/$version/CHANGELOG.md#$versionlink) EOF } @@ -315,26 +317,31 @@ function prepare_changelog() { #------------------------------------------------------------------------------- function announce() { - local version="$1.$2.$3" + local version="$1.$2.$3" + + if [ "$3" != "0" ] + then + patch_release_disclaimer="As a patch release, it only contains bug fixes; no new features and no breaking changes." + fi cat < Date: Thu, 20 Oct 2022 13:25:59 +0000 Subject: [PATCH 65/74] release: 2.8.2 --- kong-2.8.1-0.rockspec => kong-2.8.2-0.rockspec | 4 ++-- kong/meta.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename kong-2.8.1-0.rockspec => kong-2.8.2-0.rockspec (99%) diff --git a/kong-2.8.1-0.rockspec b/kong-2.8.2-0.rockspec similarity index 99% rename from kong-2.8.1-0.rockspec rename to kong-2.8.2-0.rockspec index e8aaafc0d19f..c94078b52d20 100644 --- a/kong-2.8.1-0.rockspec +++ b/kong-2.8.2-0.rockspec @@ -1,10 +1,10 @@ package = "kong" -version = "2.8.1-0" +version = "2.8.2-0" rockspec_format = "3.0" supported_platforms = {"linux", "macosx"} source = { url = "https://github.com/Kong/kong.git", - tag = "2.8.1" + tag = "2.8.2" } description = { summary = "Kong is a scalable and customizable API Management Layer built on top of Nginx.", diff --git a/kong/meta.lua b/kong/meta.lua index 0a82752f9a18..c9059c0b484e 100644 --- a/kong/meta.lua +++ b/kong/meta.lua @@ -1,7 +1,7 @@ local version = setmetatable({ major = 2, minor = 8, - patch = 1, + patch = 2, --suffix = "rc.1" }, { -- our Makefile during certain releases adjusts this line. Any changes to From acac7954e814473b0f0dd94197c96a1034bf2dd1 Mon Sep 17 00:00:00 2001 From: catbro666 <38037704+catbro666@users.noreply.github.com> Date: Thu, 20 Oct 2022 18:19:47 +0800 Subject: [PATCH 66/74] fix(request-transformer): preserves empty json arrays after decoding and re-encoding (#9571) backport FTI-4205 --- kong/plugins/request-transformer/access.lua | 13 ++- .../36-request-transformer/02-access_spec.lua | 90 +++++++++++++++++++ 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/kong/plugins/request-transformer/access.lua b/kong/plugins/request-transformer/access.lua index f4478131669d..4622240c16b8 100644 --- a/kong/plugins/request-transformer/access.lua +++ b/kong/plugins/request-transformer/access.lua @@ -1,5 +1,5 @@ local multipart = require "multipart" -local cjson = require "cjson" +local cjson = require("cjson.safe").new() local pl_template = require "pl.template" local pl_tablex = require "pl.tablex" @@ -19,7 +19,6 @@ local encode_args = ngx.encode_args local ngx_decode_args = ngx.decode_args local type = type local str_find = string.find -local pcall = pcall local pairs = pairs local error = error local rawset = rawset @@ -42,12 +41,12 @@ local compile_opts = { } +cjson.decode_array_with_array_mt(true) + + local function parse_json(body) if body then - local status, res = pcall(cjson.decode, body) - if status then - return res - end + return cjson.decode(body) end end @@ -344,7 +343,7 @@ local function transform_json_body(conf, body, content_length) end if removed or renamed or replaced or added or appended then - return true, cjson.encode(parameters) + return true, assert(cjson.encode(parameters)) end end diff --git a/spec/03-plugins/36-request-transformer/02-access_spec.lua b/spec/03-plugins/36-request-transformer/02-access_spec.lua index 6e2bcfe5f29a..9cddc53cce36 100644 --- a/spec/03-plugins/36-request-transformer/02-access_spec.lua +++ b/spec/03-plugins/36-request-transformer/02-access_spec.lua @@ -679,6 +679,21 @@ describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function() local value = assert.request(r).has.queryparam("q2") assert.equals("v2", value) end) + it("preserves empty json array", function() + local r = assert(client:send { + method = "POST", + path = "/request", + body = [[{"emptyarray":[]}]], + headers = { + host = "test4.test", + ["content-type"] = "application/json" + } + }) + assert.response(r).has.status(200) + assert.response(r).has.jsonbody() + local json = assert.request(r).has.jsonbody() + assert.equals("{\"emptyarray\":[]}", json.data) + end) end) describe("rename", function() @@ -827,6 +842,21 @@ describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function() local value2 = assert.request(r).has.queryparam("nottorename") assert.equals("true", value2) end) + it("preserves empty json array", function() + local r = assert(client:send { + method = "POST", + path = "/request", + body = [[{"emptyarray":[]}]], + headers = { + host = "test9.test", + ["content-type"] = "application/json" + } + }) + assert.response(r).has.status(200) + assert.response(r).has.jsonbody() + local json = assert.request(r).has.jsonbody() + assert.equals("{\"emptyarray\":[]}", json.data) + end) end) describe("rename", function() @@ -1180,6 +1210,21 @@ describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function() local value = assert.request(r).has.queryparam("q2") assert.equals("v2", value) end) + it("preserves empty json array", function() + local r = assert(client:send { + method = "POST", + path = "/request", + body = [[{"emptyarray":[], "p1":"v"}]], + headers = { + host = "test5.test", + ["content-type"] = "application/json" + } + }) + assert.response(r).has.status(200) + assert.response(r).has.jsonbody() + local json = assert.request(r).has.jsonbody() + assert.is_truthy(string.find(json.data, "\"emptyarray\":[]", 1, true)) + end) pending("escape UTF-8 characters when replacing upstream path - enable after Kong 2.4", function() local r = assert(client:send { @@ -1399,6 +1444,21 @@ describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function() local value = assert.has.header("host", json) assert.equals("test2.test", value) end) + it("preserves empty json array", function() + local r = assert(client:send { + method = "POST", + path = "/request", + body = [[{"emptyarray":[]}]], + headers = { + host = "test1.test", + ["content-type"] = "application/json" + } + }) + assert.response(r).has.status(200) + assert.response(r).has.jsonbody() + local json = assert.request(r).has.jsonbody() + assert.is_truthy(string.find(json.data, "\"emptyarray\":[]", 1, true)) + end) end) describe("append ", function() @@ -1555,6 +1615,21 @@ describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function() local value = assert.request(r).has.formparam("p1") assert.equals("This should not change", value) end) + it("preserves empty json array", function() + local r = assert(client:send { + method = "POST", + path = "/request", + body = [[{"emptyarray":[]}]], + headers = { + host = "test6.test", + ["content-type"] = "application/json" + } + }) + assert.response(r).has.status(200) + assert.response(r).has.jsonbody() + local json = assert.request(r).has.jsonbody() + assert.is_truthy(string.find(json.data, "\"emptyarray\":[]", 1, true)) + end) end) describe("remove, replace, add and append ", function() @@ -1959,6 +2034,21 @@ describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function() local value = assert.request(r).has.queryparam("q1") assert.equals("20", value) end) + it("preserves empty json array", function() + local r = assert(client:send { + method = "POST", + path = "/request", + body = [[{"emptyarray":[]}]], + headers = { + host = "test3.test", + ["content-type"] = "application/json" + } + }) + assert.response(r).has.status(200) + assert.response(r).has.jsonbody() + local json = assert.request(r).has.jsonbody() + assert.is_truthy(string.find(json.data, "\"emptyarray\":[]", 1, true)) + end) end) From 534398a898304c3ccac7310231573dfcbea69df3 Mon Sep 17 00:00:00 2001 From: catbro666 <38037704+catbro666@users.noreply.github.com> Date: Thu, 20 Oct 2022 18:20:42 +0800 Subject: [PATCH 67/74] fix(http-log) internal error during validating the schema if `http_endpoint` contains userinfo but `headers` is empty (#9574) The missing field will be filled with an appropriate default value in function `handle_missing_field`. When no explicit defualt value is set and the field isn't nilable and required, then its default value will be ngx.null, which is a lightuserdata with the point NULL. FTI-4173 --- kong/plugins/http-log/schema.lua | 2 +- spec/03-plugins/03-http-log/02-schema_spec.lua | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/kong/plugins/http-log/schema.lua b/kong/plugins/http-log/schema.lua index c01f6cbe226b..f143dcb062da 100644 --- a/kong/plugins/http-log/schema.lua +++ b/kong/plugins/http-log/schema.lua @@ -40,7 +40,7 @@ return { custom_validator = function(config) -- check no double userinfo + authorization header local parsed_url = url.parse(config.http_endpoint) - if parsed_url.userinfo and config.headers then + if parsed_url.userinfo and config.headers and config.headers ~= ngx.null then for hname, hvalue in pairs(config.headers) do if hname:lower() == "authorization" then return false, "specifying both an 'Authorization' header and user info in 'http_endpoint' is not allowed" diff --git a/spec/03-plugins/03-http-log/02-schema_spec.lua b/spec/03-plugins/03-http-log/02-schema_spec.lua index 71f7e6d21a84..62a693a01dae 100644 --- a/spec/03-plugins/03-http-log/02-schema_spec.lua +++ b/spec/03-plugins/03-http-log/02-schema_spec.lua @@ -23,6 +23,14 @@ describe(PLUGIN_NAME .. ": (schema)", function() assert.is_truthy(ok) end) + it("accepts empty headers with username/password in the http_endpoint", function() + local ok, err = validate({ + http_endpoint = "http://bob:password@myservice.com/path", + }) + assert.is_nil(err) + assert.is_truthy(ok) + end) + it("accepts custom fields by lua", function() local ok, err = validate({ http_endpoint = "http://myservice.com/path", From ea777507ef11e37065000be865cc4898661d0d00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20H=C3=BCbner?= Date: Thu, 20 Oct 2022 15:45:25 +0200 Subject: [PATCH 68/74] chore(release): remove a leftover old release script --- scripts/make-prerelease-release | 173 -------------------------------- 1 file changed, 173 deletions(-) delete mode 100755 scripts/make-prerelease-release diff --git a/scripts/make-prerelease-release b/scripts/make-prerelease-release deleted file mode 100755 index 5b7ee6c1b04a..000000000000 --- a/scripts/make-prerelease-release +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env bash - -cyan="\033[0;36m" -nocolor="\033[0m" - -source "$(dirname "$0")/common.sh" -check_requirements - -#------------------------------------------------------------------------------- -function usage() { - echo - echo -e "Make a Kong ${cyan}alpha|beta|rc${nocolor} release using this script:" - echo "" - echo "Usage:" - if [ "$version" = "" ] - then - echo " List executed steps for a given release" - echo " $0 $version $1 $3" - echo - fi - c=1 - step "switch" "switch or create to the release branch" - step "write_changelog" "prepare the changelog" - step "commit_changelog" "commit the changelog" - step "update_copyright" "update copyright file" - step "update_admin_api_def" "update Admin API definition" - step "version_bump" "bump and commit the version number" - step "submit" "push and submit a release PR" - step "tag" "tag and sign the release candidate" - if [ "$beta" == true ] - then - step "docs_pr" "push and submit a docs.konghq.com PR for the release" - step "approve_docker" "update and submit a PR to Kong's docker-kong repo" - step "merge_docker" "merge, tag and sign Kong's docker-kong PR" - step "merge_homebrew" "humans approve and merge machine PR to homebrew-kong" - step "merge_pongo" "humans approve and merge machine PR to kong-pongo" - fi - exit 0 -} - -#------------------------------------------------------------------------------- -# Default help -#------------------------------------------------------------------------------- - -if [ "$1" = "-h" ] || [ "$1" = "--help" ] || ! [ "$1" ] -then - version="" - usage "$@" -fi - - -#------------------------------------------------------------------------------- -# Variables -#------------------------------------------------------------------------------- - -version="${1:-0.0.0-alpha.0}" -step="$2" - - -xyzversion="${version%%-*}" -major=${xyzversion%%.*} -rest=${xyzversion#*.} -minor=${rest%%.*} -patch=${rest##*.} -prerelease=${version##*-} -rockspec="kong-$xyzversion$prerelease-0.rockspec" -branch="release/$xyzversion" -base="release/$major.$minor.x" - -beta=false -if [[ $version == *"beta"* ]]; then - beta=true -fi - -if ! [[ "$version" =~ ^[0-9]+.[0-9]+.0-(alpha|beta|rc)\.[0-9]$ ]] -then - die "first argument must be a version in x.y.z-(alpha|beta|rc).n format" -fi - -if [ "$step" = "" ] -then - usage "$@" -fi - -EDITOR="${EDITOR-$VISUAL}" - -case "$step" in - #--------------------------------------------------------------------------- - switch) - set -e - git pull - git checkout "$base" || true - git checkout -B "$base" || true - - SUCCESS "Release branch is switched locally." \ - "You are ready to run the next step:" \ - " $0 $version write_changelog" - ;; - #--------------------------------------------------------------------------- - write_changelog) write_changelog "$version" ;; - commit_changelog) commit_changelog "$version" ;; - update_copyright) update_copyright "$version" ;; - update_admin_api_def) update_admin_api_def "$version" ;; - - #--------------------------------------------------------------------------- - version_bump) - sed -i.bak 's/major = [0-9]*/major = '$major'/' kong/meta.lua - sed -i.bak 's/minor = [0-9]*/minor = '$minor'/' kong/meta.lua - sed -i.bak 's/patch = [0-9]*/patch = '$patch'/' kong/meta.lua - sed -i.bak 's/--.*suffix.*$/suffix = "'$prerelease'"/' kong/meta.lua - - if ! [ -f "$rockspec" ] - then - old_rockspec=$(ls kong-*-0.rockspec | head -n 1) - sed -i.bak 's/^version = ".*"/version = "'$xyzversion''$prerelease'-0"/' "$old_rockspec" - sed -i.bak 's/^ tag = ".*"/ tag = "'$version'"/' "$old_rockspec" - fi - - git diff kong/meta.lua $old_rockspec - - CONFIRM "If everything looks all right, press Enter to make the release commit" \ - "or Ctrl-C to cancel." - - git mv "$old_rockspec" "$rockspec" - git add kong/meta.lua - git add $rockspec - - git commit -m "release: $version" - git log -n 1 - - SUCCESS "Version bump for the release is now committed locally." \ - "You are ready to run the next step:" \ - " $0 $version submit" - ;; - #--------------------------------------------------------------------------- - submit_release_pr) submit_release_pr "$base" "$version" ;; - - #--------------------------------------------------------------------------- - tag) - CONFIRM "Press Enter to tag the prerelease (it is not actually merged)" \ - "or Ctrl-C to cancel." - - set -e - git checkout "$base" - git pull - git tag -s "$version" -m "$version" - git push origin "$version" - - make_github_release_file - - hub release create --prerelease -F release-$version.txt "$version" - rm -f release-$version.txt - - SUCCESS "While the packages are being built continue to" \ - " $0 $version docs_pr" \ - "After the packages are built continue to" \ - "Once they are built, you may run the following steps in parallel:" \ - "* 'approve_docker', then 'merge_docker'" - "* 'merge_homebrew'" \ - "* 'merge_pongo'" - ;; - #--------------------------------------------------------------------------- - docs_pr) docs_pr "$branch" ;; - approve_docker) approve_docker;; - merge_docker) merge_docker "$branch" "$version" ;; - merge_homebrew) merge_homebrew ;; - merge_pongo) merge_pongo ;; - #--------------------------------------------------------------------------- - *) - die "Unknown step!" - ;; -esac - From 3869ddca742411538b046dcaf209a560e12a0a9c Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 2 Nov 2022 17:08:07 +0000 Subject: [PATCH 69/74] docs(changelog): add 2.8.3 changes --- CHANGELOG.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aba8ca680944..23c82f399840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Table of Contents +- [2.8.3](#283) - [2.8.2](#282) - [2.8.1](#281) - [2.8.0](#280) @@ -64,14 +65,17 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) -## Unreleased + +## [2.8.3] + +> Released 2022/11/02 ### Fixes -#### Admin API +##### CLI -- Increase the maximum request argument number from 100 to 1000, and return 400 error if request parameters reach the limitation to avoid being truncated. - [#9510](https://github.com/Kong/kong/pull/9510) +- Fixed a packaging problem affecting a subset of releases where the `kong version` + command was incorrect ## [2.8.2] @@ -6878,6 +6882,8 @@ First version running with Cassandra. [Back to TOC](#table-of-contents) +[2.8.3]: https://github.com/Kong/kong/compare/2.8.2...2.8.3 +[2.8.2]: https://github.com/Kong/kong/compare/2.8.1...2.8.2 [2.8.1]: https://github.com/Kong/kong/compare/2.8.0...2.8.1 [2.8.0]: https://github.com/Kong/kong/compare/2.7.0...2.8.0 [2.7.1]: https://github.com/Kong/kong/compare/2.7.0...2.7.1 From e636d7c089cdfa42eec38fa987d8686dbbabd2be Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 2 Nov 2022 17:10:03 +0000 Subject: [PATCH 70/74] release: 2.8.3 --- kong-2.8.2-0.rockspec => kong-2.8.3-0.rockspec | 4 ++-- kong/meta.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename kong-2.8.2-0.rockspec => kong-2.8.3-0.rockspec (99%) diff --git a/kong-2.8.2-0.rockspec b/kong-2.8.3-0.rockspec similarity index 99% rename from kong-2.8.2-0.rockspec rename to kong-2.8.3-0.rockspec index c94078b52d20..7d6d0211bf28 100644 --- a/kong-2.8.2-0.rockspec +++ b/kong-2.8.3-0.rockspec @@ -1,10 +1,10 @@ package = "kong" -version = "2.8.2-0" +version = "2.8.3-0" rockspec_format = "3.0" supported_platforms = {"linux", "macosx"} source = { url = "https://github.com/Kong/kong.git", - tag = "2.8.2" + tag = "2.8.3" } description = { summary = "Kong is a scalable and customizable API Management Layer built on top of Nginx.", diff --git a/kong/meta.lua b/kong/meta.lua index c9059c0b484e..29484be5a4a6 100644 --- a/kong/meta.lua +++ b/kong/meta.lua @@ -1,7 +1,7 @@ local version = setmetatable({ major = 2, minor = 8, - patch = 2, + patch = 3, --suffix = "rc.1" }, { -- our Makefile during certain releases adjusts this line. Any changes to From 98eb6fba5daefe00bdb1ce0acb3158788d8b11d9 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 2 Nov 2022 17:15:40 +0000 Subject: [PATCH 71/74] chore(ci): build a test package on PR's to release branches --- Jenkinsfile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index e3092e8a0d9a..b4badb18eb6e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,6 +19,30 @@ pipeline { DEBUG = 0 } stages { + stage('Test The Package') { + agent { + node { + label 'bionic' + } + } + when { + anyOf { + changeRequest target: 'master' + changeRequest target: 'release/*' + } + } + environment { + KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" + KONG_SOURCE_LOCATION = "${env.WORKSPACE}" + GITHUB_SSH_KEY = credentials('github_bot_ssh_key') + } + steps { + sh './scripts/setup-ci.sh' + sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' + sh 'make setup-kong-build-tools' + sh 'cd ../kong-build-tools && make package-kong test' + } + } stage('Release Per Commit') { when { beforeAgent true From 567e61fb7b5c6664a915853160fbcf395d2bdb17 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 2 Nov 2022 17:22:34 +0000 Subject: [PATCH 72/74] Revert "chore(ci): build a test package on PR's to release branches" This reverts commit 98eb6fba5daefe00bdb1ce0acb3158788d8b11d9. --- Jenkinsfile | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index b4badb18eb6e..e3092e8a0d9a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,30 +19,6 @@ pipeline { DEBUG = 0 } stages { - stage('Test The Package') { - agent { - node { - label 'bionic' - } - } - when { - anyOf { - changeRequest target: 'master' - changeRequest target: 'release/*' - } - } - environment { - KONG_BUILD_TOOLS_LOCATION = "${env.WORKSPACE}/../kong-build-tools" - KONG_SOURCE_LOCATION = "${env.WORKSPACE}" - GITHUB_SSH_KEY = credentials('github_bot_ssh_key') - } - steps { - sh './scripts/setup-ci.sh' - sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true' - sh 'make setup-kong-build-tools' - sh 'cd ../kong-build-tools && make package-kong test' - } - } stage('Release Per Commit') { when { beforeAgent true From 6678daf0717863b943e3e7d33c3610b4d6b6aa2c Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 2 Nov 2022 18:05:25 +0000 Subject: [PATCH 73/74] docs(README.md): adjust the 2.8.3 readme --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23c82f399840..26d1478a4935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,11 @@ ### Fixes +##### Plugins + +- **HTTP Log**: fix internal error during validating the schema if http_endpoint contains + userinfo but headers is empty [#9574](https://github.com/Kong/kong/pull/9574) + ##### CLI - Fixed a packaging problem affecting a subset of releases where the `kong version` From 8e12c0a29ede4f8df6d127583a53d3a3b6d3dff9 Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Wed, 2 Nov 2022 18:31:37 +0000 Subject: [PATCH 74/74] Release: 2.8.3 (#9665) * docs(changelog): add 2.8.3 changes * release: 2.8.3 * chore(ci): build a test package on PR's to release branches * Revert "chore(ci): build a test package on PR's to release branches" This reverts commit 98eb6fba5daefe00bdb1ce0acb3158788d8b11d9. * docs(README.md): adjust the 2.8.3 readme --- CHANGELOG.md | 19 +++++++++++++++---- ...-2.8.2-0.rockspec => kong-2.8.3-0.rockspec | 4 ++-- kong/meta.lua | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) rename kong-2.8.2-0.rockspec => kong-2.8.3-0.rockspec (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index aba8ca680944..26d1478a4935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Table of Contents +- [2.8.3](#283) - [2.8.2](#282) - [2.8.1](#281) - [2.8.0](#280) @@ -64,14 +65,22 @@ - [0.10.0](#0100---20170307) - [0.9.9 and prior](#099---20170202) -## Unreleased + +## [2.8.3] + +> Released 2022/11/02 ### Fixes -#### Admin API +##### Plugins + +- **HTTP Log**: fix internal error during validating the schema if http_endpoint contains + userinfo but headers is empty [#9574](https://github.com/Kong/kong/pull/9574) + +##### CLI -- Increase the maximum request argument number from 100 to 1000, and return 400 error if request parameters reach the limitation to avoid being truncated. - [#9510](https://github.com/Kong/kong/pull/9510) +- Fixed a packaging problem affecting a subset of releases where the `kong version` + command was incorrect ## [2.8.2] @@ -6878,6 +6887,8 @@ First version running with Cassandra. [Back to TOC](#table-of-contents) +[2.8.3]: https://github.com/Kong/kong/compare/2.8.2...2.8.3 +[2.8.2]: https://github.com/Kong/kong/compare/2.8.1...2.8.2 [2.8.1]: https://github.com/Kong/kong/compare/2.8.0...2.8.1 [2.8.0]: https://github.com/Kong/kong/compare/2.7.0...2.8.0 [2.7.1]: https://github.com/Kong/kong/compare/2.7.0...2.7.1 diff --git a/kong-2.8.2-0.rockspec b/kong-2.8.3-0.rockspec similarity index 99% rename from kong-2.8.2-0.rockspec rename to kong-2.8.3-0.rockspec index c94078b52d20..7d6d0211bf28 100644 --- a/kong-2.8.2-0.rockspec +++ b/kong-2.8.3-0.rockspec @@ -1,10 +1,10 @@ package = "kong" -version = "2.8.2-0" +version = "2.8.3-0" rockspec_format = "3.0" supported_platforms = {"linux", "macosx"} source = { url = "https://github.com/Kong/kong.git", - tag = "2.8.2" + tag = "2.8.3" } description = { summary = "Kong is a scalable and customizable API Management Layer built on top of Nginx.", diff --git a/kong/meta.lua b/kong/meta.lua index c9059c0b484e..29484be5a4a6 100644 --- a/kong/meta.lua +++ b/kong/meta.lua @@ -1,7 +1,7 @@ local version = setmetatable({ major = 2, minor = 8, - patch = 2, + patch = 3, --suffix = "rc.1" }, { -- our Makefile during certain releases adjusts this line. Any changes to