Skip to content

Commit

Permalink
feat: create openapi such way that generated client code allows to up…
Browse files Browse the repository at this point in the history
…date configuration and inputs (#740)
  • Loading branch information
hsekowski-splunk authored and artemrys committed May 2, 2023
1 parent f2ae295 commit c412a60
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
# limitations under the License.
#
import copy
from enum import Flag, auto
from functools import lru_cache
from typing import List, Dict, Any, Optional, Union
from typing import List, Tuple, Dict, Any, Optional, Union
from splunk_add_on_ucc_framework import global_config as global_config_lib
from splunk_add_on_ucc_framework import app_manifest as app_manifest_lib
from splunk_add_on_ucc_framework.commands.openapi_generator.oas import (
Expand All @@ -27,6 +28,11 @@
)


class GloblaConfigPages(Flag):
CONFIGURATION = auto()
INPUTS = auto()


def __create_min_required(
global_config: global_config_lib.GlobalConfig,
) -> OpenAPIObject:
Expand Down Expand Up @@ -83,12 +89,23 @@ def __add_security_scheme_object(open_api_object: OpenAPIObject) -> OpenAPIObjec
return open_api_object


def __get_schema_object(*, name: str, entities: list) -> oas.SchemaObject:
def __create_schema_name(*, name, without: Optional[list] = None) -> str:
return f"{name}_without_{'_'.join(without)}" if without else name


def __get_schema_object(
*, name: str, entities: list, without: Optional[list] = None
) -> Tuple[str, oas.SchemaObject]:
name = __create_schema_name(name=name, without=without)
schema_object = oas.SchemaObject(
type="object", xml=oas.XMLObject(name=name), properties={}
)
for entity in entities:
if "helpLink" == entity.type:
if "helpLink" == entity.type or (
isinstance(without, list)
and hasattr(entity, "field")
and entity.field in without
):
continue
if schema_object.properties is not None:
schema_object.properties[entity.field] = {"type": "string"}
Expand All @@ -112,7 +129,7 @@ def __get_schema_object(*, name: str, entities: list) -> oas.SchemaObject:
)
if hasattr(entity, "encrypted") and entity.encrypted:
schema_object.properties[entity.field]["format"] = "password"
return schema_object
return (name, schema_object)


def __add_schemas_object(
Expand All @@ -121,17 +138,50 @@ def __add_schemas_object(
if open_api_object.components is not None:
open_api_object.components.schemas = {}
for tab in global_config.pages.configuration.tabs:
open_api_object.components.schemas[tab.name] = __get_schema_object(
schema_name, schema_object = __get_schema_object(
name=tab.name, entities=tab.entity
)
open_api_object.components.schemas[schema_name] = schema_object
schema_name, schema_object = __get_schema_object(
name=tab.name, entities=tab.entity, without=["name"]
)
open_api_object.components.schemas[schema_name] = schema_object
if hasattr(global_config.pages, "inputs") and hasattr(
global_config.pages.inputs, "services"
):
additional_input_entities = [
json_to_object.DataClasses(
json={
"field": "disabled",
"type": "singleSelect",
"options": {
"autoCompleteFields": [
{"value": "0"},
{"value": "1"},
]
},
}
)
]
for service in global_config.pages.inputs.services:
open_api_object.components.schemas[service.name] = __get_schema_object(
schema_name, schema_object = __get_schema_object(
name=service.name,
entities=service.entity,
entities=service.entity + additional_input_entities,
)
open_api_object.components.schemas[schema_name] = schema_object
schema_name, schema_object = __get_schema_object(
name=service.name,
entities=service.entity + additional_input_entities,
without=["name"],
)
open_api_object.components.schemas[schema_name] = schema_object
schema_name, schema_object = __get_schema_object(
name=service.name,
entities=service.entity + additional_input_entities,
without=["disabled"],
)
open_api_object.components.schemas[schema_name] = schema_object

return open_api_object


Expand Down Expand Up @@ -186,13 +236,17 @@ def __get_path_get_for_item(*, name: str) -> oas.OperationObject:
return __get_path_get(name=name, description=description)


def __get_path_post(*, name: str, description: str) -> oas.OperationObject:
def __get_path_post(
*, name: str, description: str, request_schema_without: Optional[List[str]] = None
) -> oas.OperationObject:
return oas.OperationObject(
description=description,
requestBody=oas.RequestBodyObject(
content={
"application/x-www-form-urlencoded": __get_media_type_object_with_schema_ref(
schema_name=name
schema_name=__create_schema_name(
name=name, without=request_schema_without
)
)
}
),
Expand All @@ -212,14 +266,22 @@ def __get_path_post(*, name: str, description: str) -> oas.OperationObject:
)


def __get_path_post_for_create(*, name: str) -> oas.OperationObject:
description = f"Create item in {name}"
return __get_path_post(name=name, description=description)
def __get_path_post_for_create(
*, name: str, page: GloblaConfigPages
) -> oas.OperationObject:
return __get_path_post(
name=name,
description=f"Create item in {name}",
request_schema_without=["disabled"]
if page == GloblaConfigPages.INPUTS
else None,
)


def __get_path_post_for_update(*, name: str) -> oas.OperationObject:
description = f"Update {name} item"
return __get_path_post(name=name, description=description)
return __get_path_post(
name=name, description=f"Update {name} item", request_schema_without=["name"]
)


def __get_path_delete(*, name: str) -> oas.OperationObject:
Expand Down Expand Up @@ -258,11 +320,12 @@ def __assign_ta_paths(
path: str,
path_name: str,
actions: List[str],
page: GloblaConfigPages,
):
if open_api_object.paths is not None:
open_api_object.paths[path] = oas.PathItemObject(
get=__get_path_get_for_list(name=path_name),
post=__get_path_post_for_create(name=path_name),
post=__get_path_post_for_create(name=path_name, page=page),
)
open_api_object.paths[path].parameters = [
__get_output_mode(),
Expand Down Expand Up @@ -302,6 +365,7 @@ def __add_paths(
actions=tab.table.actions
if hasattr(tab, "table") and hasattr(tab.table, "actions")
else None,
page=GloblaConfigPages.CONFIGURATION,
)
if hasattr(global_config.pages, "inputs") and hasattr(
global_config.pages.inputs, "services"
Expand All @@ -312,6 +376,7 @@ def __add_paths(
path=f"/{global_config.meta.restRoot}_{service.name}",
path_name=service.name,
actions=global_config.pages.inputs.table.actions,
page=GloblaConfigPages.INPUTS,
)
return open_api_object

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,39 @@
"wrapped": false
}
},
"account_without_name": {
"type": "object",
"properties": {
"custom_endpoint": {
"type": "string",
"enum": [
"login.example.com",
"test.example.com",
"other"
]
},
"endpoint": {
"type": "string"
},
"account_checkbox": {
"type": "string"
},
"account_radio": {
"type": "string"
},
"account_multiple_select": {
"type": "string"
},
"oauth": {
"type": "string"
}
},
"xml": {
"name": "account_without_name",
"attribute": false,
"wrapped": false
}
},
"proxy": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -97,6 +130,43 @@
"wrapped": false
}
},
"proxy_without_name": {
"type": "object",
"properties": {
"proxy_enabled": {
"type": "string"
},
"proxy_type": {
"type": "string",
"enum": [
"http",
"socks4",
"socks5"
]
},
"proxy_url": {
"type": "string"
},
"proxy_port": {
"type": "string"
},
"proxy_username": {
"type": "string"
},
"proxy_password": {
"type": "string",
"format": "password"
},
"proxy_rdns": {
"type": "string"
}
},
"xml": {
"name": "proxy_without_name",
"attribute": false,
"wrapped": false
}
},
"logging": {
"type": "object",
"properties": {
Expand All @@ -117,6 +187,26 @@
"wrapped": false
}
},
"logging_without_name": {
"type": "object",
"properties": {
"loglevel": {
"type": "string",
"enum": [
"DEBUG",
"INFO",
"WARNING",
"ERROR",
"CRITICAL"
]
}
},
"xml": {
"name": "logging_without_name",
"attribute": false,
"wrapped": false
}
},
"custom_abc": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -147,6 +237,37 @@
"attribute": false,
"wrapped": false
}
},
"custom_abc_without_name": {
"type": "object",
"properties": {
"testString": {
"type": "string"
},
"testNumber": {
"type": "string"
},
"testRegex": {
"type": "string"
},
"testEmail": {
"type": "string"
},
"testIpv4": {
"type": "string"
},
"testDate": {
"type": "string"
},
"testUrl": {
"type": "string"
}
},
"xml": {
"name": "custom_abc_without_name",
"attribute": false,
"wrapped": false
}
}
},
"securitySchemes": {
Expand Down Expand Up @@ -282,7 +403,7 @@
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/account"
"$ref": "#/components/schemas/account_without_name"
}
}
},
Expand Down

0 comments on commit c412a60

Please sign in to comment.