diff --git a/.gitignore b/.gitignore index cd3d22536..92c28268d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -logs \ No newline at end of file +logs +.idea diff --git a/release.md b/release.md index dbe0008fd..b98becb72 100644 --- a/release.md +++ b/release.md @@ -1,3 +1,18 @@ +# V1.5.14 + +### 新增功能 +* 支持初始化接入APIGateway的API和文档 + +### 功能优化 +* 自动更新资源实例名称对大策略的防御性忽略 +* 新增接入系统管理类API的bk_nocode白名单 +* 调用第三方接口失败时支持返回异常信息 +* 用户组授权调整为立即执行任务 + +### 缺陷修复 +* 自动更新资源实例名称兼容接入系统回调异常 +* 解决未资源实例视图为空时导致授权异常 + # V1.5.13 ### 新增功能 diff --git a/saas/VERSION b/saas/VERSION index fa85d4d1d..8df6b88a9 100644 --- a/saas/VERSION +++ b/saas/VERSION @@ -1 +1 @@ -1.5.13 +1.5.14 diff --git a/saas/backend/api/management/migrations/0004_auto_20211130_1137.py b/saas/backend/api/management/migrations/0004_auto_20211130_1137.py new file mode 100644 index 000000000..453f274ac --- /dev/null +++ b/saas/backend/api/management/migrations/0004_auto_20211130_1137.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-权限中心(BlueKing-IAM) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" +# Generated by Django 2.2.24 on 2021-11-30 03:37 + +from django.db import migrations + +from backend.api.constants import ALLOW_ANY + + +def init_allow_list(apps, schema_editor): + """初始化授权API白名单""" + ManagementAPIAllowListConfig = apps.get_model("management", "ManagementAPIAllowListConfig") + + # 查询已存在白名单,避免重复 + all_allow_list = ManagementAPIAllowListConfig.objects.all() + allow_set = set([(a.system_id, a.api) for a in all_allow_list]) + + # 白名单列表 + system_id_allow_apis = { + "bk_nocode": [ALLOW_ANY], + } + + # 组装成Model对象 + mgmt_api_allow_list_config = [] + for system_id, apis in system_id_allow_apis.items(): + for api in apis: + # 已存在,则直接忽略 + if (system_id, api) in allow_set: + continue + mgmt_api_allow_list_config.append(ManagementAPIAllowListConfig(system_id=system_id, api=api)) + # 批量创建 + if len(mgmt_api_allow_list_config) != 0: + ManagementAPIAllowListConfig.objects.bulk_create(mgmt_api_allow_list_config) + + +class Migration(migrations.Migration): + + dependencies = [ + ('management', '0003_systemallowauthsystem'), + ] + + operations = [ + migrations.RunPython(init_allow_list) + ] diff --git a/saas/backend/apps/template/views.py b/saas/backend/apps/template/views.py index cc1ce2919..71f6a12a7 100644 --- a/saas/backend/apps/template/views.py +++ b/saas/backend/apps/template/views.py @@ -559,7 +559,7 @@ def create(self, request, *args, **kwargs): # 使用长时任务实现用户组授权更新 task = TaskDetail.create(TaskType.TEMPLATE_UPDATE.value, [template.id]) - TaskFactory().delay(task.id) + TaskFactory()(task.id) audit_context_setter(template=template) diff --git a/saas/backend/biz/group.py b/saas/backend/biz/group.py index 50bd1a535..b36418ea2 100644 --- a/saas/backend/biz/group.py +++ b/saas/backend/biz/group.py @@ -519,7 +519,7 @@ def grant(self, role: Role, group: Group, templates: List[GroupTemplateGrantBean task = TaskDetail.create(TaskType.GROUP_AUTHORIZATION.value, [subject.dict(), uuid]) # 执行授权流程 - TaskFactory().delay(task.id) + TaskFactory()(task.id) def get_group_role_dict_by_ids(self, group_ids: List[int]) -> GroupRoleDict: """ diff --git a/saas/backend/biz/instance_selection.py b/saas/backend/biz/instance_selection.py index f41044ab6..cfdb50e73 100644 --- a/saas/backend/biz/instance_selection.py +++ b/saas/backend/biz/instance_selection.py @@ -69,6 +69,9 @@ def _list_system_id(self): """ 获取所有视图节点的system_id """ + if not self.selections: + return [] + return list(set.union(*[selection.get_chain_system_set() for selection in self.selections])) def fill_chain_node_name(self): @@ -96,6 +99,9 @@ def list_by_action_resource_type( selections = self.svc.list_by_action_resource_type( system_id, action_id, resource_type_system_id, resource_type_id ) + if not selections: + return [] + biz_selections = parse_obj_as(List[InstanceSelectionBean], selections) return self._fill_chain_node_name(biz_selections) diff --git a/saas/backend/biz/policy.py b/saas/backend/biz/policy.py index 4e55cae71..db83d471a 100644 --- a/saas/backend/biz/policy.py +++ b/saas/backend/biz/policy.py @@ -9,6 +9,7 @@ specific language governing permissions and limitations under the License. """ import functools +import logging import time from copy import deepcopy from itertools import chain, groupby @@ -23,7 +24,7 @@ from backend.common.error_codes import error_codes from backend.common.time import PERMANENT_SECONDS, expired_at_display, generate_default_expired_at from backend.service.action import ActionService -from backend.service.constants import ANY_ID +from backend.service.constants import ANY_ID, FETCH_MAX_LIMIT from backend.service.models import ( Action, BackendThinPolicy, @@ -49,6 +50,8 @@ from .resource import ResourceBiz, ResourceNodeBean +logger = logging.getLogger(__name__) + class PolicyEmptyException(Exception): pass @@ -889,12 +892,17 @@ def check_instance_selection(self, ignore_path=False): continue rrt.check_selection(resource_type.instance_selections, ignore_path) - def _list_path_node(self) -> List[PathNodeBean]: + def _list_path_node(self, is_ignore_big_policy=False) -> List[PathNodeBean]: """ 查询策略包含的资源范围 - 所有路径上的节点,包括叶子节点 + is_ignore_big_policy: 是否忽略大的策略,大策略是指策略里的实例数量大于1000, + 主要是用于自动更新策略里的资源实例名称时避免大数量的请求接入系统(1000是权限中心的回调接口协议里规定的) """ nodes = [] for p in self.policies: + # 这里是定制逻辑:基于fetch_instance_info限制,避免出现大策略 + if is_ignore_big_policy and p.count_all_type_instance() > FETCH_MAX_LIMIT: + continue nodes.extend(p.list_path_node()) return nodes @@ -937,8 +945,8 @@ def check_instance_count_limit(self): def get_renamed_resources(self) -> Dict[PathNodeBean, str]: """查询已经被重命名的资源实例""" - # 获取策略里的资源的所有节点 - path_nodes = self._list_path_node() + # 获取策略里的资源的所有节点,防御性措施:忽略大策略,避免给接入系统请求压力 + path_nodes = self._list_path_node(is_ignore_big_policy=True) # 查询资源实例的实际名称 resource_name_dict = self.resource_biz.fetch_resource_name(parse_obj_as(List[ResourceNodeBean], path_nodes)) @@ -965,8 +973,13 @@ def auto_update_resource_name(self) -> List[PolicyBean]: 策略里存储的资源名称可能已经变了,需要进行更新 Note: 该函数仅用于需要对外展示策略数据时调用,不会自动更新DB里数据 """ - # 获取策略里被重命名的资源实例 - renamed_resources = self.get_renamed_resources() + # 由于自动更新并非核心功能,若接入系统查询有问题,也需要正常显示 + try: + # 获取策略里被重命名的资源实例 + renamed_resources = self.get_renamed_resources() + except Exception as error: + logger.exception(f"auto_update: get_renamed_resources error={error}") + return [] # 没有任何被重命名的资源实例,则无需更新策略 if len(renamed_resources) == 0: diff --git a/saas/backend/component/engine.py b/saas/backend/component/engine.py index 0f141ce1e..b8bb08188 100644 --- a/saas/backend/component/engine.py +++ b/saas/backend/component/engine.py @@ -48,7 +48,7 @@ def _call_engine_api(http_func, url_path, data, timeout=30): if not ok: message = "engine api failed, method: %s, info: %s" % (http_func.__name__, kwargs) logger.error(message) - raise error_codes.ENGINE_REQUEST_ERROR.format("request engine api error") + raise error_codes.ENGINE_REQUEST_ERROR.format(f'request engine api error: {data["error"]}') code = data["code"] message = data["message"] diff --git a/saas/backend/component/esb.py b/saas/backend/component/esb.py index 900168835..1fee79b50 100644 --- a/saas/backend/component/esb.py +++ b/saas/backend/component/esb.py @@ -45,7 +45,7 @@ def _call_esb_api(http_func, url_path, data, timeout=30): if not ok: message = "esb api failed, method: %s, info: %s" % (http_func.__name__, kwargs) logger.error(message) - raise error_codes.REMOTE_REQUEST_ERROR.format("request esb api error") + raise error_codes.REMOTE_REQUEST_ERROR.format(f'request esb api error: {data["error"]}') code = data["code"] message = data["message"] diff --git a/saas/backend/component/http.py b/saas/backend/component/http.py index 0f6ead8ca..9bf202704 100644 --- a/saas/backend/component/http.py +++ b/saas/backend/component/http.py @@ -67,11 +67,11 @@ def _http_request(method, url, headers=None, data=None, timeout=None, verify=Fal url=url, headers=headers, json=data, timeout=timeout, verify=verify, cert=cert, cookies=cookies ) else: - return False, None - except requests.exceptions.RequestException: + return False, {"error": "method not supported"} + except requests.exceptions.RequestException as e: logger.exception("http request error! method: %s, url: %s, data: %s", method, url, data) trace_func(exc=traceback.format_exc()) - return False, None + return False, {"error": str(e)} else: # record for /metrics latency = int((time.time() - st) * 1000) @@ -90,7 +90,7 @@ def _http_request(method, url, headers=None, data=None, timeout=None, verify=Fal logger.error(error_msg, method, url, str(data), resp.status_code, content) trace_func(status_code=resp.status_code, content=content) - return False, None + return False, {"error": f"status_code is {resp.status_code}, not 200"} return True, resp.json() diff --git a/saas/backend/component/iam.py b/saas/backend/component/iam.py index ccdee367a..a6d50ca86 100644 --- a/saas/backend/component/iam.py +++ b/saas/backend/component/iam.py @@ -52,7 +52,7 @@ def _call_iam_api(http_func, url_path, data, timeout=30): if not ok: message = "iam api failed, method: %s, info: %s" % (http_func.__name__, kwargs) logger.error(message) - raise error_codes.REMOTE_REQUEST_ERROR.format("request iam api error") + raise error_codes.REMOTE_REQUEST_ERROR.format(f'request iam api error: {data["error"]}') code = data["code"] message = data["message"] diff --git a/saas/backend/long_task/tasks.py b/saas/backend/long_task/tasks.py index c1ec170ec..fc370e33e 100644 --- a/saas/backend/long_task/tasks.py +++ b/saas/backend/long_task/tasks.py @@ -232,4 +232,4 @@ def retry_long_task(): status__in=[TaskStatus.PENDING.value, TaskStatus.RUNNING.value], created_time__lt=day_before ) for t in qs: - TaskFactory().delay(t.id) + TaskFactory()(t.id) diff --git a/saas/backend/service/constants.py b/saas/backend/service/constants.py index e3df09ece..a5f6032bf 100644 --- a/saas/backend/service/constants.py +++ b/saas/backend/service/constants.py @@ -39,6 +39,13 @@ class SubjectRelationType(ChoicesEnum, LowerStrEnum): _choices_labels = skip(((GROUP, "用户组"), (DEPARTMENT, "部门"))) +# ---------------------------------------------------------------------------------------------- # +# Resource Provider +# ---------------------------------------------------------------------------------------------- # +# fetch_instance_info 接口的批量限制 +FETCH_MAX_LIMIT = 1000 + + # ---------------------------------------------------------------------------------------------- # # Group Constants # ---------------------------------------------------------------------------------------------- # diff --git a/saas/backend/service/resource.py b/saas/backend/service/resource.py index 5fef5b96b..c57fc9e59 100644 --- a/saas/backend/service/resource.py +++ b/saas/backend/service/resource.py @@ -19,6 +19,7 @@ from backend.util.cache import redis_region, region from backend.util.url import url_join +from .constants import FETCH_MAX_LIMIT from .models import ( ResourceAttribute, ResourceAttributeValue, @@ -210,10 +211,9 @@ def fetch_instance_info( ) -> List[ResourceInstanceInfo]: """批量查询资源实例属性,包括display_name等""" # fetch_instance_info 接口的批量限制 - fetch_limit = 1000 # 分页查询资源实例属性 results = [] - page_ids_list = chunked(ids, fetch_limit) + page_ids_list = chunked(ids, FETCH_MAX_LIMIT) for page_ids in page_ids_list: filter_condition = {"ids": page_ids, "attrs": attributes} if attributes else {"ids": page_ids} page_results = self.client.fetch_instance_info(filter_condition) diff --git a/saas/config/default.py b/saas/config/default.py index a2de8e390..1517b7dca 100644 --- a/saas/config/default.py +++ b/saas/config/default.py @@ -353,3 +353,12 @@ # 是否是smart部署方式 IS_SMART_DEPLOY = os.environ.get("BKAPP_IS_SMART_DEPLOY", "True").lower() == "true" + +# apigateway 相关配置 +# NOTE: it sdk will read settings.BK_APP_CODE and settings.BK_APP_SECRET, so you should set it +BK_APIGW_NAME = "bk-iam" +BK_API_URL_TMPL = "" +INSTALLED_APPS += ("apigw_manager.apigw",) +BK_IAM_BACKEND_SVC = os.environ.get("BK_IAM_BACKEND_SVC", "bkiam-web") +BK_IAM_ENGINE_SVC = os.environ.get("BK_IAM_ENGINE_SVC", "bkiam-search-engine-web") +BK_APIGW_RESOURCE_DOCS_BASE_DIR = os.path.join(BASE_DIR, "resources/apigateway/docs/") diff --git a/saas/config/dev.py b/saas/config/dev.py index d687c07e7..251fe33f9 100644 --- a/saas/config/dev.py +++ b/saas/config/dev.py @@ -62,8 +62,8 @@ # 蓝鲸智云开发者中心的域名,形如:http://paas.bking.com BK_PAAS_HOST = "" -APP_ID = os.environ.get("APP_ID", APP_ID) -APP_TOKEN = os.environ.get("APP_TOKEN", APP_TOKEN) +APP_ID = BK_APP_CODE = os.environ.get("APP_ID", APP_ID) +APP_TOKEN = BK_APP_SECRET = os.environ.get("APP_TOKEN", APP_TOKEN) BK_PAAS_HOST = os.environ.get("BK_PAAS_HOST", BK_PAAS_HOST) BK_PAAS_INNER_HOST = os.environ.get("BK_PAAS_INNER_HOST", BK_PAAS_HOST) BK_IAM_HOST = "" diff --git a/saas/config/prod.py b/saas/config/prod.py index fbeeb4f24..d91a2e169 100644 --- a/saas/config/prod.py +++ b/saas/config/prod.py @@ -51,8 +51,8 @@ def get_app_service_url(app_code: str) -> str: return {item["key"]["bk_app_code"]: item["value"]["prod"] for item in decoded_value}[app_code] # 兼容component的APP_ID,APP_TOKEN - APP_CODE = APP_ID = os.environ.get("BKPAAS_APP_ID", APP_CODE) - SECRET_KEY = APP_TOKEN = os.environ.get("BKPAAS_APP_SECRET", SECRET_KEY) + APP_CODE = APP_ID = BK_APP_CODE = os.environ.get("BKPAAS_APP_ID", APP_CODE) + SECRET_KEY = APP_TOKEN = BK_APP_SECRET = os.environ.get("BKPAAS_APP_SECRET", SECRET_KEY) BK_PAAS_INNER_HOST = os.environ.get("BK_PAAS2_URL", BK_PAAS_INNER_HOST) BK_COMPONENT_API_URL = os.environ.get("BK_COMPONENT_API_URL") BK_COMPONENT_INNER_API_URL = BK_COMPONENT_API_URL diff --git a/saas/poetry.lock b/saas/poetry.lock index 29786cf1a..da3283aa5 100644 --- a/saas/poetry.lock +++ b/saas/poetry.lock @@ -22,6 +22,23 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "apigw-manager" +version = "1.0.0" +description = "" +category = "main" +optional = false +python-versions = "==3.*,>=3.6.1" + +[package.dependencies] +bkapi-bk-apigateway = ">=1.0.3,<2.0.0" +bkapi-client-core = ">=1.0.8,<2.0.0" +future = "0.18.2" +pyjwt = ">=1.6.4" +python-dateutil = "2.8.1" +pyyaml = ">=5.4.1,<6.0.0" +urllib3 = ">=1.25.3" + [[package]] name = "appdirs" version = "1.4.4" @@ -60,6 +77,36 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "bkapi-bk-apigateway" +version = "1.0.3" +description = "蓝鲸API网关" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,<4.0,>=2.7" + +[package.dependencies] +bkapi-client-core = ">=1.0.2,<2.0.0" + +[package.extras] +django = ["bkapi-client-core[django] (>=1.0.2,<2.0.0)"] + +[[package]] +name = "bkapi-client-core" +version = "1.1.0" +description = "" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +curlify = ">=2.0,<3.0" +requests = ">=2.20,<3.0" +typing-extensions = ">=3.7.4,<4.0.0" + +[package.extras] +django = ["bkoauth (>=0.0.10)"] + [[package]] name = "black" version = "21.7b0" @@ -236,6 +283,17 @@ pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] ssh = ["bcrypt (>=3.1.5)"] test = ["pytest (>=3.6.0,!=3.9.0,!=3.9.1,!=3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +[[package]] +name = "curlify" +version = "2.2.1" +description = "Library to convert python requests object to curl command." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +requests = "*" + [[package]] name = "dataclasses" version = "0.7" @@ -426,6 +484,14 @@ python-versions = ">=3.6" flake8 = ">=3.0,<3.2.0 || >3.2.0,<4" importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +[[package]] +name = "future" +version = "0.18.2" +description = "Clean single-source support for Python 3 and 2" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "httplib2" version = "0.19.0" @@ -791,6 +857,17 @@ pytest = ">=5.4.0" docs = ["sphinx", "sphinx-rtd-theme"] testing = ["django", "django-configurations (>=2.0)"] +[[package]] +name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + [[package]] name = "python-json-logger" version = "0.1.7" @@ -807,6 +884,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pyyaml" +version = "5.4.1" +description = "YAML parser and emitter for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + [[package]] name = "redis" version = "2.10.6" @@ -948,7 +1033,7 @@ python-versions = "*" name = "typing-extensions" version = "3.10.0.0" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -1011,7 +1096,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "3.6.6" -content-hash = "684c9701a531f345cd8abea5de62654b985c61cc07d8b67df80ff9a15708c538" +content-hash = "574b5d5770f7aa3cee7e92f1d0eea9bd4478da8fd31b164f4e4ea120ef4bc640" [metadata.files] aenum = [ @@ -1026,6 +1111,9 @@ amqp = [ anyjson = [ {file = "anyjson-0.3.3.tar.gz", hash = "sha256:37812d863c9ad3e35c0734c42e0bf0320ce8c3bed82cd20ad54cb34d158157ba"}, ] +apigw-manager = [ + {file = "apigw-manager-1.0.0.tar.gz", hash = "sha256:96032b786aa6ec578001de26035faec4b17a3f304a3af37484d9f7297a15739a"}, +] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, @@ -1048,6 +1136,12 @@ billiard = [ {file = "billiard-3.3.0.23-cp33-none-win_amd64.whl", hash = "sha256:d4d2fed1a251ea58eed47b48db3778ebb92f5ff4407dc91869c6f41c3a9249d0"}, {file = "billiard-3.3.0.23.tar.gz", hash = "sha256:692a2a5a55ee39a42bcb7557930e2541da85df9ea81c6e24827f63b80cd39d0b"}, ] +bkapi-bk-apigateway = [ + {file = "bkapi-bk-apigateway-1.0.3.tar.gz", hash = "sha256:3bc9ae60524c1f64431092d7dad72f73d718514e9fc860b7650c70b3c1b0d887"}, +] +bkapi-client-core = [ + {file = "bkapi_client_core-1.1.0-py2.py3-none-any.whl", hash = "sha256:de9d862b89d35cd33466eb3c142a91a027e2e002b02960b7401606d0dad10540"}, +] black = [ {file = "black-21.7b0-py3-none-any.whl", hash = "sha256:1c7aa6ada8ee864db745b22790a32f94b2795c253a75d6d9b5e439ff10d23116"}, {file = "black-21.7b0.tar.gz", hash = "sha256:c8373c6491de9362e39271630b65b964607bc5c79c83783547d76c839b3aa219"}, @@ -1195,6 +1289,9 @@ cryptography = [ {file = "cryptography-3.3.2-cp36-abi3-win_amd64.whl", hash = "sha256:7951a966613c4211b6612b0352f5bf29989955ee592c4a885d8c7d0f830d0433"}, {file = "cryptography-3.3.2.tar.gz", hash = "sha256:5a60d3780149e13b7a6ff7ad6526b38846354d11a15e21068e57073e29e19bed"}, ] +curlify = [ + {file = "curlify-2.2.1.tar.gz", hash = "sha256:0d3f02e7235faf952de8ef45ef469845196d30632d5838bcd5aee217726ddd6d"}, +] dataclasses = [ {file = "dataclasses-0.7-py3-none-any.whl", hash = "sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836"}, {file = "dataclasses-0.7.tar.gz", hash = "sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6"}, @@ -1257,6 +1354,9 @@ flake8-comprehensions = [ {file = "flake8-comprehensions-3.5.0.tar.gz", hash = "sha256:f24be9032587127f7a5bc6d066bf755b6e66834f694383adb8a673e229c1f559"}, {file = "flake8_comprehensions-3.5.0-py3-none-any.whl", hash = "sha256:b07aef3277623db32310aa241a1cec67212b53c1d18e767d7e26d4d83aa05bf7"}, ] +future = [ + {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, +] httplib2 = [ {file = "httplib2-0.19.0-py3-none-any.whl", hash = "sha256:749c32603f9bf16c1277f59531d502e8f1c2ca19901ae653b49c4ed698f0820e"}, {file = "httplib2-0.19.0.tar.gz", hash = "sha256:e0d428dad43c72dbce7d163b7753ffc7a39c097e6788ef10f4198db69b92f08e"}, @@ -1522,6 +1622,10 @@ pytest-django = [ {file = "pytest-django-4.1.0.tar.gz", hash = "sha256:26f02c16d36fd4c8672390deebe3413678d89f30720c16efb8b2a6bf63b9041f"}, {file = "pytest_django-4.1.0-py3-none-any.whl", hash = "sha256:10e384e6b8912ded92db64c58be8139d9ae23fb8361e5fc139d8e4f8fc601bc2"}, ] +python-dateutil = [ + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, +] python-json-logger = [ {file = "python-json-logger-0.1.7.tar.gz", hash = "sha256:aeee3edcf155e1d8bf2fb11330b7cc24b2a9488607d8a96ff7dd7db0a002b4d3"}, ] @@ -1529,6 +1633,37 @@ pytz = [ {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, ] +pyyaml = [ + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, +] redis = [ {file = "redis-2.10.6-py2.py3-none-any.whl", hash = "sha256:8a1900a9f2a0a44ecf6e8b5eb3e967a9909dfed219ad66df094f27f7d6f330fb"}, {file = "redis-2.10.6.tar.gz", hash = "sha256:a22ca993cea2962dbb588f9f30d0015ac4afcc45bee27d3978c0dbe9e97c6c0f"}, diff --git a/saas/pyproject.toml b/saas/pyproject.toml index 2a4064566..92f000445 100644 --- a/saas/pyproject.toml +++ b/saas/pyproject.toml @@ -102,6 +102,7 @@ django-mptt = "0.11.0" pyinstrument = "3.1.3" redis = "2.10.6" django-redis = "4.11.0" +apigw-manager = "^1.0.0" [tool.poetry.dev-dependencies] # For flake8 support pyproject.toml diff --git a/saas/requirements.txt b/saas/requirements.txt index 56124644d..80f16701b 100644 --- a/saas/requirements.txt +++ b/saas/requirements.txt @@ -1,7 +1,10 @@ aenum==2.2.6 amqp==1.4.9 anyjson==0.3.3 +apigw-manager==1.0.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" billiard==3.3.0.23 +bkapi-bk-apigateway==1.0.3; python_full_version >= "3.6.1" and python_version < "4.0" and python_full_version < "4.0.0" +bkapi-client-core==1.1.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version < "4.0" celery==3.1.25 certifi==2021.5.30; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" cffi==1.14.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" @@ -9,6 +12,7 @@ charset-normalizer==2.0.4; python_full_version >= "3.6.0" and python_version >= coreapi==2.3.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" coreschema==0.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" cryptography==3.3.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") +curlify==2.2.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" dataclasses==0.7; python_version >= "3.6" and python_version < "3.7" decorator==5.0.9; python_version >= "3.5" django-celery==3.2.1 @@ -22,6 +26,7 @@ django==2.2.24; python_version >= "3.5" djangorestframework==3.11.2; python_version >= "3.5" dogpile.cache==0.9.2 drf-yasg==1.17.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") +future==0.18.2; python_full_version >= "3.6.1" and python_full_version < "4.0.0" httplib2==0.19.0 idna==2.10; python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3" inflection==0.5.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" @@ -39,15 +44,18 @@ pyinstrument-cext==0.2.4 pyinstrument==3.1.3 pyjwt==1.7.1 pyparsing==2.4.7; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +python-dateutil==2.8.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" python-json-logger==0.1.7 pytz==2020.1 +pyyaml==5.4.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" redis==2.10.6 requests==2.26.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") ruamel.yaml.clib==0.2.6; platform_python_implementation == "CPython" and python_version < "3.10" and (python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3") and python_version >= "3.5" ruamel.yaml==0.17.10; python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3" six==1.15.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") sqlparse==0.4.2; python_version >= "3.5" +typing-extensions==3.10.0.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" uritemplate==3.0.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" -urllib3==1.26.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" +urllib3==1.26.6; python_full_version >= "3.6.1" and python_version < "4" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4") werkzeug==1.0.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") whitenoise==5.1.0; python_version >= "3.5" and python_version < "4" diff --git a/saas/requirements_dev.txt b/saas/requirements_dev.txt index 1cd72076b..5d359ac3d 100644 --- a/saas/requirements_dev.txt +++ b/saas/requirements_dev.txt @@ -1,10 +1,13 @@ aenum==2.2.6 amqp==1.4.9 anyjson==0.3.3 +apigw-manager==1.0.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" appdirs==1.4.4; python_full_version >= "3.6.2" atomicwrites==1.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.4.0" attrs==21.2.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" billiard==3.3.0.23 +bkapi-bk-apigateway==1.0.3; python_full_version >= "3.6.1" and python_version < "4.0" and python_full_version < "4.0.0" +bkapi-client-core==1.1.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version < "4.0" black==21.7b0; python_full_version >= "3.6.2" celery==3.1.25 certifi==2021.5.30; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" @@ -15,7 +18,9 @@ colorama==0.4.4; sys_platform == "win32" and python_version >= "3.6" and python_ converge==0.9.8 coreapi==2.3.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" coreschema==0.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +coverage==6.1.2; python_version >= "3.6" cryptography==3.3.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") +curlify==2.2.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" dataclasses==0.7; python_version >= "3.6" and python_version < "3.7" decorator==5.0.9; python_version >= "3.5" django-celery==3.2.1 @@ -32,6 +37,7 @@ dogpile.cache==0.9.2 drf-yasg==1.17.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") flake8-comprehensions==3.5.0; python_version >= "3.6" flake8==3.9.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" +future==0.18.2; python_full_version >= "3.6.1" and python_full_version < "4.0.0" httplib2==0.19.0 idna==2.10; python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3" importlib-metadata==4.6.3; python_version < "3.8" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.5.0" and python_version < "3.8" and python_version >= "3.6") and (python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.4.0" and python_version >= "3.6" and python_version < "3.8") and python_full_version >= "3.6.2" @@ -62,10 +68,13 @@ pyinstrument==3.1.3 pyjwt==1.7.1 pyparsing==2.4.7; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" pyproject-flake8==0.0.1a2 +pytest-cov==3.0.0; python_version >= "3.6" pytest-django==4.1.0; python_version >= "3.5" pytest==6.2.2; python_version >= "3.6" +python-dateutil==2.8.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" python-json-logger==0.1.7 pytz==2020.1 +pyyaml==5.4.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" redis==2.10.6 regex==2021.8.3; python_full_version >= "3.6.2" requests==2.26.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") @@ -81,9 +90,9 @@ types-pytz==2021.1.2 types-redis==3.5.6 types-requests==2.25.6 types-six==0.1.9 -typing-extensions==3.10.0.0; python_version < "3.8" and python_full_version >= "3.6.2" and python_version >= "3.6" +typing-extensions==3.10.0.0; python_version < "3.8" and python_full_version >= "3.6.2" and python_version >= "3.6" and python_full_version < "4.0.0" uritemplate==3.0.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" -urllib3==1.26.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" +urllib3==1.26.6; python_full_version >= "3.6.1" and python_version < "4" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4") werkzeug==1.0.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") whitenoise==5.1.0; python_version >= "3.5" and python_version < "4" zipp==3.5.0; python_version < "3.8" and python_version >= "3.6" diff --git a/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml b/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml new file mode 100644 index 000000000..b0373e828 --- /dev/null +++ b/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml @@ -0,0 +1,1737 @@ +swagger: '2.0' +basePath: / +info: + version: '0.1' + title: API Gateway Resources + description: '' +schemes: +- http +paths: + /api/v1/engine/batch-search: + post: + operationId: engine_batch_search + description: 批量检索 + tags: + - engine + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/batch-search + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.engine} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/engine/healthz: + get: + operationId: engine_healthz + description: 检查engine服务是否健康 + tags: + - engine + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: get + path: /healthz + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.engine} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/engine/ping: + get: + operationId: engine_ping + description: 检查engine连通性 + tags: + - engine + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: get + path: /ping + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.engine} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/engine/search: + post: + operationId: engine_search + description: 检索 + tags: + - engine + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/search + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.engine} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/engine/version: + get: + operationId: engine_version + description: 检查engine程序版本 + tags: + - engine + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: get + path: /version + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.engine} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems: + post: + operationId: system_create + description: 新增 system + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/model/systems + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}: + get: + operationId: system_get + description: 查询 system + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/model/systems/{system_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + put: + operationId: system_update + description: 更新 system + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/model/systems/{system_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/action/{action_id}/policies: + delete: + operationId: system_delete_action_policies + description: 删除action的policies + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/action/{action_id}/policies + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/actions: + delete: + operationId: system_batch_delete_actions + description: 批量删除actions + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/actions + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + post: + operationId: system_add_actions + description: 新增actions + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/model/systems/{system_id}/actions + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/actions/{action_id}: + delete: + operationId: system_delete_action + description: 删除action + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/actions/{action_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + put: + operationId: system_update_action + description: 更新action + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/model/systems/{system_id}/actions/{action_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/clients: + get: + operationId: system_get_clients + description: 查询 system clients + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/model/systems/{system_id}/clients + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/configs/{name}: + post: + operationId: system_add_configs + description: 配置新增name=common_actions/feature_shield_rules/resource_creator_actions + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/model/systems/{system_id}/configs/{name} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + put: + operationId: system_update_configs + description: 配置更新name=common_actions/feature_shield_rules/resource_creator_actions + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/model/systems/{system_id}/configs/{name} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/instance-selections: + delete: + operationId: system_batch_delete_instance_selections + description: 批量删除 instance-selections + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/instance-selections + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + post: + operationId: system_add_instance_selections + description: 新增instance_selections + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/model/systems/{system_id}/instance-selections + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/instance-selections/{instance_selection_id}: + delete: + operationId: system_delete_instance_selection + description: 删除 instance_selection + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/instance-selections/{instance_selection_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + put: + operationId: system_update_instance_selection + description: 更新 instance_selection + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/model/systems/{system_id}/instance-selections/{instance_selection_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/query: + get: + operationId: system_query + description: 查询 system 通用信息 + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/model/systems/{system_id}/query + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/resource-types: + delete: + operationId: system_batch_delete_resource_types + description: 批量删除 resource_type + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/resource-types + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + post: + operationId: system_add_resource_types + description: 新增resource_type + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/model/systems/{system_id}/resource-types + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/resource-types/{resource_type_id}: + delete: + operationId: system_delete_resource_types + description: 删除 resource_type + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/model/systems/{system_id}/resource-types/{resource_type_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + put: + operationId: system_update_resource_types + description: 更新 resource_type + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/model/systems/{system_id}/resource-types/{resource_type_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/model/systems/{system_id}/token: + get: + operationId: system_get_token + description: 查询 system token + tags: + - model + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/model/systems/{system_id}/token + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/application/: + post: + operationId: application + description: 接入系统权限申请 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/application/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/batch_instance/: + post: + operationId: authorization_batch_instance + description: 批量操作批量资源授权回收, deprecated + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/batch_instance/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/batch_path/: + post: + operationId: authorization_batch_path + description: 批量操作批量拓扑层级授权/回收 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/batch_path/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/batch_resource_creator_action/: + post: + operationId: authorization_batch_resource_creator_action + description: 新建关联授权 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/batch_resource_creator_action/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/instance/: + post: + operationId: authorization_instance + description: 单个资源授权回收, deprecated + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/instance/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/path/: + post: + operationId: authorization_path + description: 单个拓扑层级授权/回收 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/path/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/resource_creator_action/: + post: + operationId: authorization_resource_creator_action + description: 新建关联授权 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/resource_creator_action/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/authorization/resource_creator_action_attribute/: + post: + operationId: authorization_resource_creator_action_attribute + description: 新建关联授权-属性授权 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/authorization/resource_creator_action_attribute/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/grade_managers/: + post: + operationId: management_grade_managers + description: 创建分级管理员 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/management/grade_managers/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/grade_managers/{id}/groups/: + get: + operationId: management_grade_manager_groups + description: 分级管理员的用户组列表 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/management/grade_managers/{id}/groups/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + post: + operationId: management_grade_manager_create_groups + description: 分级管理员批量创建用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/management/grade_managers/{id}/groups/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/grade_managers/{id}/members/: + delete: + operationId: management_delete_grade_manager_members + description: 批量删除分级管理员成员 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/open/management/grade_managers/{id}/members/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + get: + operationId: management_grade_manager_members + description: 分级管理员成员列表 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/management/grade_managers/{id}/members/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + post: + operationId: management_add_grade_manager_members + description: 批量添加分级管理员成员 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/management/grade_managers/{id}/members/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/groups/applications/: + post: + operationId: management_groups_applications + description: 创建用户组申请单 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/management/groups/applications/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/groups/{id}/: + delete: + operationId: management_grade_manager_delete_group + description: 分级管理员删除用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/open/management/groups/{id}/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + put: + operationId: management_grade_manager_update_group + description: 分级管理员更新用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/open/management/groups/{id}/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/groups/{id}/members/: + delete: + operationId: management_delete_group_members + description: 用户组删除成员 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/open/management/groups/{id}/members/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + get: + operationId: management_group_members + description: 用户组成员列表 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/management/groups/{id}/members/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + post: + operationId: management_add_group_members + description: 用户组添加成员 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/management/groups/{id}/members/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/groups/{id}/policies/: + post: + operationId: management_groups_policies + description: 用户组授权 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/management/groups/{id}/policies/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/users/grade_managers/: + get: + operationId: management_users_grade_managers + description: 用户加入的分级管理员列表 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/management/users/grade_managers/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/open/management/users/grade_managers/{id}/groups/: + get: + operationId: management_users_grade_managers_groups + description: 用户在某个分级管理员下加入的用户组列表 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/management/users/grade_managers/{id}/groups/ + matchSubpath: false + timeout: 0 + upstreams: {} + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/policy/auth: + post: + operationId: policy_auth + description: 直接鉴权 + tags: + - policy + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/policy/auth + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/policy/auth_by_actions: + post: + operationId: policy_auth_by_actions + description: 批量action直接鉴权 + tags: + - policy + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/policy/auth_by_actions + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/policy/auth_by_resources: + post: + operationId: policy_auth_by_resources + description: 批量资源直接鉴权 + tags: + - policy + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/policy/auth_by_resources + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/policy/query: + post: + operationId: policy_query + description: 策略查询 + tags: + - policy + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/policy/query + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/policy/query_by_actions: + post: + operationId: policy_query_by_actions + description: 批量拉取一批操作的权限策略 + tags: + - policy + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/policy/query_by_actions + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/policy/query_by_ext_resources: + post: + operationId: policy_query_by_ext_resources + description: 批量第三方依赖鉴权策略查询 + tags: + - policy + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/policy/query_by_ext_resources + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/systems/{system_id}/policies: + get: + operationId: system_policies + description: 拉取系统下某个操作的策略列表 + tags: + - system + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/systems/{system_id}/policies + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/systems/{system_id}/policies/-/subjects: + get: + operationId: system_policies_subjects + description: 根据策略 ID 拉群策略对应的用户信息 + tags: + - system + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/systems/{system_id}/policies/-/subjects + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/systems/{system}/policies/{policy_id}: + get: + operationId: system_get_policy + description: 获取某条策略详情 + tags: + - system + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/systems/{system}/policies/{policy_id} + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /api/v1/web/: + x-bk-apigateway-method-any: + operationId: api_v1_web_any + description: SaaS调用后台 API 入口 + tags: + - web + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: true + backend: + type: HTTP + method: any + path: /api/v1/web/ + matchSubpath: true + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /healthz: + get: + operationId: healthz + description: 接口检查服务是否健康 + tags: + - basic + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /healthz + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /metrics: + get: + operationId: metrics + description: 接口暴露程序metrics + tags: + - basic + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /metrics + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /ping: + get: + operationId: ping + description: 接口检查连通性 + tags: + - basic + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /ping + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] + /version: + get: + operationId: version + description: 接口检查程序版本 + tags: + - basic + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /version + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: {} + authConfig: + userVerifiedRequired: false + appVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [] diff --git a/saas/resources/apigateway/definition.yaml b/saas/resources/apigateway/definition.yaml new file mode 100644 index 000000000..44f727508 --- /dev/null +++ b/saas/resources/apigateway/definition.yaml @@ -0,0 +1,27 @@ +apigateway: + description: "蓝鲸权限中心 API" + is_public: true + maintainers: + - "admin" + +release: + comment: "auto release the first version while installing" + +stage: + name: "prod" + vars: + backend: "{{ settings.BK_IAM_BACKEND_SVC }}" + engine: "{{ settings.BK_IAM_ENGINE_SVC }}" + proxy_http: + timeout: 180 + upstreams: + loadbalance: "roundrobin" + hosts: + - host: "http://127.0.0.1" + weight: 100 + transform_headers: + set: + X-Bkapi-From: apigw + +resource_docs: + basedir: "{{ settings.BK_APIGW_RESOURCE_DOCS_BASE_DIR }}" diff --git a/saas/resources/apigateway/docs/zh/__api_v1_model_config_action_groups.md.j2 b/saas/resources/apigateway/docs/zh/__api_v1_model_config_action_groups.md.j2 new file mode 100644 index 000000000..f0b17c522 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/__api_v1_model_config_action_groups.md.j2 @@ -0,0 +1,23 @@ +#### Parameters + +路径参数 + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +参数 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| name |string | 是 | 操作组名称 | +| name_en | string | 是 | 操作组英文名,国际化时切换到英文版本显示 | +| actions | Array(Object) | 否 | 操作列表 | +| sub_groups | Array(Object) | 否 | 下一级操作组 | + +注意: + +1. 最多`两级`操作组(即第一级`sub_gropus`下的操作组不能有下一级`sub_groups`), 如果嵌套超过两级, 会返回错误 `1901400(more than 2-levels action_group, current only support 2-levels)` +2. 同一个操作组的`actions`和`sub_groups` 不能同时为空 `1901400(actions and sub_groups can't be empty at the same time)` +3. action 可以挂在一级或二级的`操作组`上, 但是, 同一个 action 只能挂在一个`一级操作组`/`二级操作组`下; 即, action_id 全局 json 内唯一; `1901400(one action can belong only one group)` +4. 会校验每一个`action_id`; 必须是系统注册的合法`action_id`; 所以使用接口调用注册或者使用 migration 注册时, `action_id`对应的操作必须先注册, 再更新`action_groups` diff --git a/saas/resources/apigateway/docs/zh/__api_v1_model_config_common_actions.md.j2 b/saas/resources/apigateway/docs/zh/__api_v1_model_config_common_actions.md.j2 new file mode 100644 index 000000000..648c77215 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/__api_v1_model_config_common_actions.md.j2 @@ -0,0 +1,15 @@ +#### Parameters + +路径参数 + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +参数 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| name |string | 是 | 常用操作名称 | +| name_en | string | 是 | 常用操作英文名,国际化时切换到英文版本显示 | +| actions | Array(Object) | 是 | 操作列表 | diff --git a/saas/resources/apigateway/docs/zh/__api_v1_model_config_feature_shield_rules.md.j2 b/saas/resources/apigateway/docs/zh/__api_v1_model_config_feature_shield_rules.md.j2 new file mode 100644 index 000000000..e1ead4fe3 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/__api_v1_model_config_feature_shield_rules.md.j2 @@ -0,0 +1,45 @@ +#### Parameters + +路径参数 + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +参数 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| effect |string | 是 | 支持黑白名单,值为 deny 或 allow | +| feature | string | 是 | 开启或关闭的功能 | +| action | Object | 是 | 操作 | + +feature 字段枚举值说明: + +| 枚举值 | 说明 | +|:---|:---|:---| +| application.custom_permission.grant | 申请自定义权限 | +| application.custom_permission.renew | 申请自定义权限续期 | +| user_permission.custom_permission.delete | 自定义权限删除 | + + +action 字段说明: + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | Action 的唯一标识,`特别说明:` 如果功能是针对整个接入系统,则 id 为 * | + + +`特别说明`: +1. 多条 allow/deny 规则判断最终 effect 的逻辑(类似 Nginx 的 IP 白名单判断),即判断某个功能开启或关闭逻辑: + +```bash +在某个功能下的该系统的某个Action的开启与否:allow *[开启] > allow action_id[开启] > deny *[关闭] > deny action_id[关闭] > 默认开启 +(1)如果存在allow * 或 allow action_id 的规则匹配,则开启 +(3)如果不存在allow * 和 allow action_id 规则,但有deny * 或者deny action_id 规则匹配,则关闭 +(4)如果没有任何规则匹配,则默认开启 + +一般来说,只需要配置屏蔽的功能即可 +``` + +2. 对于依赖操作,如果被屏蔽了,则不会创建依赖操作,比如 edit 依赖 view,但是 view 被屏蔽了,则申请 edit 权限时,不会创建其依赖操作 view diff --git a/saas/resources/apigateway/docs/zh/__api_v1_model_config_resource_creator_actions.md.j2 b/saas/resources/apigateway/docs/zh/__api_v1_model_config_resource_creator_actions.md.j2 new file mode 100644 index 000000000..cbfa103cd --- /dev/null +++ b/saas/resources/apigateway/docs/zh/__api_v1_model_config_resource_creator_actions.md.j2 @@ -0,0 +1,40 @@ +#### Parameters + +路径参数 + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +参数 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| config | array(object) | 是 | 新建关联的配置文件,包含了每种资源类型对应的创建时可以对创建者进行授权的 Action | + +config 里的每个元素的字段说明: + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 资源类型的唯一标识 | +| actions | array(object) | 是 | 对应资源被创建时可以对创建者进行授权的 Action 列表 | +| sub_resource_types | array(object) | 否 |子资源类型相关可授权的 Action 相关配置信息,列表每个元素同 config 列表里的每个元素一样,这是个递归结构| + +actions 里的每个元素的字段说明: + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | Action 的唯一标识 | +| required | bool | 是 | 该 Action 是否是必须的,即后续权限中心支持企业和用户修改创建者赋权时,该 Action 能否不被选择授予 | + +**`required 字段特别说明`** + +> 假设资源类型 host 产生时可以对 host_edit 、host_view、host_delete 这 3 个权限授权,且 host_delete 配置 required=true + +- 后续权限中心将支持用户和企业自定义这个新建关联的配置时,host_delete 是必选的,无法去除 +- 如果用户自定义新建管理的配置是 host 产生时对 host_view、host_delete 这 2 个权限授权(host_edit 和 host_view 由于 required=false,所以是可以配置为不授权的),那么该用户在接入系统新增 host 后,自动拥有 host_view 和 host_delete + + +`注意:` +1. 层级结构是依据资源的层级 +2. 后续权限中心将会支持这份配置可由企业全局修改和每个用户自定义 diff --git a/saas/resources/apigateway/docs/zh/_api_v1_engine_search.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_engine_search.md.j2 new file mode 100644 index 000000000..4fc9ae832 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_engine_search.md.j2 @@ -0,0 +1,22 @@ +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system |string | 是 | 系统唯一标识 | +| subject_type | string | 是 | user/group/all | +| action | object | 是 | 操作 | +| resources | Array(resource_node) | 是 | 资源实例, 资源类型的顺序必须操作注册时的顺序一致 | +| limit | int | 是 | 最大返回subject数量 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +resource_node + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| id | 字符串 | 是 | 资源实例 ID | +| attribute | 对象 | 是 | 资源属性 | diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_actions.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_actions.md.j2 new file mode 100644 index 000000000..11acbea60 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_actions.md.j2 @@ -0,0 +1,39 @@ +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 操作 id, 系统下唯一, 只允许小写字母开头、包含小写字母、数字、下划线(_)和连接符(-). 最长 32 个字符. | +| name |string | 是 | 操作名称,系统下唯一| +| name_en | string | 是 | 操作英文名,国际化时切换到英文版本显示| +| description |string | 否 | 操作描述 | +| description_en | string | 否 | 操作描述英文,国际化时切换到英文版本显示 | +| type | string | 否 | 操作的类型,枚举值包括`create\delete\view\edit\list\manage\execute\use` 比如创建类操作需要标识为"create",无法分类可为空字符串 | +| related_resource_types | Array(Object) | 否 | 操作的对象,资源类型列表,列表顺序与`产品展示`、`鉴权校验` 顺序 必须保持一致。`如果操作无需关联资源实例,这里为空即可。` **注意这是一个有序的列表!**: | +| related_actions | Array(string) | 否 | 操作的依赖操作, 由操作 ID 组成的字符串列表, 用于在申请权限时同时创建依赖权限 | +| version | int | 否 | 版本号,允许为空,仅仅作为在权限中心上进行 New 的更新提醒 | + +related_resource_types 里的元素 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system_id | string | 是 | 资源类型的来源系统,可以是自身系统或其他系统 | +| id | string | 是 | 资源类型 ID,操作关联多个资源类型时,`同一个related_resource_types里 id 不能重复` | +| name_alias | string | 否 | 资源类型名称的别名,同一个资源类型对于不同 Action 可以有各自的显示名称 +| name_alias_en | string | 否 | 资源类型名称的别名英文名 | +| selection_mode | string | 否 | 选择类型, 即资源在权限中心产品上配置权限时的作用范围, 可选: `instance`/`attribute`/`all`, 如果不设置, 默认为`instance` | +| related_instance_selections | Array(Object) | 否 | 关联的实例视图,即资源在权限中心产品上配置权限时的选择方式; 可以配置本系统的实例视图, 也可以配置其他系统的实例视图(如果`selection_mode=attribute`则该字段不用配置; 如果没有设置`selection_mode`或`selection_mode=instance/all`, 此时这个字段不能为空) | + +related_instance_selections 里的元素 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system_id | string | 是 | 实例视图的来源系统 ID | +| id |string | 是 | 实例视图 ID | +| ignore_iam_path | bool | 否 | 是否配置的权限忽略路径,`默认为false` | + +注册后,IAM 配置权限时拉取资源的逻辑 + +**重要说明:** +- Action 关联的资源类型必须在权限中心已经注册的,否则 Action 将注册失败 +- 若关联的资源类型的自身系统的,则需要先注册该资源类型 +- 若关联的资源类型是依赖其他系统的,则需要等依赖系统注册该资源类型后才可以进行该 Action 注册 diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_instance_actions_delete.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_instance_actions_delete.md.j2 new file mode 100644 index 000000000..c42a91d17 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_instance_actions_delete.md.j2 @@ -0,0 +1,2 @@ +说明: +- 删除 Action 成功后,将会删除该 Action 相关权限,该删除操作不可逆,请谨慎调用 diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_instance_selections.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_instance_selections.md.j2 new file mode 100644 index 000000000..3560a821f --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_instance_selections.md.j2 @@ -0,0 +1,16 @@ +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 实例视图 id, 系统下唯一, 只允许小写字母开头、包含小写字母、数字、下划线(_)和连接符(-),最长 32 个字符. | +| name |string | 是 | 实例视图名称,系统下唯一 | +| name_en | string | 是 | 实例视图的英文名,国际化时切换到英文版本显示,系统下唯一 | +| is_dynamic | bool | 否 | 是否是动态拓扑视图,`默认为false` | +| resource_type_chain | Array(Object) | 是 | 资源类型的层级链路 | + +resource_type_chain 里的元素 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system_id | string | 是 | 资源类型的来源系统 ID | +| id |string | 是 | 资源类型 ID | diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_instance_selections_delete.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_instance_selections_delete.md.j2 new file mode 100644 index 000000000..70e5b6cdf --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_instance_selections_delete.md.j2 @@ -0,0 +1,2 @@ +必须满足以下条件才能成功删除实例视图: +1. 该实例视图没有被本系统的 Action 关联资源操作引用,具体遍历所有 Action 的 related_resource_types 中的 related_instance_selections 是否存在该实例视图 diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_resource_types.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_resource_types.md.j2 new file mode 100644 index 000000000..443beffb1 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_resource_types.md.j2 @@ -0,0 +1,26 @@ +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 资源类型 id, 系统下唯一, 只允许小写字母开头、包含小写字母、数字、下划线(_)和连接符(-),最长 32 个字符. | +| name |string | 是 | 资源类型名称,系统下唯一 | +| name_en | string | 是 | 资源类型英文名,国际化时切换到英文版本显示 | +| description |string | 否 | 资源类型名称,系统下唯一 | +| description_en | string | 否 | 资源类型英文名,国际化时切换到英文版本显示 | +| parents | Array[Object] | 否 | 资源类型的直接上级,可多个直接上级,可以是自身系统的资源类型或其他系统的资源类型, 可为空列表,不允许重复,数据仅用于权限中心产品上显示| +| provider_config | Object | 是 | 权限中心调用查询资源实例接口的配置文件,与 system.provider_config.host 配合使用 | +| version | int | 否 | 版本号,允许为空,仅仅作为在权限中心上进行 New 的更新提醒 | + +parents 元素参数说明 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system_id | string | 是 | 直接上级资源类型的来源系统 ID | +| id |string | 是 | 直接上级资源类型 ID | + +provider_config 内元素 参数: + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| path | string | 是 | 权限中心调用查询资源实例接口的 URL 的 PATH,与 system.provider_config.host 配合使用 | + diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_resource_types_delete.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_resource_types_delete.md.j2 new file mode 100644 index 000000000..3e07d07c8 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_resource_types_delete.md.j2 @@ -0,0 +1,3 @@ +必须同时满足以下两个条件才能成功删除资源类型 +1. 该资源类型不作为其他的上级资源,具体遍历所有资源类型的 parents 是否存在该资源类型 +2. 该资源类型不作为 Action 的操作对象资源类型,具体遍历所有 Action 的 related_resource_types 是否存在该资源类型 diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system.md.j2 new file mode 100644 index 000000000..12383c777 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system.md.j2 @@ -0,0 +1,19 @@ +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 系统 id, 全局唯一, 只允许小写字母开头、包含小写字母、数字、下划线(_)和连接符(-), 最长 32 个字符. | +| name |string | 是 | 系统名称,全局唯一 | +| name_en | string | 是 | 系统英文名,国际化时切换到英文版本显示 | +| description |string | 否 | 系统描述,全局唯一 | +| description_en | string | 否 | 系统描述英文,国际化时切换到英文版本显示 | +| clients | string | 是 | 有权限调用的客户端,即有权限调用的 app_code 列表,多个使用英文逗号分隔,注册系统时会校验 Header 头里的 app_code 必须在列表里 | +| provider_config | Object | 是 | 权限中心回调接入系统的配置文件 | + +provider_config 内元素 参数: + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| host | string | 是 | 权限中心调用查询资源实例接口的 HOST,格式:scheme://netloc,与 resource_type.provider_config.path 配合使用 | +| auth | string | 是 | 权限中心调用查询资源实例接口的鉴权方式, 当前可选: `none`/`basic`| +| healthz | string | 否 | 权限中心调用接入系统的 healthz 检查系统是否健康; 与 provider_config.host 配合使用, `例如system.provider_config.host=http://cmdb.consul, provider_config.healthz=/healthz/`, 那么将调用`http://cmdb.consul/healthz/`检查系统是否健康. | diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_action_groups.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_action_groups.md.j2 new file mode 100644 index 000000000..5cf04cd88 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_action_groups.md.j2 @@ -0,0 +1,49 @@ +### 注册操作组 + +{% include '__api_v1_model_config_action_groups.md.j2' %} + +#### Request + +```json +[ + { + "name": "管理权限", + "name_en": "Admin Permissions", + "actions": [ + { + "id": "create_biz" + }, + { + "id": "delete_biz" + } + ] + }, + { + "name": "运维", + "name_en": "Devops Permissions", + "sub_groups": [ + { + "name": "主机权限", + "name_en": "Host Permissions", + "actions": [ + { + "id": "view_host" + }, + { + "id": "create_host" + } + ] + } + ] + } +] +``` +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_common_actions.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_common_actions.md.j2 new file mode 100644 index 000000000..ac69676fc --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_common_actions.md.j2 @@ -0,0 +1,30 @@ +### 注册常用操作 + + +{% include '__api_v1_model_config_common_actions.md.j2' %} + +#### Request + +```json +[ + { + "name": "测试", + "name_en": "test", + "actions": [ + { + "id": "biz_delete" + } + ] + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_feature_shield_rules.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_feature_shield_rules.md.j2 new file mode 100644 index 000000000..b6860f8cb --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_feature_shield_rules.md.j2 @@ -0,0 +1,36 @@ +### 注册功能开关规则 + +{% include '__api_v1_model_config_feature_shield_rules.md.j2' %} + +#### Request + +```json +[ + // 对于自定义申请,屏蔽整个该接入系统所有Action,即该接入系统不支持自定义申请 + { + "effect": "deny", + "feature": "application.custom_permission.grant", + "action": { + "id": "*" + } + }, + // 对于个人权限,接入系统某个Aciton的自定义权限不允许被删除 + { + "effect": "deny", + "feature": "user_permission.custom_permission.delete", + "action": { + "id": "access_business" + } + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_resource_creator_actions.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_resource_creator_actions.md.j2 new file mode 100644 index 000000000..d73f9b1b4 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_add_configs_resource_creator_actions.md.j2 @@ -0,0 +1,239 @@ +### 注册新建关联配置 + +{% include '__api_v1_model_config_resource_creator_actions.md.j2' %} + +#### Request + +- [样例] cmdb 可能的新建关联配置 + +```json +{ + "config":[ + { + "id":"biz", + "actions":[ + { + "id":"biz_edit", + "required":false + }, + { + "id":"biz_view", + "required":true + }, + { + "id":"set_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"set", + "actions":[ + { + "id":"set_edit", + "required":false + }, + { + "id":"set_view", + "required":false + }, + { + "id":"module_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"module", + "actions":[ + { + "id":"module_edit", + "required":false + }, + { + "id":"module_view", + "required":false + }, + { + "id":"host_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"host", + "actions":[ + { + "id":"host_edit", + "required":false + }, + { + "id":"host_view", + "required":false + } + ] + } + ] + } + ] + } + ] + } + ] +} +``` + +- [样例] 标准运维新建关联配置 + +```json +{ + "config":[ + { + "id":"project", + "actions":[ + { + "id":"project_fast_create_task", + "required":false + }, + { + "id":"flow_create", + "required":false + }, + { + "id":"project_edit", + "required":false + }, + { + "id":"project_view", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"common_flow", + "actions":[ + { + "id":"common_flow_view", + "required":false + }, + { + "id":"common_flow_edit", + "required":false + }, + { + "id":"common_flow_delete", + "required":false + } + ] + }, + { + "id":"flow", + "actions":[ + { + "id":"flow_create_periodic_task", + "required":false + }, + { + "id":"flow_create_mini_app", + "required":false + }, + { + "id":"flow_create_task", + "required":false + }, + { + "id":"flow_delete", + "required":false + }, + { + "id":"flow_edit", + "required":false + }, + { + "id":"flow_view", + "required":false + } + ] + }, + { + "id":"mini_app", + "actions":[ + { + "id":"mini_app_create_task", + "required":false + }, + { + "id":"mini_app_delete", + "required":false + }, + { + "id":"mini_app_edit", + "required":false + }, + { + "id":"mini_app_view", + "required":false + } + ] + }, + { + "id":"periodic_task", + "actions":[ + { + "id":"periodic_task_view", + "required":false + }, + { + "id":"periodic_task_edit", + "required":false + }, + { + "id":"periodic_task_delete", + "required":false + } + ] + }, + { + "id":"task", + "actions":[ + { + "id":"task_view", + "required":false + }, + { + "id":"task_edit", + "required":false + }, + { + "id":"task_operate", + "required":false + }, + { + "id":"task_claim", + "required":false + }, + { + "id":"task_delete", + "required":false + }, + { + "id":"task_clone", + "required":false + } + ] + } + ] + } + ] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_config.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_config.md.j2 new file mode 100644 index 000000000..bc7521d8e --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_config.md.j2 @@ -0,0 +1,5 @@ +系统配置支持: +- action_groups: 操作组 +- common_actions: 常用操作 +- feature_shield_rules: 功能开关 +- resource_creator_actions: 新建关联 diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_action_groups.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_action_groups.md.j2 new file mode 100644 index 000000000..f7a4232cb --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_action_groups.md.j2 @@ -0,0 +1,51 @@ +### 更新操作组 + +整个列表完全覆盖更新 + +{% include '__api_v1_model_config_action_groups.md.j2' %} + +#### Request + +```json +[ + { + "name": "管理权限", + "name_en": "Admin Permissions", + "actions": [ + { + "id": "create_biz" + }, + { + "id": "delete_biz" + } + ] + }, + { + "name": "运维", + "name_en": "Devops Permissions", + "sub_groups": [ + { + "name": "主机权限", + "name_en": "Host Permissions", + "actions": [ + { + "id": "view_host" + }, + { + "id": "create_host" + } + ] + } + ] + } +] +``` +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_common_actions.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_common_actions.md.j2 new file mode 100644 index 000000000..bae03c16a --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_common_actions.md.j2 @@ -0,0 +1,31 @@ +### 更新常用操作 + +整个列表完全覆盖更新 + +{% include '__api_v1_model_config_common_actions.md.j2' %} + +#### Request + +```json +[ + { + "name": "测试", + "name_en": "test", + "actions": [ + { + "id": "biz_delete" + } + ] + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_feature_shield_rules.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_feature_shield_rules.md.j2 new file mode 100644 index 000000000..f8ff14aef --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_feature_shield_rules.md.j2 @@ -0,0 +1,38 @@ +### 更新功能开关规则 + +整个列表完全覆盖更新 + +{% include '__api_v1_model_config_feature_shield_rules.md.j2' %} + +#### Request + +```json +[ + // 对于自定义申请,屏蔽整个该接入系统所有Action,即该接入系统不支持自定义申请 + { + "effect": "deny", + "feature": "application.custom_permission.grant", + "action": { + "id": "*" + } + }, + // 对于个人权限,接入系统某个Aciton的自定义权限不允许被删除 + { + "effect": "deny", + "feature": "user_permission.custom_permission.delete", + "action": { + "id": "access_business" + } + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_resource_creator_actions.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_resource_creator_actions.md.j2 new file mode 100644 index 000000000..374f0e4f4 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_model_system_update_configs_resource_creator_actions.md.j2 @@ -0,0 +1,241 @@ +### 更新新建关联配置 + +整个列表完全覆盖更新 + +{% include '__api_v1_model_config_resource_creator_actions.md.j2' %} + +#### Request + +- [样例] cmdb 可能的新建关联配置 + +```json +{ + "config":[ + { + "id":"biz", + "actions":[ + { + "id":"biz_edit", + "required":false + }, + { + "id":"biz_view", + "required":true + }, + { + "id":"set_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"set", + "actions":[ + { + "id":"set_edit", + "required":false + }, + { + "id":"set_view", + "required":false + }, + { + "id":"module_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"module", + "actions":[ + { + "id":"module_edit", + "required":false + }, + { + "id":"module_view", + "required":false + }, + { + "id":"host_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"host", + "actions":[ + { + "id":"host_edit", + "required":false + }, + { + "id":"host_view", + "required":false + } + ] + } + ] + } + ] + } + ] + } + ] +} +``` + +- [样例] 标准运维新建关联配置 + +```json +{ + "config":[ + { + "id":"project", + "actions":[ + { + "id":"project_fast_create_task", + "required":false + }, + { + "id":"flow_create", + "required":false + }, + { + "id":"project_edit", + "required":false + }, + { + "id":"project_view", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"common_flow", + "actions":[ + { + "id":"common_flow_view", + "required":false + }, + { + "id":"common_flow_edit", + "required":false + }, + { + "id":"common_flow_delete", + "required":false + } + ] + }, + { + "id":"flow", + "actions":[ + { + "id":"flow_create_periodic_task", + "required":false + }, + { + "id":"flow_create_mini_app", + "required":false + }, + { + "id":"flow_create_task", + "required":false + }, + { + "id":"flow_delete", + "required":false + }, + { + "id":"flow_edit", + "required":false + }, + { + "id":"flow_view", + "required":false + } + ] + }, + { + "id":"mini_app", + "actions":[ + { + "id":"mini_app_create_task", + "required":false + }, + { + "id":"mini_app_delete", + "required":false + }, + { + "id":"mini_app_edit", + "required":false + }, + { + "id":"mini_app_view", + "required":false + } + ] + }, + { + "id":"periodic_task", + "actions":[ + { + "id":"periodic_task_view", + "required":false + }, + { + "id":"periodic_task_edit", + "required":false + }, + { + "id":"periodic_task_delete", + "required":false + } + ] + }, + { + "id":"task", + "actions":[ + { + "id":"task_view", + "required":false + }, + { + "id":"task_edit", + "required":false + }, + { + "id":"task_operate", + "required":false + }, + { + "id":"task_claim", + "required":false + }, + { + "id":"task_delete", + "required":false + }, + { + "id":"task_clone", + "required":false + } + ] + } + ] + } + ] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/_api_v1_open_authorization_path.md.j2 b/saas/resources/apigateway/docs/zh/_api_v1_open_authorization_path.md.j2 new file mode 100644 index 000000000..19c2490df --- /dev/null +++ b/saas/resources/apigateway/docs/zh/_api_v1_open_authorization_path.md.j2 @@ -0,0 +1,57 @@ +#### 前置说明 + +`resources.path`/`resources.paths[i]`的说明 + +示例 1: 拓扑层级授权到资源实例, *业务 1-集群 2-主机 1* + +```json +{ + "system": "bk_cmdb", + "type": "host", + "path": [ + { + "type": "biz", + "id": "1", + "name": "biz1" + }, + { + "type": "set", + "id": "2", + "name": "set2" + }, + { + "type": "host", + "id": "1", + "name": "host1" + } + ] +} +``` + +示例 2: 拓扑层级前缀, *业务 1-任意集群*, 此时只有业务 1 的集群下的主机会有权限 + +`注意`: + +- 业务 1 下的主机与业务 1 下任意集群的主机的定义是不一样的 + 1. `业务1下的主机`包含业务 1 下可能的`所有拓扑`下的所有主机 + 2. `业务1下集群的所有主机`, 只包含特定拓扑 `业务-集群` 下的所有主机 +- 为避免权限放大, 在拓扑层级授权时需要把选择到的拓扑节点的下一级的任意带上, 比如选择的是 `业务1`, 授权时传 `业务1-任意集群` + +```json +{ + "system": "bk_cmdb", + "type": "host", + "path": [ + { + "type": "biz", + "id": "1", + "name": "biz1" + }, + { + "type": "set", + "id": "*", + "name": "" + } + ] +} +``` diff --git a/saas/resources/apigateway/docs/zh/api_v1_web_any.md.j2 b/saas/resources/apigateway/docs/zh/api_v1_web_any.md.j2 new file mode 100644 index 000000000..fabf61e46 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/api_v1_web_any.md.j2 @@ -0,0 +1,13 @@ +### Web 通用接口 + +内部接口, 接入系统无需关注 + +#### Request + + +#### Response + + +```json +{} +``` diff --git a/saas/resources/apigateway/docs/zh/application.md.j2 b/saas/resources/apigateway/docs/zh/application.md.j2 new file mode 100644 index 000000000..6d13c4e5a --- /dev/null +++ b/saas/resources/apigateway/docs/zh/application.md.j2 @@ -0,0 +1,193 @@ +### 生成无权限申请URL + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +|system|字符串|是|系统 id| +|actions|数组|是|申请权限的操作| + +actions + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +|id|字符串|是|操作 id| +|related_resource_types|数组|是|操作关联的资源类型, `资源类型的顺序必须操作注册时的顺序一致`| + +related_resource_types + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +|system|字符串|是|资源类型的系统 id| +|type|字符串|是|资源类型| +|instances|数组[数组]|否|资源实例,可选| +|attributes|数组|否|实例属性,可选| + +related_resource_types.instances + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +|type|字符串|是|资源类型| +|id|字符串|是|资源实例 id| + +related_resource_types.attributes + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +|id|字符串|是|属性 key| +|name|字符串|是|属性 key 名称| +|values|数组|是|属性的可选值| + +related_resource_types.attributes.values + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +|id|字符串|是|属性 value| +|name|字符串|是|属性 value 名称| + +#### Request + +1. 无关联资源类型的操作示例: + +系统`bk_job`的`create_job`操作未关联资源类型 + +```json +{ + "system": "bk_job", # 权限的系统 + "actions": [ + { + "id": "create_job", # 操作id + "related_resource_types": [] # related_resource_types 空数组表示操作不关联资源类型 + } + ] +} +``` + +2. 资源拓扑路径的操作示例: + +系统`bk_job`的`view_job`操作关联资源类型`job`, 并且注册了实例视图 `业务(biz)`-`作业(job)`, 这个实例视图拓扑路径有2层 + +```json +{ + "system": "bk_job", # 权限的系统 + "actions": [ + { + "id": "view_job", # 操作id + "related_resource_types": [ + { + "system": "bk_job", # 资源类型所属的系统id + "type": "job", # 资源类型 + "instances": [ + [ # 一个数组表示一个实例的拓扑路径, 拓扑路径必须与实例视图的资源链路一致, 业务(biz)-作业(job) + { + "type": "biz", # 实例视图中资源的第一层业务 + "id": "biz1", + }, + { + "type": "job", # 实例视图中资源拓扑路径的第二层作业 + "id": "job1", + } + ] + ] + } + ] + } + ] +} +``` + +3. 关联多个资源类型的操作示例: + +系统`bk_job`的`execute_job`操作关联资源类型`job`与系统`bk_cmdb`的资源类型`host`, +`job`注册了实例视图 `业务(biz)`-`作业(job)`, 这个实例视图拓扑路径有2层, +`bk_cmdb`的资源类型`host`注册实例视图, `业务(biz)`-`集群(set)`-`模块(module)`-`主机(host)`, 这个实例视图拓扑路径有4层 + +```json +{ + "system": "bk_job", # 权限的系统 + "actions": [ + { + "id": "execute_job", # 操作id + "related_resource_types": [ # 关联几个资源类型, 这里就必须传几个item, 并且资源类型的顺序必须与注册操作时资源类型的顺序一致 + { + "system": "bk_job", + "type": "job", + "instances": [ + [ # 业务(biz)-作业(job) + { + "type": "biz", + "id": "biz1", + }, + { + "type": "job", + "id": "job1", + } + ] + ] + }, + { + "system": "bk_cmdb", # 资源类型所属的系统id + "type": "host", # 操作依赖的另外一个资源类型 + "instances": [ + [ # 4层的拓扑路径, 必须与实例视图的资源链路一致: 业务(biz)-集群(set)-模块(module)-主机(host) + { + "type": "biz", + "id": "biz1", + }, { + "type": "set", + "id": "set1", + }, { + "type": "module", + "id": "module1", + }, { + "type": "host", + "id": "host1", + } + ] + ], + "attributes": [ # 支持配置实例的属性值, attributes与instances的组合关系为AND + { + "id": "os", # 属性的key + "name": "操作系统", + "values": [ + { + "id": "linux", # 属性的value, 可以有多个 + "name": "linux" + } + ] + } + ] + } + ] + } + ] +} +``` + +#### Response + + +```json +{ + "data": { + "url": "https://{PAAS_DOMAIN}/o/bk_iam_app/perm-apply?system_id=bk_job&tid=09d432dccac74ec4aa17629f5f83715f" # 链接有效期10分钟 + }, + "result": true, + "code": 0, + "message": "OK" +} +``` + +data + +| 字段 | 类型 | 描述 | +|:---|:---|:---| +|url|字符串|权限申请重定向 URL| + + +返回结果错误说明 + +由于跳转申请后,产品上需要显示的时资源实例名称,而不是 ID,所以权限中心会回调查询接入系统 +1. 如果未提供查询相关接口,则错误码 code=1902204 +2. 如果查询不到资源实例的名称或接入系统不存在对应的资源实例,则错误码 code=1902416 +3. 会校验 `related_resource_types`操作关联的资源类型, `资源类型的顺序必须操作注册时的顺序一致`, 如果不一致, 错误码 `1902417` diff --git a/saas/resources/apigateway/docs/zh/authorization_batch_instance.md.j2 b/saas/resources/apigateway/docs/zh/authorization_batch_instance.md.j2 new file mode 100644 index 000000000..69d9f4564 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_batch_instance.md.j2 @@ -0,0 +1 @@ +Deprecated diff --git a/saas/resources/apigateway/docs/zh/authorization_batch_path.md.j2 b/saas/resources/apigateway/docs/zh/authorization_batch_path.md.j2 new file mode 100644 index 000000000..510e8062f --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_batch_path.md.j2 @@ -0,0 +1,122 @@ +### 批量资源拓扑授权/回收 + +对多个资源拓扑, 多个操作的授权与回收接口 + + +{% include '_api_v1_open_authorization_path.md.j2' %} + + +#### Parameters + + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| asynchronous | 布尔 | 是 | 是否异步调用, 默认 否, 当前只支持同步 | +| operate | 字符串 | 是 | grant 或 revoke | +| system | 字符串 | 是 | 系统 id | +| actions | 数组[对象] | 是 | 操作 | +| subject | 字符串 | 是 | 授权对象 | +| resources | 数组[对象] | 是 | 资源拓扑, 资源类型的顺序必须操作注册时的顺序一致| + +actions + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resources + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| paths | 数组[[对象]] | 是 | 批量资源拓扑,`最多1000个` | + +resources.paths + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 拓扑节点类型 ID | +| id | 字符串 | 是 | 拓扑节点实例 ID | +| name | 字符串 | 是 | 拓扑节点实例名称 | + +#### Request + +```json +{ + "asynchronous": false, + "operate": "grant", + "system": "bk_cmdb", + "actions": [ # 批量的操作 + { + "id": "edit_host" + } + ], + "subject": { + "type": "user", + "id": "admin" + }, + "resources": [ + { # 操作关联的资源类型, 必须与所有的actions都匹配, 资源类型的顺序必须操作注册时的顺序一致 + "system": "bk_cmdb", + "type": "host", + "paths": [ # 批量资源拓扑 + [ + { + "type": "biz", + "id": "1", + "name": "biz1" + }, + { + "type": "set", + "id": "*", + "name": "" + } + ] + ] + } + ] +} +``` + +#### Response + +| 字段 | 类型 | 描述 | +|:---|:---|:---| +| policy_id | 数值 | 权限策略 id | +| action | 对象 | 操作 | + +```json +{ + "code": 0, + "message": "ok", + "data": [ + { + "action": { + "id": "edit_host" + }, + "policy_id": 1 + } + ] +} +``` + +#### Response when async (暂未实现) + +```json +{ + "code": 0, + "message": "ok", + "data": { + "task_id": 1 // 任务id + } +} +``` + diff --git a/saas/resources/apigateway/docs/zh/authorization_batch_resource_creator_action.md.j2 b/saas/resources/apigateway/docs/zh/authorization_batch_resource_creator_action.md.j2 new file mode 100644 index 000000000..9f8d5502d --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_batch_resource_creator_action.md.j2 @@ -0,0 +1 @@ +deprecated diff --git a/saas/resources/apigateway/docs/zh/authorization_instance.md.j2 b/saas/resources/apigateway/docs/zh/authorization_instance.md.j2 new file mode 100644 index 000000000..69d9f4564 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_instance.md.j2 @@ -0,0 +1 @@ +Deprecated diff --git a/saas/resources/apigateway/docs/zh/authorization_path.md.j2 b/saas/resources/apigateway/docs/zh/authorization_path.md.j2 new file mode 100644 index 000000000..183a68517 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_path.md.j2 @@ -0,0 +1,116 @@ +### 资源拓扑授权/回收 + +对单个资源拓扑, 单个操作的授权与回收接口 + +`注意`: + +- `resources.type`的是操作关联的资源类型, `resources.path`是资源类型能选择的拓扑层级 +- `resources.path`的路径必须与接入系统注册的资源实例选择视图的拓扑层级一致, 否则授权的拓扑层级在权限中心会出现在视图中选择不中(打不上勾)的情况 + +{% include '_api_v1_open_authorization_path.md.j2' %} + +#### Parameters + + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| asynchronous | 布尔 | 是 | 是否异步调用, 默认 否, 当前只支持同步 | +| operate | 字符串 | 是 | grant 或 revoke | +| system | 字符串 | 是 | 系统 id | +| action | 字符串 | 是 | 操作 | +| subject | 字符串 | 是 | 授权对象 | +| resources | 数组[对象] | 是 | 资源拓扑, 资源类型的顺序必须操作注册时的顺序一致 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resources + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| path | 数组[对象] | 是 | 资源的拓扑 | + +resources.path + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 拓扑节点类型 ID | +| id | 字符串 | 是 | 拓扑节点实例 ID | +| name | 字符串 | 是 | 拓扑节点实例名称 | + +#### Request + +```json +{ + "asynchronous": false, # 默认false, 当前只支持同步 + "operate": "grant", # grant 授权 revoke 回收 + "system": "bk_cmdb", + "action": { + "id": "edit_host" + }, + "subject": { # 当前只能对user授权 + "type": "user", + "id": "admin" + }, + "resources": [ # 操作依赖多个资源类型的情况下, 表示一个组合资源, 资源类型的顺序必须操作注册时的顺序一致 + { + "system": "bk_cmdb", + "type": "host", + "path": [ + { + "type": "biz", + "id": "1", + "name": "biz1" + },{ + "type": "set", + "id": "*", + "name": "" + } + ] + } + ] +} +``` + +#### Response + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| policy_id | 数值 | 权限策略 id | + + +> Status: 200 OK + +```json +{ + "code": 0, + "message": "ok", + "data": { + "policy_id": 1 + } +} +``` + +#### Response when async (暂未实现) + +```json +{ + "code": 0, + "message": "ok", + "data": { + "task_id": 1 // 任务id + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/authorization_resource_creator_action.md.j2 b/saas/resources/apigateway/docs/zh/authorization_resource_creator_action.md.j2 new file mode 100644 index 000000000..9f8d5502d --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_resource_creator_action.md.j2 @@ -0,0 +1 @@ +deprecated diff --git a/saas/resources/apigateway/docs/zh/authorization_resource_creator_action_attribute.md.j2 b/saas/resources/apigateway/docs/zh/authorization_resource_creator_action_attribute.md.j2 new file mode 100644 index 000000000..ec7f1ab60 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/authorization_resource_creator_action_attribute.md.j2 @@ -0,0 +1,114 @@ +### 新建关联属性授权接口 + +#### 前置说明 + +* 背景: + - 接入系统上批量资源实例被创建时,对应的创建者应该需要赋予依赖这批实例的某个属性的相关权限 + - 比如批量作业创建时,创建者需要有属性为 creator=xxx 的作业的编辑、删除和查看权限 + +* 流程: + - 1. **用户**在**接入系统**上产生资源实例 + - 2. **接入系统**请求 API, **权限中心**根据新建关联配置对应创建者进行授权 + +* 接口描述: + - 接入系统根据资源实例创建,对创建者进行相关属性授权 + +* `接口特别说明` + - 新建关联的 Actions 对应的依赖资源类型必须 selection_mode 为 all 或 attribute(Action 无关联实例除外)且只能有一种依赖资源,否则新建关联授权时会被`自动忽略` + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | string | 是 | 系统唯一标识 | +| type | string | 是 | 资源类型的唯一标识 | +| creator | string | 是 | 资源实例的创建者 | +| attributes | array(object) | 是 | 资源属性列表,`多个属性之间的权限逻辑是AND` | + +attributes 列表的元素说明 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 资源属性的唯一标识 | +| name | string | 是 | 资源属性的名称 | +| values | array(object) | 是 | 资源属性的值,支持多个值,`多个值之间的权限逻辑是OR` | + +values 列表的元素说明 + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | string | 是 | 资源属性值的唯一标识 | +| name | string | 是 | 资源属性值的名称 | + + +#### Request + +```json +{ + "system": "bk_sops", + "type":"task", + "creator":"admin", + "attributes": [ + { + "id":"owner", + "name":"任务所属者", + "values": [ + { + "id": "admin", + "name": "admin(管理员)" + } + ] + } + ] +} +``` + +#### Response + +data 数组元素 + +| 字段 | 类型 | 描述 | +|:---|:---|:---| +|action|object| creator 被授权对应的 Action | +|policy_id|int| creator 被授权对应的策略 ID | + +action + +| 字段 | 类型 | 描述 | +|:---|:---|:---| +|id|string| 操作 ID | + + +```json +{ + "data": [ // 表示creator被授权对应的Action和策略ID列表 + { + "action": { + "id": "edit" + }, + "policy_id": 1 + }, + { + "action": { + "id": "list" + }, + "policy_id": 2 + }, + { + "action": { + "id": "delete" + }, + "policy_id": 3 + }, + { + "action": { + "id": "view" + }, + "policy_id": 4 + } + ], + "result": true, + "code": 0, + "message": "OK" +} +``` diff --git a/saas/resources/apigateway/docs/zh/engine_batch_search.md.j2 b/saas/resources/apigateway/docs/zh/engine_batch_search.md.j2 new file mode 100644 index 000000000..b9e20496a --- /dev/null +++ b/saas/resources/apigateway/docs/zh/engine_batch_search.md.j2 @@ -0,0 +1,66 @@ +### 批量检索有权限的subject列表 + +#### Parameters + +请求json是一个列表, 列表内的结构说明 + +{% include '_api_v1_engine_search.md.j2' %} + + +#### Request + + +```json +[ // 单个请求对象与search接口相同, 批量使用数组传多个请求对象 + { + "system": "bk_job", + "subject_type": "all", // all同时查询user与group + "action": { + "id": "execute" + }, + "resources": [{ // 资源类型的顺序必须操作注册时的顺序一致, 否则会导致鉴权失败! + "system": "bk_job", + "type": "job", + "id": "ping", + "attribute": { // 资源的属性值可能有多个, 目前支持string/int/boolean, 以及路径stringList + "os": "linux", + "_bk_iam_path_": ["/biz,1/set,2/"], + "is_ready": true, + "area_id": 200 + } + }, { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1", + "attribute": {} // 外部资源的属性由iam负责查询属性, 接入方不需要传入 + }], + "limit": 1000 // 最多返回的subject数量 + } +] +``` + +#### Response + + +```json +{ + "code": 0, + "message": "ok", + "data": { + "results": [ // 批量返回的数据, 每个请求对象一个数组, 顺序与请求对象的顺序一致 + [ // 返回subject的数组 + { + "type": "user", + "id": "admin", + "name": "admin" + }, + { + "type": "group", + "id": "1001", + "name": "测试用户组" + } + ] + ] + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/engine_healthz.md.j2 b/saas/resources/apigateway/docs/zh/engine_healthz.md.j2 new file mode 100644 index 000000000..a6ebff7d0 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/engine_healthz.md.j2 @@ -0,0 +1,13 @@ +### 检查engine健康状态 + +#### Request + +#### Response + +> 200 OK + +``` +ok +``` + +> 500 Internal Server Error diff --git a/saas/resources/apigateway/docs/zh/engine_ping.md.j2 b/saas/resources/apigateway/docs/zh/engine_ping.md.j2 new file mode 100644 index 000000000..c24b78717 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/engine_ping.md.j2 @@ -0,0 +1,11 @@ +### 检查engine是否启动 + +#### Request + +#### Response + +```json +{ + message: "pong" +} +``` diff --git a/saas/resources/apigateway/docs/zh/engine_search.md.j2 b/saas/resources/apigateway/docs/zh/engine_search.md.j2 new file mode 100644 index 000000000..8eb3a3a67 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/engine_search.md.j2 @@ -0,0 +1,56 @@ +### 检索有权限的subject列表 + +#### Parameters + +{% include '_api_v1_engine_search.md.j2' %} + +#### Request + + +```json +{ + "system": "bk_job", + "subject_type": "all", // all同时查询user与group + "action": { + "id": "execute" + }, + "resources": [{ // 资源类型的顺序必须操作注册时的顺序一致, 否则会导致鉴权失败! + "system": "bk_job", + "type": "job", + "id": "ping", + "attribute": { // 资源的属性值可能有多个, 目前支持string/int/boolean, 以及路径stringList + "os": "linux", + "_bk_iam_path_": ["/biz,1/set,2/"], + "is_ready": true, + "area_id": 200 + } + }, { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1", + "attribute": {} // 外部资源的属性由iam负责查询属性, 接入方不需要传入 + }], + "limit": 1000 // 最多返回的subject数量 +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": [ // 返回subject的数组 + { + "type": "user", + "id": "admin", + "name": "admin" + }, + { + "type": "group", + "id": "1001", + "name": "测试用户组" + } + ] +} +``` diff --git a/saas/resources/apigateway/docs/zh/engine_version.md.j2 b/saas/resources/apigateway/docs/zh/engine_version.md.j2 new file mode 100644 index 000000000..8b4dd815d --- /dev/null +++ b/saas/resources/apigateway/docs/zh/engine_version.md.j2 @@ -0,0 +1,15 @@ +### 获取engine程序版本 + +#### Request + +#### Response + +```json +{ + "buildTime": "2021-11-19_02:33:51", + "commit": "6ef6b5d3bfd0c5ff9b903082b156724c7c6c5c65", + "env": "", + "goVersion": "go version go1.16.3 darwin/amd64", + "version": "1.0.1" +} +``` diff --git a/saas/resources/apigateway/docs/zh/healthz.md.j2 b/saas/resources/apigateway/docs/zh/healthz.md.j2 new file mode 100644 index 000000000..3e0e3a35b --- /dev/null +++ b/saas/resources/apigateway/docs/zh/healthz.md.j2 @@ -0,0 +1,13 @@ +### 检查健康状态 + +#### Request + +#### Response + +> 200 OK + +``` +ok +``` + +> 500 Internal Server Error diff --git a/saas/resources/apigateway/docs/zh/management_add_grade_manager_members.md.j2 b/saas/resources/apigateway/docs/zh/management_add_grade_manager_members.md.j2 new file mode 100644 index 000000000..8d0fe52c4 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_add_grade_manager_members.md.j2 @@ -0,0 +1,30 @@ +### 添加分级管理员成员 + +#### Parameters + +| 字段 | 类型 | 必选 | 位置 |描述 | +|-----------|------------|--------|------------|------------| +| grade_manager_id | int | 是 | path | 分级管理员ID | +| members | array[string] | 是 | body | 用户名列表 | + +#### Request + +```json +{ + "members": [ + "admin", + "test1", + "test2" + ] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/management_add_group_members.md.j2 b/saas/resources/apigateway/docs/zh/management_add_group_members.md.j2 new file mode 100644 index 000000000..e679ff7d1 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_add_group_members.md.j2 @@ -0,0 +1,58 @@ +### 添加用户组成员 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| group_id | int | 是 | path | 用户组ID | +| members | array[object] | 是 | body | 成员列表 | +| expired_at | int | 是 | body |过期时间戳(单位秒),即用户或部门在expired_at后将不具有该用户组的相关权限,其中值为4102444800表示永久 | + +members + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| type | string | 是 | body | 成员类型,user表示用户,department表示部门 | +| id | string | 是 | body | 用户或部门ID | + +#### Request + +```json +{ + "members": [ + { + "type": "user", + "id": "admin" + }, + { + "type": "department", + "id": "1" + } + ], + "expired_at": 1619587562 +} +``` + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| count | int | 总数量 | +| results | array[object] | 分页查询到结果 | + +results +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| type | string | 成员类型,user表示用户,department表示部门 +| id | string | 用户或部门ID | +| name | string | 用户或部门名称 | +| expired_at | int | 过期时间戳(单位秒),即用户或部门在expired_at后将不具有该用户组的相关权限,其中值为4102444800表示永久 | + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_delete_grade_manager_members.md.j2 b/saas/resources/apigateway/docs/zh/management_delete_grade_manager_members.md.j2 new file mode 100644 index 000000000..b404a903a --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_delete_grade_manager_members.md.j2 @@ -0,0 +1,22 @@ +### 删除分级管理员成员 + + +#### Parameters + +| 字段 | 类型 | 必选 | 位置 |描述 | +|-----------|------------|--------|------------|------------| +| grade_manager_id | int | 是 | path | 分级管理员ID | +| members | string | 是 | query |要删除的用户名,多个用户则使用英文逗号分隔 | + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_delete_group_members.md.j2 b/saas/resources/apigateway/docs/zh/management_delete_group_members.md.j2 new file mode 100644 index 000000000..f17314808 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_delete_group_members.md.j2 @@ -0,0 +1,23 @@ +### 删除用户组成员 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| group_id | int | 是 | path | 用户组ID | +| type | string | 是 | query | 成员类型,user表示用户,department表示部门 | +| ids | string | 是 | query | 成员ID列表,多个以英文逗号分隔, 对于type=user,则ID为用户名,对于type=department,则为部门ID | + +#### Request + +#### Response + +> Status: 200 OK + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/management_grade_manager_create_groups.md.j2 b/saas/resources/apigateway/docs/zh/management_grade_manager_create_groups.md.j2 new file mode 100644 index 000000000..b2a650ba9 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_grade_manager_create_groups.md.j2 @@ -0,0 +1,50 @@ +### 创建用户组 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| grade_manager_id | int | 是 | path | 分级管理员ID | +| groups | array[object] | 是 | body | 用户组列表 | + +groups + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| name | string | 是 | body |用户组名称,至少5个字符,同一个分级管理员下唯一 | +| description | string | 是 | body | 用户组描述,至少10个字符 | +| readonly | bool | 否 | body |可选参数,默认为false, 用户组仅仅可读,true时,则无法用户组在权限中心产品上将无法删除 | + +#### Request + +```json +{ + "groups": [ + { + "name": "test1", + "description": "test1test1" + }, + { + "name": "test2", + "description": "test1test2", + "readonly": true + }, + ] +} +``` + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| data | array[int] | 用户组ID列表 | + + +```json +{ + "code": 0, + "message": "ok", + "data": [1, 2] +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_grade_manager_delete_group.md.j2 b/saas/resources/apigateway/docs/zh/management_grade_manager_delete_group.md.j2 new file mode 100644 index 000000000..8df5269c5 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_grade_manager_delete_group.md.j2 @@ -0,0 +1,20 @@ +### 删除用户组 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| group | int | 是 | path | 用户组ID | + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_grade_manager_groups.md.j2 b/saas/resources/apigateway/docs/zh/management_grade_manager_groups.md.j2 new file mode 100644 index 000000000..5230d9f45 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_grade_manager_groups.md.j2 @@ -0,0 +1,71 @@ +### 查询分级管理员下的用户组列表 + +> 只能查询某个分级管理员下的用户组列表 + + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| grade_manager_id | int | 是 | path | 分级管理员ID | +| limit | int | 是| query | 分页查询参数之一,limit表示查询数量,`最大值为100` | +| offset | int | 是| query | 分页查询参数之一,offset表示从第几个开始查询,offset从0开始计算 | + +#### Request + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| count | int | 总数量 | +| results | array[object] | 分页查询到结果 | + +results +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| id | int | 用户组ID | +| name | string | 用户组名称 | +| description | string | 用户组描述 | +| attributes | array[object] | 用户组属性 | + +attributes +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| readonly | bool | 用户组仅仅可读,true时,则无法用户组在权限中心产品上将无法删除 | + + +```json +{ + "code": 0, + "message": "ok", + "data": { + "count": 3, + "results": [ + { + "id": 1, + "name": "test1", + "description": "test1", + "attributes": { + "readonly": true + } + }, + { + "id": 2, + "name": "test2", + "description": "test2", + "attributes": { + "readonly": false + } + }, + { + "id": 2, + "name": "test2", + "description": "test", + "attributes": { + "readonly": true + } + }, + ] + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/management_grade_manager_members.md.j2 b/saas/resources/apigateway/docs/zh/management_grade_manager_members.md.j2 new file mode 100644 index 000000000..1d15cc473 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_grade_manager_members.md.j2 @@ -0,0 +1,28 @@ +### 查询分级管理员成员列表 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| grade_manager_id | int | 是 | path | 分级管理员ID | + +#### Request + + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| data | array[string] | 用户名列表 | + + +```json +{ + "code": 0, + "message": "ok", + "data": [ + "admin", + "test" + ] +} +``` diff --git a/saas/resources/apigateway/docs/zh/management_grade_manager_update_group.md.j2 b/saas/resources/apigateway/docs/zh/management_grade_manager_update_group.md.j2 new file mode 100644 index 000000000..f0d8c461f --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_grade_manager_update_group.md.j2 @@ -0,0 +1,29 @@ +### 更新用户组名称和描述 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| group | int | 是 | path | 用户组ID | +| name | string | 是 | body | 用户组名称,至少5个字符,也可为空,空则不更新 | +| description | string | 是 | body| 用户组描述,至少10个字符,也可为空,空则不更新 | + +#### Request + +```json +{ + "name": "test2", + "description": "test1test2" +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_grade_managers.md.j2 b/saas/resources/apigateway/docs/zh/management_grade_managers.md.j2 new file mode 100644 index 000000000..c72aefcc8 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_grade_managers.md.j2 @@ -0,0 +1,124 @@ +### 创建分级管理员 + +#### Parameters + +| 字段 | 类型 | 必选 | 位置 |描述 | +|-----------|------------|--------|------------|------------| +| system | string | 是 | body |系统id | +| name | string| 是 | body |分级管理员名称, 权限中心里全局唯一 | +| description | string | 是 | body |分级管理员描述,可为空字符串 | +| members | array[string] | 是 | body | 分级管理员成员列表 | +| authorization_scopes | array[object] | 是 | body |分级管理员可授权范围 | +| subject_scopes | array[object] | 是 | body |分级管理员可授权的人员范围 | + +subject_scopes + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| type | string | 是 | body | 授权对象类型, 当前只支持 user和department | +| id | string | 是 | body | 授权对象ID,即用户名或部门ID | + +authorization_scopes + +| 字段 | 类型 | 必选 | 位置 |描述 | +|-----------|------------|--------|------------|------------| +| system | string | 是 | body | 系统id | +| actions | array[object] | 是 | body | 操作 | +| resources | array[object] | 是 | body | 资源拓扑, 资源类型的顺序必须操作注册时的顺序一致| + +actions + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| id | string | 是 | body | 操作ID | + +resources + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| system | string | 是 | body | 资源系统ID | +| type | string | 是 | body | 资源类型ID | +| paths | `array[array[object]]` | 是 | body | 批量资源拓扑,`最多1000个` | + +paths + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| system | string | 是 | body | 拓扑节点类型的系统ID | +| type | string | 是 | body | 拓扑节点类型ID | +| id | string | 是 | body | 拓扑节点实例ID | +| name | string | 是 | body | 拓扑节点实例名称 | + +`resources.paths`是批量的资源实例拓扑 + + +#### Request + +```json +{ + "system": "bk_cmdb", + "name": "分级管理员1", + "description": "", + "members": [ + "admin" + ], + "authorization_scopes": [ + { + "system": "bk_cmdb", + "actions": [ + { + "id": "edit_host" + } + ], + "resources": [ + { # 操作关联的资源类型, 必须与所有的actions都匹配, 资源类型的顺序必须操作注册时的顺序一致 + "system": "bk_cmdb", + "type": "host", + "paths": [ # 批量资源拓扑 + [ + { + "system": "bk_cmdb" + "type": "biz", + "id": "1", + "name": "biz1" + }, + { + "system": "bk_cmdb" + "type": "set", + "id": "*", + "name": "" + } + ] + ] + } + ] + } + ], + "subject_scopes": [ + { + "type": "user", + "id": "admin" + } + ] +} +``` + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| id | int | 分级管理员id | + + +```json +{ + "code": 0, + "message": "ok", + "data": [ + { + "id": 1 + } + ] +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_group_members.md.j2 b/saas/resources/apigateway/docs/zh/management_group_members.md.j2 new file mode 100644 index 000000000..89db1a5cf --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_group_members.md.j2 @@ -0,0 +1,52 @@ +### 查询用户组成员列表 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| group_id | int | 是 | path | 用户组ID | +| limit | int | 是| query | 分页查询参数之一,limit表示查询数量,`最大值为100` | +| offset | int | 是| query | 分页查询参数之一,offset表示从第几个开始查询,offset从0开始计算 | + +#### Request + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| count | int | 总数量 | +| results | array[object] | 分页查询到结果 | + +results + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| type | string | 成员类型,user表示用户,department表示部门 +| id | string | 用户或部门ID | +| name | string | 用户或部门名称 | +| expired_at | int | 过期时间戳(单位秒),即用户或部门在expired_at后将不具有该用户组的相关权限,其中值为4102444800表示永久 | + +```json +{ + "code": 0, + "message": "ok", + "data": { + "count": 2, + "results": [ + { + "type": "user", + "id": "admin", + "name": "管理员", + "expired_at": 1619587562 + }, + { + "type": "department", + "id": "1", + "name": "部门1", + "expired_at": 4102444800 + } + ] + } +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_groups_applications.md.j2 b/saas/resources/apigateway/docs/zh/management_groups_applications.md.j2 new file mode 100644 index 000000000..158d1c427 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_groups_applications.md.j2 @@ -0,0 +1,42 @@ +### 创建用户组申请单据 + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| group_ids | array[int] | 是| body | 用户组ID列表 | +| expired_at | int | 是 | body | 过期时间戳(单位秒),即用户在expired_at后将不具有申请的用户组的相关权限,其中值为4102444800表示永久 | +| applicant | string | 是 | body | 申请人,即username | +| reason | string | 是 | body | 申请理由 | + +#### Request + +```json +{ + "group_ids": [ + 1, + 2, + 3 + ], + "expired_at": 1653481167, + "reason": "开发需要", + "applicant": "blueking" +} +``` + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|------------|--------| +| ids | array[int] | 申请单据ID列表,由于不同用户组审批流程不一样,所以会拆分出不同申请单据 | + + +```json +{ + "code": 0, + "message": "ok", + "data": { + "ids": [1, 2, 3] + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/management_groups_policies.md.j2 b/saas/resources/apigateway/docs/zh/management_groups_policies.md.j2 new file mode 100644 index 000000000..f10453357 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_groups_policies.md.j2 @@ -0,0 +1,81 @@ +### 用户组授权 + +#### Parameters + +| 字段 | 类型 | 必选 | 位置 |描述 | +|-----------|------------|--------|------------|------------| +| group_id | int | 是 | path | 用户组ID | +| system | string | 是 | body | 系统id | +| actions | array[object] | 是 | body | 操作 | +| resources | array[object] | 是 | body | 资源拓扑, 资源类型的顺序必须操作注册时的顺序一致| + +actions + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| id | string | 是 | body | 操作ID | + +resources + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| system | string | 是 | body | 资源系统ID | +| type | string | 是 | body | 资源类型ID | +| paths | `array[array[object]]` | 是 | body | 批量资源拓扑,`最多1000个` | + +paths + +| 字段 | 类型 | 必选 | 位置 | 描述 | +|-----------|------------|--------|------------|------------| +| system | string | 是 | body | 拓扑节点类型的系统ID | +| type | string | 是 | body | 拓扑节点类型ID | +| id | string | 是 | body | 拓扑节点实例ID | +| name | string | 是 | body | 拓扑节点实例名称 | + +`resources.paths`是批量的资源实例拓扑 + + +#### Request + +```json +{ + "system": "bk_cmdb", + "actions": [ + { + "id": "edit_host" + } + ], + "resources": [ + { # 操作关联的资源类型, 必须与所有的actions都匹配, 资源类型的顺序必须操作注册时的顺序一致 + "system": "bk_cmdb", + "type": "host", + "paths": [ # 批量资源拓扑 + [ + { + "system": "bk_cmdb" + "type": "biz", + "id": "1", + "name": "biz1" + }, + { + "system": "bk_cmdb" + "type": "set", + "id": "*", + "name": "" + } + ] + ] + } + ] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 b/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 new file mode 100644 index 000000000..89a982327 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 @@ -0,0 +1,37 @@ +### 查询用户的分级管理员列表 + + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| system | string| 是 | body | 系统ID,即查询由某个系统创建的分级管理员列表 | +| uesr_id | string | 是 | body | 用户ID,即用户名 | + +#### Request + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| id | int | 分级管理员ID | + + +```json +{ + "code": 0, + "message": "ok", + "data": [ + { + "id": 1, + }, + { + "id": 2, + }, + { + "id": 3, + } + ] +} +``` + diff --git a/saas/resources/apigateway/docs/zh/management_users_grade_managers_groups.md.j2 b/saas/resources/apigateway/docs/zh/management_users_grade_managers_groups.md.j2 new file mode 100644 index 000000000..42270ac81 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/management_users_grade_managers_groups.md.j2 @@ -0,0 +1,44 @@ +### 查询用户在某个分级管理员下的加入的用户组列表 + + +#### Parameters + +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|--------|--------| +| grade_manager_id | int | 是 | path | 分级管理员ID | +| uesr_id | string | 是 | body | 用户ID,即用户名 | + +#### Request + +#### Response + +| 字段 | 类型 | 描述 | +|-----------|-----------|-----------| +| id | int | 用户组ID | +| name | string | 用户组名称 | +| description | string | 用户组描述 | + +```json +{ + "code": 0, + "message": "ok", + "data": [ + { + "id": 1, + "name": "test1", + "description": "test1", + }, + { + "id": 2, + "name": "test2", + "description": "test2", + }, + { + "id": 2, + "name": "test2", + "description": "test", + } + ] +} +``` + diff --git a/saas/resources/apigateway/docs/zh/metrics.md.j2 b/saas/resources/apigateway/docs/zh/metrics.md.j2 new file mode 100644 index 000000000..9381b4df2 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/metrics.md.j2 @@ -0,0 +1,7 @@ +### Prometheus Metrics + +#### Request + +#### Response + +return prometheus metrics diff --git a/saas/resources/apigateway/docs/zh/ping.md.j2 b/saas/resources/apigateway/docs/zh/ping.md.j2 new file mode 100644 index 000000000..30fcd38a3 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/ping.md.j2 @@ -0,0 +1,11 @@ +### 检查程序是否启动 + +#### Request + +#### Response + +```json +{ + message: "pong" +} +``` diff --git a/saas/resources/apigateway/docs/zh/policy_auth.md.j2 b/saas/resources/apigateway/docs/zh/policy_auth.md.j2 new file mode 100644 index 000000000..a930597ce --- /dev/null +++ b/saas/resources/apigateway/docs/zh/policy_auth.md.j2 @@ -0,0 +1,75 @@ +### policy auth + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system |string | 是 | 系统唯一标识 | +| subject | string | 是 | subject | +| action | object | 是 | 操作 | +| resources | Array(resource_node) | 是 | 资源实例, 资源类型的顺序必须操作注册时的顺序一致 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resource_node + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| id | 字符串 | 是 | 资源实例 ID | +| attribute | 对象 | 是 | 资源属性 | + +#### Request + +```json +{ + "system": "bk_job", + "subject": { + "type": "user", + "id": "admin" + }, + "action": { + "id": "execute" + }, + "resources": [{ // 资源类型的顺序必须操作注册时的顺序一致, 否则会导致鉴权失败! + "system": "bk_job", + "type": "job", + "id": "ping", + "attribute": { // 资源的属性值可能有多个, 目前支持string/int/boolean, 以及路径stringList + "os": "linux", + "_bk_iam_path_": ["/biz,1/set,2/"], + "is_ready": true, + "area_id": 200 + } + }, { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1", + "attribute": {} // 外部资源的属性由iam负责查询属性, 接入方不需要传入 + }] +} +``` + +### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { + "allowed": true + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/policy_auth_by_actions.md.j2 b/saas/resources/apigateway/docs/zh/policy_auth_by_actions.md.j2 new file mode 100644 index 000000000..c2397c3b2 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/policy_auth_by_actions.md.j2 @@ -0,0 +1,81 @@ +### policy auth by actions + +鉴权场景: 查看一个`用户`有没有`资源A`的`查看`/`编辑`/`删除`权限 +限制: actions 最大能传 10 个操作 + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system |string | 是 | 系统唯一标识 | +| subject | string | 是 | subject | +| actions | Array(action) | 是 | 操作 | +| resources | Array(resource_node) | 是 | 资源实例, 资源类型的顺序必须操作注册时的顺序一致 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resource_node + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| id | 字符串 | 是 | 资源实例 ID | +| attribute | 对象 | 是 | 资源属性 | + +#### Request + +```json +{ + "system": "bk_job", + "subject": { + "type": "user", + "id": "admin" + }, + "actions": [{ + "id": "execute" + }, { + "id": "view" + }], + "resources": [{ // 资源类型的顺序必须操作注册时的顺序一致, 否则会导致鉴权失败! + "system": "bk_job", + "type": "job", + "id": "ping", + "attribute": { // 资源的属性值可能有多个, 目前支持string/int/boolean, 以及路径stringList + "os": "linux", + "_bk_iam_path_": ["/biz,1/set,2/"], + "is_ready": true, + "area_id": 200 + } + }, { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1", + "attribute": {} // 外部资源的属性由iam负责查询属性, 接入方不需要传入 + }] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { + "execute": true, + "view": false + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/policy_auth_by_resources.md.j2 b/saas/resources/apigateway/docs/zh/policy_auth_by_resources.md.j2 new file mode 100644 index 000000000..b58648376 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/policy_auth_by_resources.md.j2 @@ -0,0 +1,103 @@ +### 2. policy auth by resources + +鉴权场景: 查看一个 `用户` 有没有 100 台 `资源A` 的 `编辑` 权限 +限制: resources_list 最大能传 100 个资源 + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system |string | 是 | 系统唯一标识 | +| subject | string | 是 | subject | +| action | object | 是 | 操作 | +| resources_list | Array(resources) | 是 | 资源实例列表, 资源类型的顺序必须操作注册时的顺序一致 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resources + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| resources | Array(resource_node) | 是 | 一个资源 | + +resource_node + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| id | 字符串 | 是 | 资源实例 ID | +| attribute | 对象 | 是 | 资源属性 | + +#### Request + +```json +{ + "system": "bk_job", + "subject": { + "type": "user", + "id": "admin" + }, + "action": { + "id": "execute" + }, + "resources_list": [ + [{ // 第一个资源 + "system": "bk_job", + "type": "job", + "id": "ping", + "attribute": { + "os": "linux", + "_bk_iam_path_": ["/biz,1/set,2/"], + "is_ready": true, + "area_id": 200 + } + }, { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1", + "attribute": {} + }], + [{ // 第二个资源 + "system": "bk_job", + "type": "job", + "id": "ping2", + "attribute": { + "os": "linux", + "_bk_iam_path_": ["/biz,1/set,2/"], + "is_ready": true, + "area_id": 200 + } + }, { + "system": "bk_cmdb", + "type": "host2", + "id": "192.168.2.2", + "attribute": {} + }] + ] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { + "bk_job,job,ping/bk_cmdb,host,192.168.1.1": false, + "bk_job,job,ping2/bk_cmdb,host2,192.168.2.2": false + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/policy_query.md.j2 b/saas/resources/apigateway/docs/zh/policy_query.md.j2 new file mode 100644 index 000000000..f334b5c2b --- /dev/null +++ b/saas/resources/apigateway/docs/zh/policy_query.md.j2 @@ -0,0 +1,98 @@ +### 拉取权限策略 + +sdk 接入, 需要实现 + +1. 鉴权: 拉取权限策略 +2. 获取有权限的资源列表 + +两个将使用同一个接口, 从服务端拉取策略列表 + +返回结果中包含条件表达式 + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system |string | 是 | 系统唯一标识 | +| subject | subject | 是 | 鉴权实体 | +| action | action | 是 | 操作 | +| resources | Array(resource_node) | 是 | 资源实例, 资源类型的顺序必须操作注册时的顺序一致;可以为空列表 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resource_node + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| id | 字符串 | 是 | 资源实例 ID | +| attribute | 对象 | 是 | 资源属性 | + +#### Request + +##### 无 cmdb 依赖 + +```json +# 1. +{ + "system": "bk_job", + "subject": + { + "type": "user", + "id": "admin" + }, + "action": { + "id": "edit" + }, + "resources": [] +} +``` + +##### 有 cmdb 依赖 + +```json +{ + "system": "bk_job", + "subject": + { + "type": "user", + "id": "admin" + }, + "action": { + "id": "execute" + }, + "resources": [ + { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1" + }] +} +``` + + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { // 条件表达式 + "field": "host.id", + "op": "any", + "value": [] + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/policy_query_by_actions.md.j2 b/saas/resources/apigateway/docs/zh/policy_query_by_actions.md.j2 new file mode 100644 index 000000000..aeb817a07 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/policy_query_by_actions.md.j2 @@ -0,0 +1,126 @@ +### 批量拉取一批操作的权限策略 + +场景: 接入系统需要对同一资源类型的一批资源实例的多个操作鉴权, 比如资源实例列表页显示多个操作是否有权限 + +约束: + +1. 一批资源的资源类型必须是一样的 +2. action 如果对 cmdb 资源有依赖, 依赖的 cmdb 资源实例必须是同一个 + +SDK 实现: + +1. 批量拉取一批操作的权限策略 +2. 本地遍历计算资源实例是否有权限 + +#### Parameters + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system |string | 是 | 系统唯一标识 | +| subject | string | 是 | subject | +| actions | Array(action) | 是 | 操作列表 | +| resources | Array(resource_node) | 是 | 资源实例, 资源类型的顺序必须操作注册时的顺序一致 | + +action + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| id | 字符串 | 是 | 操作 ID | + +subject + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| type | 字符串 | 是 | 授权对象类型, 当前只支持 user | +| id | 字符串 | 是 | 授权对象 ID | + +resource_node + +| 字段 | 类型 |是否必须 | 描述 | +|:---|:---|:---|:---| +| system | 字符串 | 是 | 资源系统 ID | +| type | 字符串 | 是 | 资源类型 ID | +| id | 字符串 | 是 | 资源实例 ID | +| attribute | 对象 | 是 | 资源属性 | + +#### Request + +##### 无 cmdb 依赖 + +```json +{ + "system": "bk_job", + "subject": + { + "type": "user", + "id": "admin" + }, + "actions": [ + { + "id": "edit" + }, + { + "id": "view" + } + ], + "resources": [] +} +``` + +##### 无 cmdb 依赖 + +```json +{ + "system": "bk_job", + "subject": + { + "type": "user", + "id": "admin" + }, + "actions": [ + { + "id": "execute" + }, + { + "id": "quick_execute" + } + ], + "resources": [ + { + "system": "bk_cmdb", + "type": "host", + "id": "192.168.1.1" + }] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": [ // action的顺序与请求中的acitons顺序一致 + { + "action":{ + "id":"edit" + }, + "condition": { // 条件表达式 + "field": "host.id", + "op": "any", + "value": [] + } + }, + { + "action":{ + "id":"view" + }, + "condition": { // 条件表达式 + "field": "host.id", + "op": "any", + "value": [] + } + } + ] +} +``` diff --git a/saas/resources/apigateway/docs/zh/policy_query_by_ext_resources.md.j2 b/saas/resources/apigateway/docs/zh/policy_query_by_ext_resources.md.j2 new file mode 100644 index 000000000..fadf58c4b --- /dev/null +++ b/saas/resources/apigateway/docs/zh/policy_query_by_ext_resources.md.j2 @@ -0,0 +1,128 @@ +### 批量第三方依赖鉴权策略查询 + +#### 背景 + +本系统的操作依赖外部系统资源类型, 需要大批量使用外部资源实例鉴权 + +例如: 用户在作业平台需要触发上千台主机上批量执行某个作业, 比如 需要在 host1, host2 上执行 job1 + +这个接口, 支持拉取策略的同时, 帮助接入系统到`依赖系统`拉取策略计算需要的资源信息; + +接入系统同时拿到`策略`和`资源信息`, 就可以完成计算, 确认是否有权限; + +注: 由于大批量遍历计算 expression 属于 cpu 密集计算, 如果计算放在 IAM, 在并发批量计算时, 会导致 IAM 服务 CPU 资源不足, 进而服务不可用, 所以需要把计算分散到接入系统分布计算, 减轻 IAM 服务的压力 + +场景 1: 外部依赖资源实例的数量**不**超过 1000 个 + +使用建议: + +直接使用`query_by_ext_resources`接口查询策略表达式与资源实例相关信息到本地后遍历计算是否有权限 + +场景 2: 外部依赖资源实例的数量**超过**了 1000 个 + +使用建议: + +1. 使用`policy/query`接口查询策略表达式 +2. 本地计算表达式中是否有`any`, 是否有实例`id in ["id1", "id2"]`初步计算部分外部依赖资源实例是否权限 +3. 对于在第二步中计算无权限的资源实例, 再分批次(每次不超过 1000 个)调用`query_by_ext_resources`接口查询策略表达式与资源实例相关信息到本地后遍历计算是否有权限 + +#### 使用方式 + +1. 在 request body 中 resources 传 job1 相关的资源信息, 在 ext_resources 中传第三方依赖的 host1, host2 +2. 返回的结果中 expression 是过滤了 request 中 resource 相关条件后的条件表达式, 结果的 ext_resources 返回填充属性的资源信息 +3. **鉴权计算**: 接入系统拿到 ext_resource 后遍历每个 host 实例带入 expression 中计算得到鉴权结果 + +注意: + +- request 中 resources 与 ext_resources 的关系, 当前 ext_resources 只能有一种第三方依赖类型的实例, resource 必须为 action 依赖的其它资源类型的实例 +- ext_resources 一次查询不能超过 1000 个, 如果超过建议分批次查询 + +------ + +#### Request + +```json +{ + "system": "bk_job", + "subject": { + "type": "user", + "id": "admin" + }, + "action": { + "id": "execute" + }, + "resources": [ # 参与过滤策略的资源实例, 每种资源类型只能传1个, 可以不传, 不传时返回的表达式包含操作关联所有的资源类型的条件 + { + "system": "bk_job", + "type": "job", + "id": "job1", + "attribute": {} + } + ], + "ext_resources": [ # 不参与计算的资源类型, 可以批量传入, IAM会向第三方系统查询资源的属性信息, 一次最多1000个 + { + "system": "bk_cmdb", + "type": "host", + "ids": [ + "host1", + "host2" + ] + } + ] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { + "expression": { # 已经代入request中resources计算过后的表达式 + "op": "AND", + "content": [ + { + "op": "in", + "field": "host.id", + "value": [ + "host1", + "host2" + ] + }, + { + "op": "starts_with", + "field": "host._bk_iam_path_", + "value": [ + "/biz,5/" + ] + } + ] + }, + "ext_resources": [ # 查询得到的第三方资源实例, 填充了与表达式相关的属性 + { + "system": "bk_cmdb", + "type": "host", + "instances": [ + { + "id": "host1", + "attribute": { + "_bk_iam_path_": [ + "/biz,5/" + ] + } + }, + { + "id": "host2", + "attribute": { + "_bk_iam_path_": [ + "/biz,5/" + ] + } + } + ] + } + ] + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_add_actions.md.j2 b/saas/resources/apigateway/docs/zh/system_add_actions.md.j2 new file mode 100644 index 000000000..f6b571e22 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_add_actions.md.j2 @@ -0,0 +1,76 @@ +### 添加 action + +限制: +- 一个系统只能创建最多 100 个 action, 所以如果操作会超过 100 个, 需要思考模型的正确性/合理性(例如把实例抽象到了 action 导致 action 随实例增多而增多) + +---------- +{% include '_api_v1_model_actions.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +#### Request + +```json +[ + { + "id": "biz_create", + "name": "业务创建", + "name_en": "biz_create", + "description": "业务创建是...", + "description_en": "biz_create is...", + "type": "create", + "related_resource_types": [], + "version": 1 + }, + { + "id": "host_edit", + "name": "主机编辑", + "name_en": "host_edit", + "type": "", + "related_resource_types": [ + { + "system_id": "bk_cmdb", + "id": "host", + "name_alias": "", + "name_alias_en": "", + "selection_mode": "instance", + "related_instance_selections": [ + { + "system_id": "bk_cmdb", + "id": "free_host", + "ignore_iam_path": false, + }, + { + "system_id": "bk_cmdb", + "id": "biz_topology", + "ignore_iam_path": false, + }, + { + "system_id": "bk_cmdb", + "id": "biz_set_topology", + "ignore_iam_path": false, + } + ] + } + ], + "related_actions": ["view", "delete"], + "version": 1 + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` + diff --git a/saas/resources/apigateway/docs/zh/system_add_configs.md.j2 b/saas/resources/apigateway/docs/zh/system_add_configs.md.j2 new file mode 100644 index 000000000..74ca7e56d --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_add_configs.md.j2 @@ -0,0 +1,19 @@ +## 系统配置新增 + +{% include '_api_v1_model_system_config.md.j2' %} + +### action_groups 操作组 + +{% include './_api_v1_model_system_add_configs_action_groups.md.j2' %} + +### common_actions 常用操作 + +{% include './_api_v1_model_system_add_configs_common_actions.md.j2' %} + +### feature_shield_rules 功能开关 + +{% include './_api_v1_model_system_add_configs_feature_shield_rules.md.j2' %} + +### resource_creator_actions 新建关联 + +{% include './_api_v1_model_system_add_configs_resource_creator_actions.md.j2' %} diff --git a/saas/resources/apigateway/docs/zh/system_add_instance_selections.md.j2 b/saas/resources/apigateway/docs/zh/system_add_instance_selections.md.j2 new file mode 100644 index 000000000..dc953623a --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_add_instance_selections.md.j2 @@ -0,0 +1,62 @@ +### 新增 instanceSelection + +限制: +- 一个系统只能创建最多 50 个 instanceSelection + +---------- +{% include '_api_v1_model_instance_selections.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :---| :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +#### Request + +```json +[ + { + "id": "free_host", + "name": "空闲主机", + "name_en": "free host", + "resource_type_chain": [{ + "system_id": "bk_cmdb", + "id": "host" + }] + }, + { + "id": "biz_topology", + "name": "业务拓扑", + "name_en": "biz topology", + "resource_type_chain": [{ + "system_id": "bk_cmdb", + "id": "biz" + }, + { + "system_id": "bk_cmdb", + "id": "set" + }, + { + "system_id": "bk_cmdb", + "id": "module" + }, + { + "system_id": "bk_cmdb", + "id": "host" + } + ] + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_add_resource_types.md.j2 b/saas/resources/apigateway/docs/zh/system_add_resource_types.md.j2 new file mode 100644 index 000000000..73bec2e4f --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_add_resource_types.md.j2 @@ -0,0 +1,114 @@ +### 新增 resourceType + +限制: +- 一个系统只能创建最多 50 个 resourceType + +---------- +{% include '_api_v1_model_resource_types.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :---| :--- | :---|:---|:--- | +| system_id | string | 是 | path | 系统 ID | + +#### Request + +```json +[ + { + "id": "biz_set", + "name": "业务集", + "name_en": "biz_set", + "description": "业务集是...", + "description_en": "biz_set is a ...", + "parents": [], + "provider_config": { + "path": "/api/v1/resources/biz_set/query" + }, + "version": 1 + }, + { + "id": "biz", + "name": "业务", + "name_en": "biz", + "description": "业务是...", + "description_en": "biz is a ...", + "parents": [ + {"system_id": "bk_cmdb", "id": "biz_set"} + ], + "provider_config": { + "path": "/api/v1/resources/biz/query" + }, + "version": 1 + }, + { + "id": "dir", + "name": "目录", + "name_en": "dir", + "description": "目录是...", + "description_en": "dir is a ...", + "parents": [ + {"system_id": "bk_cmdb", "id": "biz"} + ], + "provider_config": { + "path": "/api/v1/resources/dir/query" + }, + "version": 1 + }, + { + "id": "set", + "name": "集群", + "name_en": "set", + "description": "集群是...", + "description_en": "set is a ...", + "parents": [ + {"system_id": "bk_cmdb", "id": "biz"}, + {"system_id": "bk_cmdb", "id": "dir"} + ], + "provider_config": { + "path": "/api/v1/resources/set/query" + }, + "version": 1 + }, + { + "id": "module", + "name": "模块", + "name_en": "module", + "description": "模块是...", + "description_en": "module is a ...", + "parents": [ + {"system_id": "bk_cmdb", "id": "set"} + ], + "provider_config": { + "path": "/api/v1/resources/module/query" + }, + "version": 1 + }, + { + "id": "host", + "name": "主机", + "name_en": "host", + "description": "主机是...", + "description_en": "host is a ...", + "parents": [ + {"system_id": "bk_cmdb", "id": "module"} + ], + "provider_config": { + "path": "/api/v1/resources/host/query" + }, + "version": 1 + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_batch_delete_actions.md.j2 b/saas/resources/apigateway/docs/zh/system_batch_delete_actions.md.j2 new file mode 100644 index 000000000..7703aa45d --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_batch_delete_actions.md.j2 @@ -0,0 +1,32 @@ +### 批量删除 action + +---------- +{% include '_api_v1_model_instance_actions_delete.md.j2' %} +---------- + +#### Parameters + +|字段 |类型 |是否必须 |位置 |描述 | +|:--|:--|:--|:--|:--| +|system_id |string |是 |path |系统 ID | +|check_existence |boolean |否 |query |默认会检查 id 存在, 不存在将导致删除失败, 设置 false 不检查 id 是否存在, 直接走删除( `delete from table where id in []` ) | + +#### Request + +```json +[ + { + "id": "host_edit" + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_batch_delete_instance_selections.md.j2 b/saas/resources/apigateway/docs/zh/system_batch_delete_instance_selections.md.j2 new file mode 100644 index 000000000..761a56dbb --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_batch_delete_instance_selections.md.j2 @@ -0,0 +1,34 @@ +### 批量删除 instanceSelection + +---------- +{% include '_api_v1_model_instance_selections_delete.md.j2' %} +---------- + +#### Parameters + +|字段 |类型 |是否必须 |位置 |描述 | +| :---| :--- | :---|:---|:---| +| system_id | string | 是 | path | 系统 ID | +|check_existence |boolean |否 |query |默认会检查 id 存在, 不存在将导致删除失败, 设置 false 不检查 id 是否存在, 直接走删除( `delete from table where id in []` ) | + +#### Request + +```json +[ + { + "id": "free_host" + }, + { + "id": "biz_topology" + } +] +``` +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_batch_delete_resource_types.md.j2 b/saas/resources/apigateway/docs/zh/system_batch_delete_resource_types.md.j2 new file mode 100644 index 000000000..2d91804c1 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_batch_delete_resource_types.md.j2 @@ -0,0 +1,35 @@ +### 批量删除 resourceType + +---------- +{% include '_api_v1_model_resource_types_delete.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :---| :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| check_existence | boolean | 否 | query | 默认会检查 id 存在, 不存在将导致删除失败, 设置 false 不检查 id 是否存在, 直接走删除(`delete from table where id in []`) | + +#### Request + +```json +[ + { + "id": "biz" + }, + { + "id": "set" + } +] +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_create.md.j2 b/saas/resources/apigateway/docs/zh/system_create.md.j2 new file mode 100644 index 000000000..2e4562f5e --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_create.md.j2 @@ -0,0 +1,42 @@ +### 新增 system + +注意: + +- 一个 app_code 只能创建一个 system, 且 system_id 必须等于 app_code; 如果不符合要求, 接口返回 `1901400 bad request:system_id should be the app_code!` +- 创建 system 时如果没有把自己加入 clients, 会自动将当前发起`新增system`的 app_code 加入`clients` + +------- + +{% include '_api_v1_model_system.md.j2' %} + +------- + +#### Request + +```json +{ + "id": "bk_cmdb", + "name": "配置平台", + "name_en": "CMDB", + "description": "配置平台是一个...", + "description_en": "CMDB is a...", + "clients": "bk_cmdb,cmdb", + "provider_config": { + "host": "http://cmdb.service.consul", + "auth": "basic", + "healthz": "/api/v1/healthz" + } +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": { + "id": "bk_cmdb" + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_delete_action.md.j2 b/saas/resources/apigateway/docs/zh/system_delete_action.md.j2 new file mode 100644 index 000000000..2ea0ef31a --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_delete_action.md.j2 @@ -0,0 +1,25 @@ +### 删除 action + +---------- +{% include '_api_v1_model_instance_actions_delete.md.j2' %} +---------- + +#### Parameters + +|字段 |类型 |是否必须 |位置 |描述 | +|:--|:--|:--|:--|:--| +|system_id |string |是 |path |系统 ID | +|action_id |string |是 |path |操作 ID | +|check_existence |boolean |否 |query |默认会检查 id 存在, 不存在将导致删除失败, 设置 false 不检查 id 是否存在, 直接走删除( `delete from table where id in []` ) | + +#### Request + + +#### Response +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_delete_action_policies.md.j2 b/saas/resources/apigateway/docs/zh/system_delete_action_policies.md.j2 new file mode 100644 index 000000000..b5ab77531 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_delete_action_policies.md.j2 @@ -0,0 +1,27 @@ +### 删除操作的所有策略 + +如果操作(action)已经配置了权限, 生成了策略(policy), 此时是无法直接删除操作的. + +需要: +1. 调用本接口, 删除操作的策略(此时会打标记后, 由异步任务在后台进行回收) +2. 调用删除操作接口, 进行操作删除(第一步调用成功即可执行这一步, 不需要等第一步异步任务执行成功) + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| action_id | string | 是 | path | 操作 ID | + + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_delete_instance_selection.md.j2 b/saas/resources/apigateway/docs/zh/system_delete_instance_selection.md.j2 new file mode 100644 index 000000000..14d40c37e --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_delete_instance_selection.md.j2 @@ -0,0 +1,25 @@ +### 删除 instanceSelection + +---------- +{% include '_api_v1_model_instance_selections_delete.md.j2' %} +---------- + +#### Parameters + +|字段 |类型 |是否必须 |位置 |描述 | +| :---| :--- | :---|:---|:---| +| system_id | string | 是 | path | 系统 ID | +| instance_selection_id | string | 是 | path | 实例视图 ID | +| check_existence |boolean |否 |query |默认会检查 id 存在, 不存在将导致删除失败, 设置 false 不检查 id 是否存在, 直接走删除( `delete from table where id in []` ) | + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_delete_resource_types.md.j2 b/saas/resources/apigateway/docs/zh/system_delete_resource_types.md.j2 new file mode 100644 index 000000000..fe15d3c68 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_delete_resource_types.md.j2 @@ -0,0 +1,26 @@ +### 删除 resourceType + +---------- +{% include '_api_v1_model_resource_types_delete.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :---| :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| resource_type_id | string | 是 | path | 资源类型 ID | +| check_existence | boolean | 否 | query | 默认会检查 id 存在, 不存在将导致删除失败, 设置 false 不检查 id 是否存在, 直接走删除(`delete from table where id in []`) | + +#### Request + + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_get.md.j2 b/saas/resources/apigateway/docs/zh/system_get.md.j2 new file mode 100644 index 000000000..79d21d153 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_get.md.j2 @@ -0,0 +1,28 @@ +### 查询系统 + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :---| :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +#### Request + +#### Response + +```json +{ + "code": 0, + "data": { + "clients": "app_code1,app_code2", + "description": "Platform as A Service", + "description_en": "Platform as A Service", + "id": "id", + "name": "", + "name_en": "", + "provider_config": {} + }, + "message": "ok" +} +``` + diff --git a/saas/resources/apigateway/docs/zh/system_get_clients.md.j2 b/saas/resources/apigateway/docs/zh/system_get_clients.md.j2 new file mode 100644 index 000000000..0b8676bef --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_get_clients.md.j2 @@ -0,0 +1,19 @@ +### 查询系统 clients + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :---| :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +#### Response + +```json +{ + "code": 0, + "data": { + "clients": "app_code1,app_code2" + }, + "message": "ok" +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_get_policy.md.j2 b/saas/resources/apigateway/docs/zh/system_get_policy.md.j2 new file mode 100644 index 000000000..cc2ef26fd --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_get_policy.md.j2 @@ -0,0 +1,50 @@ +### 获取某条策略详情 + +根据策略 ID, 获取策略详情 + +注意: +- 如果`policy_id`对应记录不存在(错误的 ID 或者已经被删除), 将会返回`code=1901404(NotFoundError)` +- 只能查询自己系统的策略详情, 如果是其他系统的 policy ID, 将会返回`code=1901403(ForbiddenError)` +- 返回结果中`expired_at`为过期时间, 需二次判定是否过期(查回来一刻可能还没过期, 但是传递使用时可能已过期) + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| policy_id | integer | 是 | path | 策略 ID | + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { + "version": "1", + "id": 2, + "system": "bk_cmdb", + "subject": { + "type": "user", + "id": "admin", + "name": "管理员" + }, + "action": { + "id": "view_host" + }, + "expression": { + "content": [ + { + "field": "host.id", + "op": "any", + "value": [] + } + ], + "op": "OR" + }, + "expired_at": 4102444800 + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_get_token.md.j2 b/saas/resources/apigateway/docs/zh/system_get_token.md.j2 new file mode 100644 index 000000000..8b5365ffd --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_get_token.md.j2 @@ -0,0 +1,21 @@ +### 查询系统 token + +用于`权限中心` 调用 `接入系统` 拉取资源信息相关接口的鉴权 + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :---| :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | + +#### Response + +```bash +{ + "code": 0, + "data": { + "token": "dk9httsqmq4bbdu7aqq6cqp1az6i8org" + }, + "message": "ok" +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_policies.md.j2 b/saas/resources/apigateway/docs/zh/system_policies.md.j2 new file mode 100644 index 000000000..27a72a658 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_policies.md.j2 @@ -0,0 +1,112 @@ +### 拉取系统下某个操作的策略列表 + + +用于接入系统批量拉取某个 action 的所有策略; 全量带翻页; +接入系统可以利用这个接口, 定期拉取策略进行全量校验及`补偿` + +关于 timestamp 的说明: +- 由于策略是带过期时间的, 翻页查询的过程是一个时间跨度比较长的操作, 如果每一页实时查询`当前未过期`的策略列表, 那么整体结果集及固定页码里面的策略内容将会动态变化; 接入系统无法真正拉取某个操作`全量`策略 +- 这个接口拉取第一页, 默认设置`timestamp`为当天`00:00:00`的时间戳, 例如`1593273600` +- 当翻第二页到最后一页的过程中, 接入系统建议将`timestamp`作为参数传入; 以定位一个`锚点`; 防止翻页过程中跨天导致的策略列表动态变化; (如果不担心这个, 可以一直不传) +- `timestamp` 最小为`当前时间-24小时` + +注意: +- 查询回去的每条策略中`expired_at`为过期时间, 接入系统在使用前需要再次判定是否过期 +- 只能查询自己系统的`action_id`, 如果是在本系统找不到这个`action_id`不存在, 将会返回`code=1901404(NotFoundError)` + +----- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:---|:--- | +| system_id | string | 是 | path | 系统 ID | +| action_id | string | 是 | query | 操作 ID(action id), 必须是这个系统注册到权限中心的合法 Action | +| page | integer | 否| query |页码, 不传默认为`1` | +| page_size | integer | 否| query |单页大小,不传默认`100`, 限制单页最大`500`| +| timestamp | integer | 否| query |查询时间戳, 锚点 | + +示例: `action_id=edit_host&page=1&page_size=100×tamp=1592899208` + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": { + "metadata": { + "system": "bk_cmdb", + "action": { + "id": "edit_host" + }, + "timestamp": 1593273600 + }, + "count": 3, + "results": [ + { + "version": "1", + "id": 3, + "subject": { + "type": "user", + "id": "test2", + "name": "test2" + }, + "expression": { + "content": [ + { + "field": "host.id", + "op": "eq", + "value": "192.168.1.1" + } + ], + "op": "OR" + }, + "expired_at": 4102444800 + }, + { + "version": "1", + "id": 4, + "subject": { + "type": "user", + "id": "test1", + "name": "test1" + }, + "expression": { + "content": [ + { + "field": "host.system", + "op": "eq", + "value": "linux" + } + ], + "op": "OR" + }, + "expired_at": 4102444800 + }, + { + "version": "1", + "id": 7, + "subject": { + "type": "user", + "id": "admin", + "name": "管理员" + }, + "expression": { + "content": [ + { + "field": "host.id", + "op": "any", + "value": [] + } + ], + "op": "OR" + }, + "expired_at": 4102444800 + } + ] + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_policies_subjects.md.j2 b/saas/resources/apigateway/docs/zh/system_policies_subjects.md.j2 new file mode 100644 index 000000000..c9842e7e8 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_policies_subjects.md.j2 @@ -0,0 +1,63 @@ +# 根据策略 ID 拉群策略对应的用户信息 + +基于 LBAC 方案, 最终每个资源会打上一批 label, 这批 label 对应一批 Policy IDs + +查询这个资源的有某个权限的用户列表时, 可以将这批 Policy IDs 作为这个接口参数, 查询`用户列表` + +注意: +- 只能查询自己系统的策略列表对应的`用户列表` +- 如果 policyID 是其他系统的, 将会被`过滤掉`, 接口正常, 但对应的 policyId 不会出现在结果列表中 + +#### Parameters + +|字段 |类型 |是否必须 |位置 |描述 | +|:--|:--|:--|:--|:--| +| system_id | string | 是 | path | 系统 ID | +|ids |string |是 |query |策略 id, 多个以英文逗号分隔 | + +示例: `ids=2,3,4,7,9` + +#### Request + +#### Response + +```json +{ + "code": 0, + "message": "ok", + "data": [ + { + "id": 2, + "subject": { + "type": "user", + "id": "admin", + "name": "管理员" + } + }, + { + "id": 3, + "subject": { + "type": "user", + "id": "test2", + "name": "test2" + } + }, + { + "id": 4, + "subject": { + "type": "user", + "id": "test1", + "name": "test1" + } + }, + { + "id": 7, + "subject": { + "type": "user", + "id": "admin", + "name": "管理员" + } + } + ] +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_query.md.j2 b/saas/resources/apigateway/docs/zh/system_query.md.j2 new file mode 100644 index 000000000..d92151ab5 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_query.md.j2 @@ -0,0 +1,196 @@ +### 查询系统注册的信息 + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| fields |string |否 |query | 需要查询的信息类型,枚举值:base_info(基础信息), resource_types(资源类型),actions(操作),action_groups (操作组), instance_selections(实例视图), resource_creator_actions(新建关联配置), common_actions(常用操作) 多个以英文逗号分隔,空值时查询所有注册的信息 | + +#### Request + +```json +fields=base_info,resource_types,actions,action_groups,instance_selections,resource_creator_actions +``` +#### Response + +说明: +- 返回的信息数据结构与注册时的数据结构一致 + +```json +{ + "code": 0, + "message": "", + "data": { + // 基础信息 + "base_info": { + "id": "bk_cmdb", + "name": "配置平台", + "name_en": "CMDB", + "description": "配置平台是...", + "description_en": "CMDB is...", + "clients": "bk_cmdb,cmdb", + "provider_config": { + "host": "http://cmdb.service.consul", + "auth": "basic" + } + }, + // 资源类型 + "resource_types": [ + { + "id": "host", + "name": "主机", + "name_en": "host", + "description": "主机是...", + "description_en": "host is...", + "parents": [ + {"system_id": "bk_cmdb", "id": "module"} + ], + "provider_config": { + "path": "/api/v1/resources/host/query" + } + "version": 1 + }, + { + "id": "biz", + "name": "业务", + "name_en": "biz", + "description": "业务是...", + "description_en": "biz is...", + "parents": [ + {"system_id": "bk_cmdb", "id": "biz_set"} + ], + "provider_config": { + "path": "/api/v1/resources/biz_set/query" + } + "version": 1 + } + ], + // 操作 + "actions": [ + { + "id": "host_edit", + "name": "主机编辑New", + "name_en": "host_edit", + "description": "主机编辑New是...", + "description_en": "host_edit is...", + "type": "", + "related_resource_types": [ + { + "system_id": "bk_cmdb", + "id": "host", + "name_alias": "服务器", + "name_alias_en": "server", + "instance_selections": [ + { + "name": "资源池主机", + "name_en": "free host", + "resource_type_chain": [{"system_id": "bk_cmdb", "id": "host"}] + }, + { + "name": "业务拓扑", + "name_en": "biz topology", + "resource_type_chain": [{"system_id": "bk_cmdb", "id": "biz"}, {"system_id": "bk_cmdb", "id": "set"}, {"system_id": "bk_cmdb", "id": "module"}, {"system_id": "bk_cmdb", "id": "host"}] + }, + { + "name": "业务集拓扑", + "name_en": "biz set topology" + "resource_type_chain": [{"system_id": "bk_cmdb", "id": "biz_set"}, {"system_id": "bk_cmdb", "id": "set"}, {"system_id": "bk_cmdb", "id": "module"}, {"system_id": "bk_cmdb", "id": "host"}] + } + ] + } + ], + "version": 1, + } + ], + // 实例视图 + "instance_selections": [ + { + "id": "view1", + "name": "实例选择11", + "name_en": "view11", + "resource_type_chain": [ + { + "id": "bbbdd", + "system_id": "aaacc" + } + ] + } + ], + "resource_creator_actions": { + "config":[ + { + "id":"biz", + "actions":[ + { + "id":"biz_edit", + "required":false + }, + { + "id":"biz_view", + "required":true + }, + { + "id":"set_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"set", + "actions":[ + { + "id":"set_edit", + "required":false + }, + { + "id":"set_view", + "required":false + }, + { + "id":"module_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"module", + "actions":[ + { + "id":"module_edit", + "required":false + }, + { + "id":"module_view", + "required":false + }, + { + "id":"host_create", + "required":false + } + ], + "sub_resource_types":[ + { + "id":"host", + "actions":[ + { + "id":"host_edit", + "required":false + }, + { + "id":"host_view", + "required":false + } + ] + } + ] + } + ] + } + ] + } + ] + } + } +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_update.md.j2 b/saas/resources/apigateway/docs/zh/system_update.md.j2 new file mode 100644 index 000000000..86249223e --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_update.md.j2 @@ -0,0 +1,40 @@ +### 更新 system + +`路径中system_id是唯一标识; body中只需要传入要更新的字段, 其中对于provider_config是全覆盖更新,不支持只更新provider_config中某个字段` + +注意: + +- 更新 system 时如果没有把自己加入 clients, 会自动将当前发起`更新system`的 app_code 加入`clients`(即, 更新发起者无法将自己移除`clients`) + +------- + +{% include '_api_v1_model_system.md.j2' %} + +#### Parameters + +|字段 |类型 |是否必须 |位置 |描述 | +|:--|:--|:--|:--|:--| +|system_id |string |是 |path |系统 ID | + +#### Request + +```json +{ + "name": "配置平台", + "name_en": "CMDB", + "clients": "bk_cmdb,cmdb", + "provider_config": { + "host": "http://cmdb_new.service.consul" + } +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_update_action.md.j2 b/saas/resources/apigateway/docs/zh/system_update_action.md.j2 new file mode 100644 index 000000000..1ba29dc94 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_update_action.md.j2 @@ -0,0 +1,60 @@ +### 2. 修改 action + +---------- +{% include '_api_v1_model_actions.md.j2' %} +---------- + +**重点:** +- 可更新 name\name_en\type\version\related_resource_types 这 5 个 key 的值, 如果传了对应`key`并给了`空值`, 那么执行的是`置空操作`; 如果没有传`key`, 表示不更新该字段; +- `特别:对于related_resource_types是一个完全覆盖操作,不能单独更新related_resource_types里的某个key的值` + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| action_id | string | 是 | path | 操作 ID | + +#### Request + +```json +{ + "name":"主机编辑New", + "name_en":"host_edit", + "description":"主机编辑New是...", + "description_en":"host_edit is...", + "related_resource_types":[ + { + "system_id":"bk_cmdb", + "id":"host", + "name_alias":"", + "name_alias_en":"", + "selection_mode": "instance", + "related_instance_selections":[ + { + "system_id": "bk_cmdb", + "id": "free_host", + "ignore_iam_path": false, + }, + { + "system_id": "bk_cmdb", + "id": "biz_topology", + "ignore_iam_path": false, + } + ] + } + ], + "related_actions": ["view", "delete"], + "version":2 +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_update_configs.md.j2 b/saas/resources/apigateway/docs/zh/system_update_configs.md.j2 new file mode 100644 index 000000000..9f2992d26 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_update_configs.md.j2 @@ -0,0 +1,19 @@ +## 系统配置更新 + +{% include '_api_v1_model_system_config.md.j2' %} + +### action_groups 操作组 + +{% include './_api_v1_model_system_update_configs_action_groups.md.j2' %} + +### common_actions 常用操作 + +{% include './_api_v1_model_system_update_configs_common_actions.md.j2' %} + +### feature_shield_rules 功能开关 + +{% include './_api_v1_model_system_update_configs_feature_shield_rules.md.j2' %} + +### resource_creator_actions 新建关联 + +{% include './_api_v1_model_system_update_configs_resource_creator_actions.md.j2' %} diff --git a/saas/resources/apigateway/docs/zh/system_update_instance_selection.md.j2 b/saas/resources/apigateway/docs/zh/system_update_instance_selection.md.j2 new file mode 100644 index 000000000..8dbe1e670 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_update_instance_selection.md.j2 @@ -0,0 +1,36 @@ +### 修改 instanceSelection + +---------- +{% include '_api_v1_model_instance_selections.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:---|:--- | +| system_id | string | 是 | path | 系统 ID | +| instance_selection_id | string | 是 | path | 实例视图 ID | + +#### Request + +```json +{ + "id": "free_host1", + "name": "空闲主机1", + "name_en": "free host1", + "resource_type_chain": [{ + "system_id": "bk_cmdb", + "id": "host" + }] +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` diff --git a/saas/resources/apigateway/docs/zh/system_update_resource_types.md.j2 b/saas/resources/apigateway/docs/zh/system_update_resource_types.md.j2 new file mode 100644 index 000000000..a5ab28545 --- /dev/null +++ b/saas/resources/apigateway/docs/zh/system_update_resource_types.md.j2 @@ -0,0 +1,38 @@ +### 修改 resourceType + +---------- +{% include '_api_v1_model_resource_types.md.j2' %} +---------- + +#### Parameters + +| 字段 | 类型 | 是否必须 | 位置 | 描述 | +| :--- | :--- | :--- |:--- |:--- | +| system_id | string | 是 | path | 系统 ID | +| resource_type_id | string | 是 | path | 资源类型 ID | + +#### Request + +```json +{ + "name": "业务新", + "name_en": "biz new", + "description": "业务新...", + "description_en": "biz new is ....", + "provider_config": { + "path": "/api/v2/resources/biz/query" + }, + "version": 2 +} +``` + +#### Response + +```json +{ + "code": 0, + "message": "", + "data": {} +} +``` + diff --git a/saas/resources/apigateway/docs/zh/version.md.j2 b/saas/resources/apigateway/docs/zh/version.md.j2 new file mode 100644 index 000000000..3331b9d3f --- /dev/null +++ b/saas/resources/apigateway/docs/zh/version.md.j2 @@ -0,0 +1,17 @@ +### 获取程序版本 + +#### Request + +#### Response + +```json +{ + "buildTime": "2021-10-26_11:24:05", + "commit": "9a79a2e029c58a0e352aa43f2daa465beb1d5358", + "date": "2021-11-19T10:49:13.850879552+08:00", + "env": "", + "goVersion": "go version go1.16.3 linux/amd64", + "timestamp": 1637290153, + "version": "1.9.0" +} +``` diff --git a/saas/resources/version_log/V1.5.14_2021-11-30.md b/saas/resources/version_log/V1.5.14_2021-11-30.md new file mode 100644 index 000000000..54e5e499a --- /dev/null +++ b/saas/resources/version_log/V1.5.14_2021-11-30.md @@ -0,0 +1,14 @@ +# V1.5.14 版本更新日志 + +### 新增功能 +* 支持初始化接入APIGateway的API和文档 + +### 功能优化 +* 自动更新资源实例名称对大策略的防御性忽略 +* 新增接入系统管理类API的bk_nocode白名单 +* 调用第三方接口失败时支持返回异常信息 +* 用户组授权调整为立即执行任务 + +### 缺陷修复 +* 自动更新资源实例名称兼容接入系统回调异常 +* 解决未资源实例视图为空时导致授权异常 \ No newline at end of file diff --git a/saas/resources/version_log/V1.5.14_2021-11-30_en.md b/saas/resources/version_log/V1.5.14_2021-11-30_en.md new file mode 100644 index 000000000..7129c65b6 --- /dev/null +++ b/saas/resources/version_log/V1.5.14_2021-11-30_en.md @@ -0,0 +1,14 @@ +# V1.5.14 ChangeLog + +### New Features +* Support apigateway init with apis and docs + +### Optimization Updates +* Automatically update the resource instance name to ignore the defensiveness of the big strategy +* Added bk_nocode whitelist for accessing system management API +* Support to return exception information when calling a third-party interface fails +* User group authorization is adjusted to execute tasks immediately + +### Bug Fixes +* Automatically update the resource instance name to be compatible with the access system callback exception +* Solve the authorization exception when the resource instance view is empty diff --git a/saas/urls.py b/saas/urls.py index a30f65d9f..e39a1d5a0 100644 --- a/saas/urls.py +++ b/saas/urls.py @@ -62,7 +62,7 @@ ), # healthz url("", include("backend.healthz.urls")), - # promethus + # prometheus url("", include("django_prometheus.urls")), ]