Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: api插件配置拓展 新增过滤空字段 #112

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ def _dispatch_schedule_trigger(self, data, parent_data, callback_data=None):
callback = api_data.pop("uniform_api_plugin_callback", None)
method = api_data.pop("uniform_api_plugin_method")
resp_data_path: str = api_data.pop("response_data_path", None)

# 获取空间相关配置信息
interface_client = InterfaceModuleClient()
space_infos_result = interface_client.get_space_infos(
Expand All @@ -137,10 +136,17 @@ def _dispatch_schedule_trigger(self, data, parent_data, callback_data=None):
return False

space_configs = space_infos_result.get("data", {}).get("configs", {})
if space_configs.get("uniform_api", {}).get("common", {}).get("exclude_none_fields", False):
self.logger.info("exclude_none_fields config true, poping none fields variable...")
# 过滤字符串为空的基础类型
keys_to_remove = [key for key, value in api_data.items() if value == ""]
for key in keys_to_remove:
api_data.pop(key)
self.logger.info(f"plugin_data after poping: {api_data}")

# 开启的enable_api_parameter_conversion配置只对POST参数生效
if (
space_configs.get("uniform_api", {}).get("enable_api_parameter_conversion", False)
space_configs.get("uniform_api", {}).get("common", {}).get("enable_api_parameter_conversion", False)
and method.upper() == "POST"
):
# 启动参数转换
Expand Down
18 changes: 13 additions & 5 deletions bkflow/pipeline_plugins/query/uniform_api/uniform_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
class UniformAPICategorySerializer(serializers.Serializer):
scope_type = serializers.CharField(required=False)
scope_value = serializers.CharField(required=False)
key = serializers.CharField(required=False)
key = serializers.CharField(required=True)


class UniformAPIListSerializer(serializers.Serializer):
Expand All @@ -41,7 +41,7 @@ class UniformAPIListSerializer(serializers.Serializer):
scope_type = serializers.CharField(required=False)
scope_value = serializers.CharField(required=False)
category = serializers.CharField(required=False)
key = serializers.CharField(required=False)
key = serializers.CharField(required=True)


class UniformAPIMetaSerializer(serializers.Serializer):
Expand All @@ -51,11 +51,19 @@ class UniformAPIMetaSerializer(serializers.Serializer):


def _get_space_uniform_api_list_info(space_id, request_data, config_key):
uniform_api_config = SpaceConfig.get_config(space_id=space_id, config_name=UniformApiConfig.name)
if not uniform_api_config.get(config_key):
uniform_api_configs = SpaceConfig.get_config(space_id=space_id, config_name=UniformApiConfig.name)
if not uniform_api_configs:
raise ValidationError("接入平台未注册统一API, 请联系对应接入平台管理员")
client = UniformAPIClient()
url = uniform_api_config[config_key]
if uniform_api_configs.get("api"):
# 新协议多一层 api
api_config = uniform_api_configs.get("api").get(request_data.get("key"), None)
if not api_config:
raise ValidationError("对应统一API未配置")
url = api_config[config_key]
else:
url = uniform_api_configs[config_key]
# 旧协议直接获取
request_result: HttpRequestResult = client.request(url=url, method="GET", data=request_data)
if not request_result.result:
raise APIResponseError(f"请求统一API列表失败: {request_result.message}")
Expand Down
45 changes: 36 additions & 9 deletions bkflow/space/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,27 +207,40 @@ class UniformApiConfig(BaseSpaceConfig):
value_type = SpaceConfigValueType.JSON.value
default_value = {}
example = {"meta_apis": "{meta_apis url}", "api_categories": "{api_categories url}"}
# 拓展后也支持 example = {"key": {"meta_apis": "{meta_apis url}", "api_categories": "{api_categories url}"}}

class Keys(Enum):
META_APIS = "meta_apis"
API_CATEGORIES = "api_categories"
APIS = "api"

SCHEMA = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个一般就是 SCHEMA_V2,不然无法比较 SCHEMA 和 SCHEMA_V1 谁更新

"type": "object",
"required": ["meta_apis"],
"properties": {
Keys.META_APIS.value: {"type": "string"},
Keys.API_CATEGORIES.value: {"type": "string"},
"api": {
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9_]+$": {
"type": "object",
"required": ["meta_apis"],
"properties": {
"meta_apis": {"type": "string"},
"api_categories": {"type": "string"},
"display_name": {"type": "string"},
},
"additionalProperties": False,
}
},
"additionalProperties": False,
},
"common": {"type": "object", "additionalProperties": True},
},
"required": ["api"],
"additionalProperties": False,
}

@classmethod
def validate(cls, value: dict):
try:
jsonschema.validate(value, cls.SCHEMA)
except jsonschema.ValidationError as e:
raise ValidationError(f"[validate uniform api config error]: {str(e)}")

def check_url(cls, value):
meta_apis_from_apigw = check_url_from_apigw(value[cls.Keys.META_APIS.value])
category_config = value.get(cls.Keys.API_CATEGORIES.value)
api_categories_from_apigw = check_url_from_apigw(category_config) if category_config else True
Expand All @@ -237,6 +250,20 @@ def validate(cls, value: dict):
)
return True

@classmethod
def validate(cls, value: dict):
try:
jsonschema.validate(value, cls.SCHEMA)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的 validate 也可以用 handler 来处理和校验的,这块的逻辑都可以换掉

except jsonschema.ValidationError as e:
raise ValidationError(f"[validate uniform api config error]: {str(e)}")
if cls.Keys.APIS.value in value.keys():
for obj in value.get(cls.Keys.APIS.value).values():
cls.check_url(obj)
else:
# 单层旧协议兼容
cls.check_url(value)
return True


class SuperusersConfig(BaseSpaceConfig):
name = "superusers"
Expand Down
Loading