From c8b103e2426bb5e9278b1e135934f7236253c4b1 Mon Sep 17 00:00:00 2001 From: Vinicius Mignot Date: Fri, 18 Feb 2022 16:22:28 -0300 Subject: [PATCH] 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 baf9da30632..bf9f5e4f337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,6 +112,13 @@ 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 1f7e760e2c6..8da305490d3 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 c866afa453e..584d09aa61d 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 5a78583c829..f38bb11fe28 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 dcf3d06ef50..37a03da151f 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 a7db6e2fd07..d2356072c7b 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 cd28b4f7362..f8fb31285c4 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)