From 73ae601b5cdc8579e0a18a721db1f92f943c121f Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Wed, 25 Oct 2023 16:47:53 +0200 Subject: [PATCH] fix(vault): make it possible to use vault references in declarative config (#11843) Warmup cache on `init` where we have Lua `coroutines` available so that it won't happen on `init_worker` where we don't have them (and cannot use e.g. lua-resty-http). See KAG-2620 and FTI-5080. Signed-off-by: Aapo Talvensaari * Update spec/02-integration/02-cmd/02-start_stop_spec.lua --------- Signed-off-by: Aapo Talvensaari Co-authored-by: Samuele Signed-off-by: Aapo Talvensaari --- .../unreleased/kong/vault-declarative.yml | 3 ++ kong/init.lua | 2 + kong/pdk/vault.lua | 25 ++++++++++++- .../02-cmd/02-start_stop_spec.lua | 37 ++++++++++++++++++- .../kong/vaults/mocksocket/init.lua | 37 +++++++++++++++++++ .../kong/vaults/mocksocket/schema.lua | 13 +++++++ 6 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 changelog/unreleased/kong/vault-declarative.yml create mode 100644 spec/fixtures/custom_vaults/kong/vaults/mocksocket/init.lua create mode 100644 spec/fixtures/custom_vaults/kong/vaults/mocksocket/schema.lua diff --git a/changelog/unreleased/kong/vault-declarative.yml b/changelog/unreleased/kong/vault-declarative.yml new file mode 100644 index 00000000000..9ae6d9b2208 --- /dev/null +++ b/changelog/unreleased/kong/vault-declarative.yml @@ -0,0 +1,3 @@ +message: Vault references can be used in Dbless mode in declarative config +type: bugfix +scope: Core diff --git a/kong/init.lua b/kong/init.lua index db22a18dfb6..945f588a743 100644 --- a/kong/init.lua +++ b/kong/init.lua @@ -651,6 +651,8 @@ function Kong.init() if not declarative_entities then error(err) end + + kong.vault.warmup(declarative_entities) end else diff --git a/kong/pdk/vault.lua b/kong/pdk/vault.lua index fedf459b291..442d7c6d839 100644 --- a/kong/pdk/vault.lua +++ b/kong/pdk/vault.lua @@ -1103,7 +1103,7 @@ local function new(self) -- We cannot retry, so let's just call the callback and return return callback(options) end - + local name = "vault.try:" .. calculate_hash(concat(references, ".")) local old_updated_at = RETRY_LRU:get(name) or 0 @@ -1481,6 +1481,29 @@ local function new(self) end + --- + -- Warmups vault caches from config. + -- + -- @local + -- @function kong.vault.warmup + function _VAULT.warmup(input) + for k, v in pairs(input) do + local kt = type(k) + if kt == "table" then + _VAULT.warmup(k) + elseif kt == "string" and is_reference(k) then + get(k) + end + local vt = type(v) + if vt == "table" then + _VAULT.warmup(v) + elseif vt == "string" and is_reference(v) then + get(v) + end + end + end + + return _VAULT end diff --git a/spec/02-integration/02-cmd/02-start_stop_spec.lua b/spec/02-integration/02-cmd/02-start_stop_spec.lua index 1f122e016d4..684d919b6e7 100644 --- a/spec/02-integration/02-cmd/02-start_stop_spec.lua +++ b/spec/02-integration/02-cmd/02-start_stop_spec.lua @@ -639,8 +639,43 @@ describe("kong start/stop #" .. strategy, function() assert.matches("in 'name': invalid value '@gobo': the only accepted ascii characters are alphanumerics or ., -, _, and ~", err, nil, true) assert.matches("in entry 2 of 'hosts': invalid hostname: \\\\99", err, nil, true) end) - end + it("dbless can reference secrets in declarative configuration", function() + local yaml_file = helpers.make_yaml_file [[ + _format_version: "3.0" + _transform: true + plugins: + - name: session + instance_name: session + config: + secret: "{vault://mocksocket/test}" + ]] + + finally(function() + os.remove(yaml_file) + end) + + helpers.setenv("KONG_LUA_PATH_OVERRIDE", "./spec/fixtures/custom_vaults/?.lua;./spec/fixtures/custom_vaults/?/init.lua;;") + helpers.get_db_utils(strategy, { + "vaults", + }, { + "session" + }, { + "mocksocket" + }) + + local ok, err = helpers.start_kong({ + database = "off", + declarative_config = yaml_file, + vaults = "mocksocket", + plugins = "session" + }) + + assert.truthy(ok) + assert.not_matches("error", err) + assert.logfile().has.no.line("[error]", true, 0) + end) + end end) describe("deprecated properties", function() diff --git a/spec/fixtures/custom_vaults/kong/vaults/mocksocket/init.lua b/spec/fixtures/custom_vaults/kong/vaults/mocksocket/init.lua new file mode 100644 index 00000000000..119fe23a761 --- /dev/null +++ b/spec/fixtures/custom_vaults/kong/vaults/mocksocket/init.lua @@ -0,0 +1,37 @@ +local env = require "kong.vaults.env" +local http = require "resty.luasocket.http" + + +local assert = assert +local getenv = os.getenv + + +local function init() + env.init() + assert(getenv("KONG_PROCESS_SECRETS") == nil, "KONG_PROCESS_SECRETS environment variable found") + assert(env.get({}, "KONG_PROCESS_SECRETS") == nil, "KONG_PROCESS_SECRETS environment variable found") +end + + +local function get(conf, resource, version) + local client, err = http.new() + if not client then + return nil, err + end + + client:set_timeouts(20000, 20000, 20000) + assert(client:request_uri("http://mockbin.org/headers", { + headers = { + Accept = "application/json", + }, + })) + + return env.get(conf, resource, version) +end + + +return { + VERSION = "1.0.0", + init = init, + get = get, +} diff --git a/spec/fixtures/custom_vaults/kong/vaults/mocksocket/schema.lua b/spec/fixtures/custom_vaults/kong/vaults/mocksocket/schema.lua new file mode 100644 index 00000000000..90e86d33c37 --- /dev/null +++ b/spec/fixtures/custom_vaults/kong/vaults/mocksocket/schema.lua @@ -0,0 +1,13 @@ +return { + name = "mocksocket", + fields = { + { + config = { + type = "record", + fields = { + { prefix = { type = "string", match = [[^[%a_][%a%d_]*$]] } }, + }, + }, + }, + }, +}