Skip to content

Commit

Permalink
Merge branch 'master' into docs-improve-jwt-auth
Browse files Browse the repository at this point in the history
  • Loading branch information
kayx23 authored Dec 27, 2024
2 parents 3251e93 + 3e5e0eb commit aad444c
Show file tree
Hide file tree
Showing 44 changed files with 910 additions and 221 deletions.
1 change: 0 additions & 1 deletion apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ dependencies = {
"ext-plugin-proto = 0.6.1",
"casbin = 1.41.9-1",
"inspect == 3.1.1",
"lualdap = 1.2.6-1",
"lua-resty-rocketmq = 0.3.0-0",
"opentelemetry-lua = 0.2-3",
"net-url = 0.9-1",
Expand Down
36 changes: 28 additions & 8 deletions apisix/cli/ops.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ local str_find = string.find
local str_byte = string.byte
local str_sub = string.sub
local str_format = string.format
local string = string
local table = table


local _M = {}

Expand Down Expand Up @@ -502,17 +505,34 @@ Please modify "admin_key" in conf/config.yaml .


if yaml_conf.apisix.ssl.ssl_trusted_certificate ~= nil then
local cert_path = yaml_conf.apisix.ssl.ssl_trusted_certificate
-- During validation, the path is relative to PWD
-- When Nginx starts, the path is relative to conf
-- Therefore we need to check the absolute version instead
cert_path = pl_path.abspath(cert_path)
local cert_paths = {}
local ssl_certificates = yaml_conf.apisix.ssl.ssl_trusted_certificate
for cert_path in string.gmatch(ssl_certificates, '([^,]+)') do
cert_path = util.trim(cert_path)
if cert_path == "system" then
local trusted_certs_path, err = util.get_system_trusted_certs_filepath()
if not trusted_certs_path then
util.die(err)
end
table.insert(cert_paths, trusted_certs_path)
else
-- During validation, the path is relative to PWD
-- When Nginx starts, the path is relative to conf
-- Therefore we need to check the absolute version instead
cert_path = pl_path.abspath(cert_path)
if not pl_path.exists(cert_path) then
util.die("certificate path", cert_path, "doesn't exist\n")
end

if not pl_path.exists(cert_path) then
util.die("certificate path", cert_path, "doesn't exist\n")
table.insert(cert_paths, cert_path)
end
end

yaml_conf.apisix.ssl.ssl_trusted_certificate = cert_path
local combined_cert_filepath = yaml_conf.apisix.ssl.ssl_trusted_combined_path
or "/usr/local/apisix/conf/ssl_trusted_combined.pem"
util.gen_trusted_certs_combined_file(combined_cert_filepath, cert_paths)

yaml_conf.apisix.ssl.ssl_trusted_certificate = combined_cert_filepath
end

-- enable ssl with place holder crt&key
Expand Down
3 changes: 3 additions & 0 deletions apisix/cli/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ local config_schema = {
ssl_trusted_certificate = {
type = "string",
},
ssl_trusted_combined_path = {
type = "string",
},
listen = {
type = "array",
items = {
Expand Down
53 changes: 53 additions & 0 deletions apisix/cli/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ local exit = os.exit
local stderr = io.stderr
local str_format = string.format
local tonumber = tonumber
local io = io
local ipairs = ipairs
local assert = assert

local _M = {}

Expand Down Expand Up @@ -133,4 +136,54 @@ function _M.file_exists(file_path)
return f ~= nil and close(f)
end

do
local trusted_certs_paths = {
"/etc/ssl/certs/ca-certificates.crt", -- Debian/Ubuntu/Gentoo
"/etc/pki/tls/certs/ca-bundle.crt", -- Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", -- OpenSUSE
"/etc/pki/tls/cacert.pem", -- OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", -- CentOS/RHEL 7
"/etc/ssl/cert.pem", -- OpenBSD, Alpine
}

-- Check if a file exists using Lua's built-in `io.open`
local function file_exists(path)
local file = io.open(path, "r")
if file then
file:close()
return true
else
return false
end
end

function _M.get_system_trusted_certs_filepath()
for _, path in ipairs(trusted_certs_paths) do
if file_exists(path) then
return path
end
end

return nil,
"Could not find trusted certs file in " ..
"any of the `system`-predefined locations. " ..
"Please install a certs file there or set " ..
"`lua_ssl_trusted_certificate` to a " ..
"specific file path instead of `system`"
end
end


function _M.gen_trusted_certs_combined_file(combined_filepath, paths)
local combined_file = assert(io.open(combined_filepath, "w"))
for _, path in ipairs(paths) do
local cert_file = assert(io.open(path, "r"))
combined_file:write(cert_file:read("*a"))
combined_file:write("\n")
cert_file:close()
end
combined_file:close()
end


return _M
8 changes: 7 additions & 1 deletion apisix/core/config_etcd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ local function do_run_watch(premature)
end

local rev = tonumber(res.result.header.revision)
if rev == nil then
log.warn("receive a invalid revision header, header: ", inspect(res.result.header))
cancel_watch(http_cli)
break
end
if rev > watch_ctx.rev then
watch_ctx.rev = rev + 1
end
Expand Down Expand Up @@ -284,7 +289,8 @@ local function run_watch(premature)

local ok, err = ngx_thread_wait(run_watch_th, check_worker_th)
if not ok then
log.error("check_worker thread terminates failed, retart checker, error: " .. err)
log.error("run_watch or check_worker thread terminates failed",
" restart those threads, error: ", inspect(err))
end

ngx_thread_kill(run_watch_th)
Expand Down
29 changes: 20 additions & 9 deletions apisix/core/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ local newproxy = newproxy
local getmetatable = getmetatable
local setmetatable = setmetatable
local select = select
local tostring = tostring
local new_tab = require("table.new")
local nkeys = require("table.nkeys")
local ipairs = ipairs
Expand Down Expand Up @@ -91,7 +92,7 @@ end
-- @usage
-- local arr = {"a", "b", "c"}
-- local idx = core.table.array_find(arr, "b") -- idx = 2
function _M.array_find(array, val)
local function array_find(array, val)
if type(array) ~= "table" then
return nil
end
Expand All @@ -104,6 +105,7 @@ function _M.array_find(array, val)

return nil
end
_M.array_find = array_find


-- only work under lua51 or luajit
Expand All @@ -117,19 +119,28 @@ end

local deepcopy
do
local function _deepcopy(orig, copied)
-- prevent infinite loop when a field refers its parent
copied[orig] = true
local function _deepcopy(orig, copied, parent, opts)
-- If the array-like table contains nil in the middle,
-- the len might be smaller than the expected.
-- But it doesn't affect the correctness.
local len = #orig
local copy = new_tab(len, nkeys(orig) - len)
-- prevent infinite loop when a field refers its parent
copied[orig] = copy
for orig_key, orig_value in pairs(orig) do
if type(orig_value) == "table" and not copied[orig_value] then
copy[orig_key] = _deepcopy(orig_value, copied)
else
local path = parent .. "." .. tostring(orig_key)
if opts and array_find(opts.shallows, path) then
copy[orig_key] = orig_value
else
if type(orig_value) == "table" then
if copied[orig_value] then
copy[orig_key] = copied[orig_value]
else
copy[orig_key] = _deepcopy(orig_value, copied, path, opts)
end
else
copy[orig_key] = orig_value
end
end
end

Expand All @@ -144,13 +155,13 @@ do

local copied_recorder = {}

function deepcopy(orig)
function deepcopy(orig, opts)
local orig_type = type(orig)
if orig_type ~= 'table' then
return orig
end

local res = _deepcopy(orig, copied_recorder)
local res = _deepcopy(orig, copied_recorder, "self", opts)
_M.clear(copied_recorder)
return res
end
Expand Down
10 changes: 1 addition & 9 deletions apisix/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -246,15 +246,7 @@ local function parse_domain_in_route(route)
-- don't modify the modifiedIndex to avoid plugin cache miss because of DNS resolve result
-- has changed

local parent = route.value.upstream.parent
if parent then
route.value.upstream.parent = nil
end
route.dns_value = core.table.deepcopy(route.value)
if parent then
route.value.upstream.parent = parent
route.dns_value.upstream.parent = parent
end
route.dns_value = core.table.deepcopy(route.value, { shallows = { "self.upstream.parent"}})
route.dns_value.upstream.nodes = new_nodes
core.log.info("parse route which contain domain: ",
core.json.delay_encode(route, true))
Expand Down
11 changes: 8 additions & 3 deletions apisix/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ local function load_plugin(name, plugins_list, plugin_type)
plugin.init()
end

if plugin.workflow_handler then
plugin.workflow_handler()
end

return
end

Expand Down Expand Up @@ -580,7 +584,7 @@ end


local function merge_service_route(service_conf, route_conf)
local new_conf = core.table.deepcopy(service_conf)
local new_conf = core.table.deepcopy(service_conf, { shallows = {"self.value.upstream.parent"}})
new_conf.value.service_id = new_conf.value.id
new_conf.value.id = route_conf.value.id
new_conf.modifiedIndex = route_conf.modifiedIndex
Expand Down Expand Up @@ -654,7 +658,7 @@ end
local function merge_service_stream_route(service_conf, route_conf)
-- because many fields in Service are not supported by stream route,
-- so we copy the stream route as base object
local new_conf = core.table.deepcopy(route_conf)
local new_conf = core.table.deepcopy(route_conf, { shallows = {"self.value.upstream.parent"}})
if service_conf.value.plugins then
for name, conf in pairs(service_conf.value.plugins) do
if not new_conf.value.plugins then
Expand Down Expand Up @@ -702,7 +706,8 @@ local function merge_consumer_route(route_conf, consumer_conf, consumer_group_co
return route_conf
end

local new_route_conf = core.table.deepcopy(route_conf)
local new_route_conf = core.table.deepcopy(route_conf,
{ shallows = {"self.value.upstream.parent"}})

if consumer_group_conf then
for name, conf in pairs(consumer_group_conf.value.plugins) do
Expand Down
10 changes: 5 additions & 5 deletions apisix/plugins/ai-proxy/drivers/openai.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ function _M.request(conf, request_table, ctx)
end

local ok, err = httpc:connect({
scheme = parsed_url.scheme or "https",
host = parsed_url.host or DEFAULT_HOST,
port = parsed_url.port or DEFAULT_PORT,
scheme = endpoint and parsed_url.scheme or "https",
host = endpoint and parsed_url.host or DEFAULT_HOST,
port = endpoint and parsed_url.port or DEFAULT_PORT,
ssl_verify = conf.ssl_verify,
ssl_server_name = parsed_url.host or DEFAULT_HOST,
ssl_server_name = endpoint and parsed_url.host or DEFAULT_HOST,
pool_size = conf.keepalive and conf.keepalive_pool,
})

if not ok then
return nil, "failed to connect to LLM server: " .. err
end

local path = (parsed_url.path or DEFAULT_PATH)
local path = (endpoint and parsed_url.path or DEFAULT_PATH)

local headers = (conf.auth.header or {})
headers["Content-Type"] = "application/json"
Expand Down
4 changes: 3 additions & 1 deletion apisix/plugins/ai.lua
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ local default_keepalive_pool = {}

local function create_router_matching_cache(api_ctx)
orig_router_http_matching(api_ctx)
return core.table.deepcopy(api_ctx)
return core.table.deepcopy(api_ctx, {
shallows = { "self.matched_route.value.upstream.parent" }
})
end


Expand Down
10 changes: 8 additions & 2 deletions apisix/plugins/jwt-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,14 @@ local consumer_schema = {
type = "object",
-- can't use additionalProperties with dependencies
properties = {
key = {type = "string"},
secret = {type = "string"},
key = {
type = "string",
minLength = 1,
},
secret = {
type = "string",
minLength = 1,
},
algorithm = {
type = "string",
enum = {"HS256", "HS512", "RS256", "ES256"},
Expand Down
15 changes: 13 additions & 2 deletions apisix/plugins/limit-count.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@
--
local fetch_secrets = require("apisix.secret").fetch_secrets
local limit_count = require("apisix.plugins.limit-count.init")
local workflow = require("apisix.plugins.workflow")

local plugin_name = "limit-count"
local _M = {
version = 0.5,
priority = 1002,
name = plugin_name,
schema = limit_count.schema,
metadata_schema = limit_count.metadata_schema,
}


function _M.check_schema(conf)
return limit_count.check_schema(conf)
function _M.check_schema(conf, schema_type)
return limit_count.check_schema(conf, schema_type)
end


Expand All @@ -36,5 +38,14 @@ function _M.access(conf, ctx)
return limit_count.rate_limit(conf, ctx, plugin_name, 1)
end

function _M.workflow_handler()
workflow.register(plugin_name,
function (conf, ctx)
return limit_count.rate_limit(conf, ctx, plugin_name, 1)
end,
function (conf)
return limit_count.check_schema(conf)
end)
end

return _M
Loading

0 comments on commit aad444c

Please sign in to comment.