From 1793de7b999f7bdd51141a02df788229202dbdc5 Mon Sep 17 00:00:00 2001 From: Jun Ouyang Date: Wed, 1 Feb 2023 08:10:47 +0800 Subject: [PATCH] fix(clustering): fix 3.2 upstream compact problem (#10192) * fix(clustering): fix upstream protocol tls and latency algorithm compat problem Signed-off-by: Jun Ouyang --- kong/clustering/compat/init.lua | 36 +++++++ spec/01-unit/19-hybrid/03-compat_spec.lua | 117 +++++++++++++++++++++- 2 files changed, 150 insertions(+), 3 deletions(-) diff --git a/kong/clustering/compat/init.lua b/kong/clustering/compat/init.lua index c94bd7a8516..244db12cc21 100644 --- a/kong/clustering/compat/init.lua +++ b/kong/clustering/compat/init.lua @@ -348,8 +348,44 @@ function _M.update_compatible_payload(payload, dp_version, log_suffix) end end end + + local config_services = config_table["services"] + if config_services then + for _, t in ipairs(config_services) do + if t["protocol"] == "tls" then + if t["client_certificate"] or t["tls_verify"] + or t["tls_verify_depth"] or t["ca_certificates"] then + ngx_log(ngx_WARN, _log_prefix, "Kong Gateway v" .. KONG_VERSION .. + " tls protocol service contains configuration 'service.client_certificate'", + " or 'service.tls_verify' or 'service.tls_verify_depth' or 'service.ca_certificates'", + " which is incompatible with dataplane version " .. dp_version .. " and will", + " be removed.", log_suffix) + t["client_certificate"] = nil + t["tls_verify"] = nil + t["tls_verify_depth"] = nil + t["ca_certificates"] = nil + has_update = true + end + end + end + end + + local config_upstreams = config_table["upstreams"] + if config_upstreams then + for _, t in ipairs(config_upstreams) do + if t["algorithm"] == "latency" then + ngx_log(ngx_WARN, _log_prefix, "Kong Gateway v" .. KONG_VERSION .. + " configuration 'upstream.algorithm' contain 'latency' option", + " which is incompatible with dataplane version " .. dp_version .. " and will", + " be fall back to 'round-robin'.", log_suffix) + t["algorithm"] = "round-robin" + has_update = true + end + end + end end + if dp_version_num < 3001000000 --[[ 3.1.0.0 ]] then local config_upstream = config_table["upstreams"] if config_upstream then diff --git a/spec/01-unit/19-hybrid/03-compat_spec.lua b/spec/01-unit/19-hybrid/03-compat_spec.lua index cf21f08b75d..5d75537e4a7 100644 --- a/spec/01-unit/19-hybrid/03-compat_spec.lua +++ b/spec/01-unit/19-hybrid/03-compat_spec.lua @@ -1,9 +1,9 @@ local compat = require("kong.clustering.compat") --- local ssl_fixtures = require "spec.fixtures.ssl" -local helpers = require "spec.helpers" +local helpers = require ("spec.helpers") local declarative = require("kong.db.declarative") local inflate_gzip = require("kong.tools.utils").inflate_gzip local cjson_decode = require("cjson.safe").decode +local ssl_fixtures = require ("spec.fixtures.ssl") local function reset_fields() compat._set_removed_fields(require("kong.clustering.compat.removed_fields")) @@ -322,7 +322,25 @@ describe("kong.clustering.compat", function() }) _G.kong.db = db + local certificate_def = { + _tags = ngx.null, + created_at = 1541088353, + id = "f6c12564-47c8-48b4-b171-0a0d9dbf7cb0", + cert = ssl_fixtures.cert, + key = ssl_fixtures.key, + } + + local ca_certificate_def = { + _tags = ngx.null, + created_at = 1541088353, + id = "f6c12564-47c8-48b4-b171-0a0d9dbf7cb1", + cert = ssl_fixtures.cert_ca, + } + + assert(declarative.load_into_db({ + ca_certificates = { [ca_certificate_def.id] = ca_certificate_def }, + certificates = { [certificate_def.id] = certificate_def }, upstreams = { upstreams1 = { id = "01a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5c6", @@ -341,6 +359,18 @@ describe("kong.clustering.compat", function() slots = 10, use_srv_name = false, }, + upstreams4 = { + id = "01a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5c9", + name = "upstreams4", + slots = 10, + algorithm = "latency", + }, + upstreams5 = { + id = "01a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5d0", + name = "upstreams5", + slots = 10, + algorithm = "round-robin", + }, }, plugins = { plugin1 = { @@ -353,7 +383,59 @@ describe("kong.clustering.compat", function() name = "correlation-id", instance_name = "my-correlation-id" }, - } + }, + services = { + service1 = { + connect_timeout = 60000, + created_at = 1234567890, + host = "example.test", + id = "123e4567-e89b-12d3-a456-426655440000", + name = "foo1", + port = 3000, + read_timeout = 60000, + retries = 5, + updated_at = 1234567890, + write_timeout = 60000, + protocol = "tls", + client_certificate = { id = certificate_def.id }, + tls_verify_depth = 1, + tls_verify = true, + ca_certificates = { ca_certificate_def.id }, + enabled = true, + }, + service2 = { + connect_timeout = 60000, + created_at = 1234567890, + host = "example.com", + id = "123e4567-e89b-12d3-a456-426655440001", + name = "foo2", + port = 80, + read_timeout = 60000, + retries = 5, + updated_at = 1234567890, + write_timeout = 60000, + protocol = "https", + client_certificate = { id = certificate_def.id }, + tls_verify_depth = 1, + tls_verify = true, + ca_certificates = { ca_certificate_def.id }, + enabled = true, + }, + service3 = { + connect_timeout = 60000, + created_at = 1234567890, + host = "example.com", + id = "123e4567-e89b-12d3-a456-426655440002", + name = "foo3", + port = 80, + protocol = "tls", + read_timeout = 60000, + retries = 5, + updated_at = 1234567890, + write_timeout = 60000, + enabled = true, + }, + }, }, { _transform = true })) config = { config_table = declarative.export_config() } @@ -377,5 +459,34 @@ describe("kong.clustering.compat", function() assert.is_nil(assert(plugins[1]).instance_name) assert.is_nil(assert(plugins[2]).instance_name) end) + + it("upstream.algorithm", function() + local has_update, result = compat.update_compatible_payload(config, "3.1.0", "test_") + assert.truthy(has_update) + result = cjson_decode(inflate_gzip(result)).config_table + local upstreams = assert(assert(assert(result).upstreams)) + assert.equals(assert(upstreams[4]).algorithm, "round-robin") + assert.equals(assert(upstreams[5]).algorithm, "round-robin") + end) + + it("service.protocol", function() + local has_update, result = compat.update_compatible_payload(config, "3.1.0", "test_") + assert.truthy(has_update) + result = cjson_decode(inflate_gzip(result)).config_table + local services = assert(assert(assert(result).services)) + assert.is_nil(assert(services[1]).client_certificate) + assert.is_nil(assert(services[1]).tls_verify) + assert.is_nil(assert(services[1]).tls_verify_depth) + assert.is_nil(assert(services[1]).ca_certificates) + assert.not_nil(assert(services[2]).client_certificate) + assert.not_nil(assert(services[2]).tls_verify) + assert.not_nil(assert(services[2]).tls_verify_depth) + assert.not_nil(assert(services[2]).ca_certificates) + assert.is_nil(assert(services[3]).client_certificate) + assert.is_nil(assert(services[3]).tls_verify) + assert.is_nil(assert(services[3]).tls_verify_depth) + assert.is_nil(assert(services[3]).ca_certificates) + end) + end) end)