From 54c8c0d48bed33bf005fbc936b315bff72e5e137 Mon Sep 17 00:00:00 2001 From: wklken Date: Fri, 27 Dec 2024 14:23:48 +0800 Subject: [PATCH] feat(plugins/bk-default-tenant.lua): add plugin bk-default-tenant (#92) (#95) --- .../ee/plugins/bk-components/bklogin.lua | 38 +++++++++++----- .../ee/tests/bk-components/test-bklogin.lua | 45 +++++++++++++++++++ .../plugins/bk-cache/user-tenant-info.lua | 4 +- src/apisix/plugins/bk-components/bkauth.lua | 4 +- src/apisix/plugins/bk-components/bkuser.lua | 20 +++------ src/apisix/plugins/bk-components/utils.lua | 2 +- src/apisix/plugins/bk-core/config.lua | 10 +++++ .../tests/bk-cache/test-user-tenant-info.lua | 22 ++++----- .../tests/bk-components/test-bkauth.lua | 2 +- .../tests/bk-components/test-bkuser.lua | 22 --------- src/apisix/tests/conf/config.yaml | 2 + 11 files changed, 108 insertions(+), 63 deletions(-) diff --git a/src/apisix/editions/ee/plugins/bk-components/bklogin.lua b/src/apisix/editions/ee/plugins/bk-components/bklogin.lua index 356b732..6f6ed04 100644 --- a/src/apisix/editions/ee/plugins/bk-components/bklogin.lua +++ b/src/apisix/editions/ee/plugins/bk-components/bklogin.lua @@ -24,12 +24,15 @@ local bk_components_utils = require("apisix.plugins.bk-components.utils") local string_format = string.format -local VERIFY_BK_TOKEN_URL = "/api/v3/apigw/bk-tokens/verify/" +local VERIFY_BK_TOKEN_URL = "/login/api/v3/apigw/bk-tokens/verify/" local BKLOGIN_TIMEOUT_MS = 5 * 1000 +local err_status_400 = "status 400, bk_token is not valid" + local _M = { host = bk_core.config.get_login_addr(), + token = bk_core.config.get_login_token(), } local function bklogin_do_request(host, path, params, request_id) @@ -38,7 +41,7 @@ local function bklogin_do_request(host, path, params, request_id) end local url = bk_core.url.url_single_joining_slash(host, path) - local res, err = bk_components_utils.handle_request(url, params, BKLOGIN_TIMEOUT_MS, true) + local res, err = bk_components_utils.handle_request(url, params, BKLOGIN_TIMEOUT_MS, false) if err ~= nil then -- if connection refused, return directly, without wrap(for the fallback cache upon layer) if err == "connection refused" then @@ -54,6 +57,21 @@ local function bklogin_do_request(host, path, params, request_id) return nil, new_err end + -- 响应格式正常,错误码 400,表示 bk_token 非法 + -- note: here we return an {} instead of err, because the lrucache should cache this result as well + if res.status == 400 then + return nil, err_status_400 + end + + if res.status ~= 200 then + local new_err = string_format( + "failed to request third-party api, url: %s, request_id: %s, status!=200, status: %s, response: %s", + url, request_id, res.status, res.body + ) + core.log.error(new_err) + return nil, new_err + end + local result result, err = bk_components_utils.parse_response_json(res.body) if err ~= nil then @@ -81,24 +99,24 @@ function _M.get_username_by_bk_token(bk_token) ssl_verify = false, headers = { ["Content-Type"] = "application/x-www-form-urlencoded", + -- use bearer token to connect bklogin + ["Authorization"] = "Bearer " .. _M.token, }, } local result, err = bklogin_do_request(_M.host, path, params, request_id) if err ~= nil then - return nil, err - end + if err == err_status_400 then + return {error_message="bk_token is not valid"}, nil + end - if result.bk_error_code ~= 0 then - return { - error_message = string_format("bk_token is invalid,host: %s, path: %s, code: %s", - _M.host, path, result.bk_error_code), - } + return nil, err end + -- {"data": {"bk_username": "cpyjg3xo3ta0op6t", "tenant_id": "system"}} return { username = result.data.bk_username, - } + }, nil end return _M diff --git a/src/apisix/editions/ee/tests/bk-components/test-bklogin.lua b/src/apisix/editions/ee/tests/bk-components/test-bklogin.lua index 50f015c..eeca152 100644 --- a/src/apisix/editions/ee/tests/bk-components/test-bklogin.lua +++ b/src/apisix/editions/ee/tests/bk-components/test-bklogin.lua @@ -67,6 +67,50 @@ describe( end ) + + it( + "status 400", function() + response = { + status = 400, + body = core.json.encode( + { + bk_error_code = 400, + bk_error_msg = "bk_token is not valid", + } + ), + } + response_err = nil + + local result, err = bklogin.get_username_by_bk_token("fake-bk-token") + assert.is_same( + result, { + error_message = "bk_token is not valid", + } + ) + assert.is_nil(err) + end + ) + + it( + "status not 200", function() + response = { + status = 500, + body = core.json.encode( + { + bk_error_code = 500, + bk_error_msg = "internal server error", + } + ), + } + response_err = nil + + local result, err = bklogin.get_username_by_bk_token("fake-bk-token") + assert.is_nil(result) + assert.is_true(core.string.has_prefix(err, "failed to request third-party api")) + assert.is_true(core.string.find(err, "request_id") ~= nil) + end + ) + it( "success", function() response = { @@ -88,6 +132,7 @@ describe( assert.is_nil(err) end ) + end ) end diff --git a/src/apisix/plugins/bk-cache/user-tenant-info.lua b/src/apisix/plugins/bk-cache/user-tenant-info.lua index 97cd1a1..772b7a6 100644 --- a/src/apisix/plugins/bk-cache/user-tenant-info.lua +++ b/src/apisix/plugins/bk-cache/user-tenant-info.lua @@ -16,7 +16,7 @@ -- to the current version of the project delivered to anyone in the future. -- local core = require("apisix.core") -local bkauth_component = require("apisix.plugins.bk-components.bkauth") +local bkuser_component = require("apisix.plugins.bk-components.bkuser") local lru_new = require("resty.lrucache").new local USER_TENANT_ID_CACHE_TTL = 600 @@ -39,7 +39,7 @@ local _M = {} function _M.get_user_tenant_info(username) local key = username - local result, err = user_tenant_info_lrucache(key, nil, bkauth_component.get_user_tenant_info, username) + local result, err = user_tenant_info_lrucache(key, nil, bkuser_component.get_user_tenant_info, username) if result == nil then -- if the service is down(100% down), we can use the fallback cache, make the dp robust if err == "connection refused" then diff --git a/src/apisix/plugins/bk-components/bkauth.lua b/src/apisix/plugins/bk-components/bkauth.lua index 05aeae6..edf59a4 100644 --- a/src/apisix/plugins/bk-components/bkauth.lua +++ b/src/apisix/plugins/bk-components/bkauth.lua @@ -199,8 +199,8 @@ function _M.get_app_tenant_info(app_code) -- } -- } return { - tenant_mode=result.data.tenant.mode, - tenant_id=result.data.tenant.id, + tenant_mode=result.data.bk_tenant.mode, + tenant_id=result.data.bk_tenant.id, error_message=nil, }, nil end diff --git a/src/apisix/plugins/bk-components/bkuser.lua b/src/apisix/plugins/bk-components/bkuser.lua index 3007ecb..bca7ba7 100644 --- a/src/apisix/plugins/bk-components/bkuser.lua +++ b/src/apisix/plugins/bk-components/bkuser.lua @@ -22,8 +22,7 @@ local bk_core = require("apisix.plugins.bk-core.init") local bk_components_utils = require("apisix.plugins.bk-components.utils") local string_format = string.format --- FIXME: change to api/v3 -local GET_USER_URL = "/api/v2/profiles/%s" +local GET_USER_URL = "/api/v3/apigw/tenant-users/%s/" local BKUSER_TIMEOUT_MS = 3 * 1000 local bkapp = bk_core.config.get_bkapp() or {} @@ -78,27 +77,18 @@ local function bkuser_do_request(host, path, params, request_id) return nil, new_err end - -- FIXME: api/v3 would not check result.code - if result.code ~= 0 then - local new_err = string_format( - "failed to request third-party api, %s, request_id: %s, result.code!=0, status: %s, response: %s", - url, request_id, res.status, res.body - ) - core.log.error(new_err) - return nil, new_err - end - return result, nil end local _M = { host = bk_core.config.get_bkuser_addr(), + token = bk_core.config.get_bkuser_token(), app_code = bkapp.bk_app_code, app_secret = bkapp.bk_app_secret, } -function _M.get_user_tenant_info(app_code) - local path = string_format(GET_USER_URL, app_code) +function _M.get_user_tenant_info(username) + local path = string_format(GET_USER_URL, username) local request_id = uuid.generate_v4() local params = { method = "GET", @@ -106,6 +96,8 @@ function _M.get_user_tenant_info(app_code) headers = { ["X-Request-Id"] = request_id, ["Content-Type"] = "application/json", + -- use bearer token to connect bkuser + ["Authorization"] = "Bearer " .. _M.token, }, } local result, err = bkuser_do_request(_M.host, path, params, request_id) diff --git a/src/apisix/plugins/bk-components/utils.lua b/src/apisix/plugins/bk-components/utils.lua index 24f9840..3ca2b88 100644 --- a/src/apisix/plugins/bk-components/utils.lua +++ b/src/apisix/plugins/bk-components/utils.lua @@ -86,7 +86,7 @@ local function handle_request(url, params, timeout, raise_for_status) return nil, err .. ", response: nil" end - if raise_for_status and res.status ~= ngx.HTTP_OK then + if raise_for_status and res.status ~= ngx.HTTP_OK then return nil, string_format("status is %s, not 200", res.status) end diff --git a/src/apisix/plugins/bk-core/config.lua b/src/apisix/plugins/bk-core/config.lua index 8a4dfca..50d335a 100644 --- a/src/apisix/plugins/bk-core/config.lua +++ b/src/apisix/plugins/bk-core/config.lua @@ -59,6 +59,11 @@ function _M.get_login_addr() return core.table.try_read_attr(conf, "bk_gateway", "hosts", "login", "addr") end +function _M.get_login_token() + local conf = core.config.local_conf() + return core.table.try_read_attr(conf, "bk_gateway", "hosts", "login", "token") +end + function _M.get_login_tencent_addr() local conf = core.config.local_conf() return core.table.try_read_attr(conf, "bk_gateway", "hosts", "login-tencent", "addr") @@ -84,6 +89,11 @@ function _M.get_bkuser_addr() return core.table.try_read_attr(conf, "bk_gateway", "hosts", "bkuser", "addr") end +function _M.get_bkuser_token() + local conf = core.config.local_conf() + return core.table.try_read_attr(conf, "bk_gateway", "hosts", "bkuser", "token") +end + function _M.get_bkauth_legacy_addr() local conf = core.config.local_conf() return core.table.try_read_attr(conf, "bk_gateway", "hosts", "bkauth-legacy", "addr") diff --git a/src/apisix/tests/bk-cache/test-user-tenant-info.lua b/src/apisix/tests/bk-cache/test-user-tenant-info.lua index 45d66e2..6e5fddc 100644 --- a/src/apisix/tests/bk-cache/test-user-tenant-info.lua +++ b/src/apisix/tests/bk-cache/test-user-tenant-info.lua @@ -17,7 +17,7 @@ -- local user_tenant_info_cache = require("apisix.plugins.bk-cache.user-tenant-info") -local bkauth_component = require("apisix.plugins.bk-components.bkauth") +local bkuser_component = require("apisix.plugins.bk-components.bkuser") local uuid = require("resty.jit-uuid") describe( @@ -32,7 +32,7 @@ describe( get_user_tenant_info_err = nil stub( - bkauth_component, "get_user_tenant_info", function() + bkuser_component, "get_user_tenant_info", function() return get_user_tenant_info_result, get_user_tenant_info_err end ) @@ -41,7 +41,7 @@ describe( after_each( function() - bkauth_component.get_user_tenant_info:revert() + bkuser_component.get_user_tenant_info:revert() end ) @@ -61,15 +61,15 @@ describe( tenant_id = "tenant-123", } ) - assert.stub(bkauth_component.get_user_tenant_info).was_called_with(username) + assert.stub(bkuser_component.get_user_tenant_info).was_called_with(username) -- get from cache user_tenant_info_cache.get_user_tenant_info(username) - assert.stub(bkauth_component.get_user_tenant_info).was_called(1) + assert.stub(bkuser_component.get_user_tenant_info).was_called(1) -- get from func user_tenant_info_cache.get_user_tenant_info(uuid.generate_v4()) - assert.stub(bkauth_component.get_user_tenant_info).was_called(2) + assert.stub(bkuser_component.get_user_tenant_info).was_called(2) end ) @@ -82,15 +82,15 @@ describe( local result, err = user_tenant_info_cache.get_user_tenant_info(username) assert.is_nil(result) assert.is_equal(err, "error") - assert.stub(bkauth_component.get_user_tenant_info).was_called_with(username) + assert.stub(bkuser_component.get_user_tenant_info).was_called_with(username) -- has err, no cache user_tenant_info_cache.get_user_tenant_info(username) - assert.stub(bkauth_component.get_user_tenant_info).was_called(2) + assert.stub(bkuser_component.get_user_tenant_info).was_called(2) -- get from func user_tenant_info_cache.get_user_tenant_info(uuid.generate_v4()) - assert.stub(bkauth_component.get_user_tenant_info).was_called(3) + assert.stub(bkuser_component.get_user_tenant_info).was_called(3) end ) @@ -103,7 +103,7 @@ describe( local result, err = user_tenant_info_cache.get_user_tenant_info(username) assert.is_nil(result) assert.is_equal(err, 'get_user_tenant_info failed, error: connection refused') - assert.stub(bkauth_component.get_user_tenant_info).was_called_with(username) + assert.stub(bkuser_component.get_user_tenant_info).was_called_with(username) end ) @@ -123,7 +123,7 @@ describe( local result, err = user_tenant_info_cache.get_user_tenant_info(username) assert.is_same(result, cached_get_user_tenant_info_result) assert.is_nil(err) - assert.stub(bkauth_component.get_user_tenant_info).was_called_with(username) + assert.stub(bkuser_component.get_user_tenant_info).was_called_with(username) end ) end diff --git a/src/apisix/tests/bk-components/test-bkauth.lua b/src/apisix/tests/bk-components/test-bkauth.lua index a76a54c..dc89dcf 100644 --- a/src/apisix/tests/bk-components/test-bkauth.lua +++ b/src/apisix/tests/bk-components/test-bkauth.lua @@ -435,7 +435,7 @@ describe( { code = 0, data = { - tenant = { + bk_tenant = { mode = "single", id = "tenant-id", }, diff --git a/src/apisix/tests/bk-components/test-bkuser.lua b/src/apisix/tests/bk-components/test-bkuser.lua index 4adf71a..5e7ff6e 100644 --- a/src/apisix/tests/bk-components/test-bkuser.lua +++ b/src/apisix/tests/bk-components/test-bkuser.lua @@ -107,28 +107,6 @@ describe( end ) - it( - "code is not equal to 0", function() - response = { - status = 200, - body = core.json.encode( - { - code = 1, - message = "error", - data = { - tenant_id = nil, - }, - } - ), - } - response_err = nil - - local result, err = bkuser.get_user_tenant_info("fake-app-code") - assert.is_nil(result) - assert.is_true(core.string.has_prefix(err, "failed to request third-party api")) - assert.is_true(core.string.find(err, "request_id") ~= nil) - end - ) it( "status is not 200", function() diff --git a/src/apisix/tests/conf/config.yaml b/src/apisix/tests/conf/config.yaml index 05fd0bc..a0d5926 100644 --- a/src/apisix/tests/conf/config.yaml +++ b/src/apisix/tests/conf/config.yaml @@ -49,9 +49,11 @@ bk_gateway: addr: "http://login-tencent.example.com" login: addr: "http://login.example" + token: "abcdefg" ssm: addr: "http://ssm.example.com" bkcore: addr: "http://bkcore.example.com" bkuser: addr: "http://bkuser.example.com" + token: "abcdefg"