-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ca_certificates): invalidate ca store caches when a ca cert is up…
…dated and prevent ca_certificates that are still being referenced by other entities from being deleted (#11789) * fix(ca_certificates): invalidate ca store caches when a ca cert is updated and prevent ca_certificates that are still being referenced by other entities from being deleted. Fix [FTI-2060](https://konghq.atlassian.net/browse/FTI-2060) * apply comments * change plugin tables from maps to arrays * fix plugin_name double check * remove `search_fields` for now as it is EE-only * do the iteration and filtering in dao by adding `select_by_ca_certificate` * auto-detect the entities and plugins that reference ca certificates to make it more generic. create a custom ca_certificates dao and put the check_ca_reference logic into the `:delete()` method instead of a custom API route * update the schema of ca_certificates * fix: fields in schema is an array and cert_pk is a table * add services:select_by_ca_certificate() tests * fix lint * add custom plugin "reference-ca-cert" and plugins:select_by_ca_certificate() tests * add ca_certificates:delete() tests * Apply suggestions from code review Co-authored-by: Michael Martin <[email protected]> * fix typo * remove plugins.lua and services.lua for `off` as they're not currently being used --------- Co-authored-by: Michael Martin <[email protected]>
- Loading branch information
Showing
20 changed files
with
1,189 additions
and
14 deletions.
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
changelog/unreleased/kong/ca_certificates_reference_check.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
message: prevent ca to be deleted when it's still referenced by other entities and invalidate the related ca store caches when a ca cert is updated. | ||
type: bugfix | ||
scope: Core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
local certificate = require "kong.runloop.certificate" | ||
local fmt = string.format | ||
|
||
local Ca_certificates = {} | ||
|
||
-- returns the first encountered entity element that is referencing the ca cert | ||
-- otherwise, returns nil, err | ||
function Ca_certificates:check_ca_reference(ca_id) | ||
for _, entity in ipairs(certificate.get_ca_certificate_reference_entities()) do | ||
local elements, err = self.db[entity]:select_by_ca_certificate(ca_id, 1) | ||
if err then | ||
local msg = fmt("failed to select %s by ca certificate %s: %s", entity, ca_id, err) | ||
return nil, msg | ||
end | ||
|
||
if type(elements) == "table" and #elements > 0 then | ||
return entity, elements[1] | ||
end | ||
end | ||
|
||
local reference_plugins = certificate.get_ca_certificate_reference_plugins() | ||
if reference_plugins and next(reference_plugins) then | ||
local plugins, err = self.db.plugins:select_by_ca_certificate(ca_id, 1, reference_plugins) | ||
if err then | ||
local msg = fmt("failed to select plugins by ca_certificate %s: %s", ca_id, err) | ||
return nil, msg | ||
end | ||
|
||
if type(plugins) == "table" and #plugins > 0 then | ||
return "plugins", plugins[1] | ||
end | ||
end | ||
|
||
return nil, nil | ||
end | ||
|
||
-- Overrides the default delete function to check the ca reference before deleting | ||
function Ca_certificates:delete(cert_pk, options) | ||
local entity, element_or_err = self:check_ca_reference(cert_pk.id) | ||
if entity then | ||
local msg = fmt("ca certificate %s is still referenced by %s (id = %s)", | ||
cert_pk.id, entity, element_or_err.id) | ||
local err_t = self.errors:referenced_by_others(msg) | ||
return nil, tostring(err_t), err_t | ||
|
||
elseif element_or_err then | ||
local err_t = self.errors:database_error(element_or_err) | ||
return nil, tostring(err_t), err_t | ||
end | ||
|
||
return self.super.delete(self, cert_pk, options) | ||
end | ||
|
||
|
||
return Ca_certificates |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
local Services = {} | ||
|
||
-- @ca_id: the id of ca certificate to be searched | ||
-- @limit: the maximum number of entities to return (must >= 0) | ||
-- @return an array of the service entity | ||
function Services:select_by_ca_certificate(ca_id, limit) | ||
local services, err = self.strategy:select_by_ca_certificate(ca_id, limit) | ||
if err then | ||
return nil, err | ||
end | ||
|
||
return self:rows_to_entities(services), nil | ||
end | ||
|
||
return Services |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
local kong = kong | ||
local fmt = string.format | ||
local tb_insert = table.insert | ||
local tb_concat = table.concat | ||
|
||
local Plugins = {} | ||
|
||
function Plugins:select_by_ca_certificate(ca_id, limit, plugin_names) | ||
local connector = kong.db.connector | ||
local escape_literal = connector.escape_literal | ||
local limit_condition = "" | ||
if limit then | ||
limit_condition = "LIMIT " .. escape_literal(connector, limit) | ||
end | ||
|
||
local name_condition = "" | ||
local escaped_names = {} | ||
if type(plugin_names) == "string" then | ||
tb_insert(escaped_names, "name = " .. escape_literal(connector, plugin_names)) | ||
elseif type(plugin_names) == "table" then | ||
for name, _ in pairs(plugin_names) do | ||
tb_insert(escaped_names, "name = " .. escape_literal(connector, name)) | ||
end | ||
end | ||
|
||
if #escaped_names > 0 then | ||
name_condition = "AND (" .. tb_concat(escaped_names, " OR ") .. ")" | ||
end | ||
|
||
local qs = fmt( | ||
"SELECT * FROM plugins WHERE config->'ca_certificates' ? %s %s %s;", | ||
escape_literal(connector, ca_id), | ||
name_condition, | ||
limit_condition) | ||
|
||
return connector:query(qs) | ||
end | ||
|
||
return Plugins |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
local kong = kong | ||
local fmt = string.format | ||
|
||
local Services = {} | ||
|
||
function Services:select_by_ca_certificate(ca_id, limit) | ||
local limit_condition = "" | ||
if limit then | ||
limit_condition = "LIMIT " .. kong.db.connector:escape_literal(limit) | ||
end | ||
|
||
local qs = fmt( | ||
"SELECT * FROM services WHERE %s = ANY(ca_certificates) %s;", | ||
kong.db.connector:escape_literal(ca_id), | ||
limit_condition) | ||
|
||
return kong.db.connector:query(qs) | ||
end | ||
|
||
return Services |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
1c4bfb3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bazel Build
Docker image available
kong/kong:1c4bfb3ebb0d714edb0b00c74b58a819000f5921
Artifacts available https://github.com/Kong/kong/actions/runs/6957553718