From 4d9b57700726c6f1bb1d8c6d00c7462d377ee43a Mon Sep 17 00:00:00 2001 From: "zhu.boxiang" Date: Wed, 13 Jul 2022 15:21:51 +0800 Subject: [PATCH] refactor: Refactor schemas 1. adjust setting schemas 2. adjust prometheus schemas 3. adjust policy schemas 4. adjust policy_manager schemas 5. adjust login schemas 6. remove some invalid model 7. update the swagger.json file Change-Id: I6b513498999f1c56481107ca78df656e4c8b38cb --- docs/api/swagger.json | 252 +++++++++++++------- skyline_apiserver/policy/manager/base.py | 16 +- skyline_apiserver/schemas/__init__.py | 3 +- skyline_apiserver/schemas/login.py | 79 +++--- skyline_apiserver/schemas/policy.py | 10 +- skyline_apiserver/schemas/policy_manager.py | 12 +- skyline_apiserver/schemas/prometheus.py | 58 +++-- skyline_apiserver/schemas/setting.py | 22 +- 8 files changed, 269 insertions(+), 183 deletions(-) diff --git a/docs/api/swagger.json b/docs/api/swagger.json index 9df98f7..98bbf24 100644 --- a/docs/api/swagger.json +++ b/docs/api/swagger.json @@ -1915,19 +1915,23 @@ "properties": { "region": { "title": "Region", - "type": "string" + "type": "string", + "description": "Credential user region" }, "domain": { "title": "Domain", - "type": "string" + "type": "string", + "description": "Credential user domain" }, "username": { "title": "Username", - "type": "string" + "type": "string", + "description": "Credential username" }, "password": { "title": "Password", - "type": "string" + "type": "string", + "description": "Credential password for user" } }, "example": { @@ -1947,11 +1951,13 @@ "properties": { "id": { "title": "Id", - "type": "string" + "type": "string", + "description": "Domain ID" }, "name": { "title": "Name", - "type": "string" + "type": "string", + "description": "Domain name" } } }, @@ -2960,7 +2966,8 @@ "type": "array", "items": { "$ref": "#/components/schemas/Policy" - } + }, + "description": "Policies list" } } }, @@ -2976,7 +2983,8 @@ "type": "array", "items": { "type": "string" - } + }, + "description": "Policies rules list" } } }, @@ -2990,11 +2998,13 @@ "properties": { "rule": { "title": "Rule", - "type": "string" + "type": "string", + "description": "Policy rule" }, "allowed": { "title": "Allowed", - "type": "boolean" + "type": "boolean", + "description": "Policy allowed" } } }, @@ -3003,74 +3013,97 @@ "required": [ "keystone_token", "region", + "exp", + "uuid", "project", "user", "roles", "keystone_token_exp", - "exp", - "uuid", "version" ], "type": "object", "properties": { "keystone_token": { "title": "Keystone Token", - "type": "string" + "type": "string", + "description": "Keystone token" }, "region": { "title": "Region", - "type": "string" + "type": "string", + "description": "User region" + }, + "exp": { + "title": "Exp", + "type": "integer", + "description": "Token expiration time" + }, + "uuid": { + "title": "Uuid", + "type": "string", + "description": "UUID" }, "project": { - "$ref": "#/components/schemas/Project" + "title": "Project", + "allOf": [ + { + "$ref": "#/components/schemas/Project" + } + ], + "description": "User project" }, "user": { - "$ref": "#/components/schemas/User" + "title": "User", + "allOf": [ + { + "$ref": "#/components/schemas/User" + } + ], + "description": "User" }, "roles": { "title": "Roles", "type": "array", "items": { "$ref": "#/components/schemas/Role" - } + }, + "description": "User roles" }, "keystone_token_exp": { "title": "Keystone Token Exp", - "type": "string" + "type": "string", + "description": "Keystone token expiration time" }, "base_roles": { "title": "Base Roles", "type": "array", "items": { "type": "string" - } + }, + "description": "User base roles" }, "base_domains": { "title": "Base Domains", "type": "array", "items": { "type": "string" - } + }, + "description": "User base domains" }, "endpoints": { "title": "Endpoints", - "type": "object" + "type": "object", + "description": "Keystone endpoints" }, "projects": { "title": "Projects", - "type": "object" - }, - "exp": { - "title": "Exp", - "type": "integer" - }, - "uuid": { - "title": "Uuid", - "type": "string" + "type": "object", + "description": "User projects" }, "version": { "title": "Version", - "type": "string" + "type": "string", + "description": "Version" } } }, @@ -3085,56 +3118,68 @@ "properties": { "id": { "title": "Id", - "type": "string" + "type": "string", + "description": "Project ID" }, "name": { "title": "Name", - "type": "string" + "type": "string", + "description": "Project name" }, "domain": { - "$ref": "#/components/schemas/Domain" + "title": "Domain", + "allOf": [ + { + "$ref": "#/components/schemas/Domain" + } + ], + "description": "Project domain" } } }, "PrometheusQueryData": { "title": "PrometheusQueryData", "required": [ - "result", - "resultType" + "resultType", + "result" ], "type": "object", "properties": { + "resultType": { + "title": "Resulttype", + "type": "string", + "description": "Prometheus result type" + }, "result": { "title": "Result", "type": "array", "items": { "$ref": "#/components/schemas/PrometheusQueryResult" - } - }, - "resultType": { - "title": "Resulttype", - "type": "string" + }, + "description": "Prometheus query result" } } }, "PrometheusQueryRangeData": { "title": "PrometheusQueryRangeData", "required": [ - "result", - "resultType" + "resultType", + "result" ], "type": "object", "properties": { + "resultType": { + "title": "Resulttype", + "type": "string", + "description": "Prometheus result type" + }, "result": { "title": "Result", "type": "array", "items": { "$ref": "#/components/schemas/PrometheusQueryRangeResult" - } - }, - "resultType": { - "title": "Resulttype", - "type": "string" + }, + "description": "Prometheus query range result" } } }, @@ -3147,22 +3192,32 @@ "properties": { "status": { "title": "Status", - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/PrometheusQueryRangeData" + "type": "string", + "description": "Prometheus status" }, "errorType": { "title": "Errortype", - "type": "string" + "type": "string", + "description": "Prometheus error type" }, "error": { "title": "Error", - "type": "string" + "type": "string", + "description": "Prometheus error" }, "warnings": { "title": "Warnings", - "type": "string" + "type": "string", + "description": "Prometheus warnings" + }, + "data": { + "title": "Data", + "allOf": [ + { + "$ref": "#/components/schemas/PrometheusQueryRangeData" + } + ], + "description": "Prometheus query range data" } } }, @@ -3170,7 +3225,7 @@ "title": "PrometheusQueryRangeResult", "required": [ "metric", - "values" + "value" ], "type": "object", "properties": { @@ -3179,12 +3234,14 @@ "type": "object", "additionalProperties": { "type": "string" - } + }, + "description": "Prometheus metric" }, - "values": { - "title": "Values", + "value": { + "title": "Value", "type": "array", - "items": {} + "items": {}, + "description": "Prometheus metric value" } } }, @@ -3197,22 +3254,32 @@ "properties": { "status": { "title": "Status", - "type": "string" - }, - "data": { - "$ref": "#/components/schemas/PrometheusQueryData" + "type": "string", + "description": "Prometheus status" }, "errorType": { "title": "Errortype", - "type": "string" + "type": "string", + "description": "Prometheus error type" }, "error": { "title": "Error", - "type": "string" + "type": "string", + "description": "Prometheus error" }, "warnings": { "title": "Warnings", - "type": "string" + "type": "string", + "description": "Prometheus warnings" + }, + "data": { + "title": "Data", + "allOf": [ + { + "$ref": "#/components/schemas/PrometheusQueryData" + } + ], + "description": "Prometheus query data" } } }, @@ -3229,12 +3296,14 @@ "type": "object", "additionalProperties": { "type": "string" - } + }, + "description": "Prometheus metric" }, "value": { "title": "Value", "type": "array", - "items": {} + "items": {}, + "description": "Prometheus metric value" } } }, @@ -3248,11 +3317,13 @@ "properties": { "id": { "title": "Id", - "type": "string" + "type": "string", + "description": "Role ID" }, "name": { "title": "Name", - "type": "string" + "type": "string", + "description": "Role name" } } }, @@ -3260,24 +3331,29 @@ "title": "Setting", "required": [ "key", + "value", "restart_service" ], "type": "object", "properties": { "key": { "title": "Key", - "type": "string" + "type": "string", + "description": "Key of setting" }, "value": { - "title": "Value" + "title": "Value", + "description": "Value of setting" }, "hidden": { "title": "Hidden", - "type": "boolean" + "type": "boolean", + "description": "Hidden setting or not" }, "restart_service": { "title": "Restart Service", - "type": "boolean" + "type": "boolean", + "description": "Restart service or not to apply setting" } } }, @@ -3293,7 +3369,8 @@ "type": "array", "items": { "$ref": "#/components/schemas/Setting" - } + }, + "description": "Settings" } } }, @@ -3314,16 +3391,19 @@ "UpdateSetting": { "title": "UpdateSetting", "required": [ - "key" + "key", + "value" ], "type": "object", "properties": { "key": { "title": "Key", - "type": "string" + "type": "string", + "description": "Key of setting" }, "value": { - "title": "Value" + "title": "Value", + "description": "Value of setting" } } }, @@ -3338,14 +3418,22 @@ "properties": { "id": { "title": "Id", - "type": "string" + "type": "string", + "description": "User ID" }, "name": { "title": "Name", - "type": "string" + "type": "string", + "description": "User name" }, "domain": { - "$ref": "#/components/schemas/Domain" + "title": "Domain", + "allOf": [ + { + "$ref": "#/components/schemas/Domain" + } + ], + "description": "User domain" } } }, diff --git a/skyline_apiserver/policy/manager/base.py b/skyline_apiserver/policy/manager/base.py index 4a45d08..100f9ba 100644 --- a/skyline_apiserver/policy/manager/base.py +++ b/skyline_apiserver/policy/manager/base.py @@ -19,7 +19,7 @@ from typing import List from oslo_policy import _parser # type: ignore from oslo_policy.policy import DocumentedRuleDefault, RuleDefault # type: ignore -from skyline_apiserver.schemas.policy_manager import Operation, OperationsSchema, ScopeTypesSchema +from skyline_apiserver import schemas class Rule: @@ -68,15 +68,15 @@ class APIRule(Rule): check_str: str, description: str, scope_types: List[str], - operations: List[Operation], + operations: List[schemas.Operation], basic_check_str: str = "", ) -> None: super().__init__(name, check_str, description, basic_check_str) - ScopeTypesSchema.parse_obj(scope_types) + schemas.ScopeTypesSchema.parse_obj(scope_types) self.scope_types = scope_types - OperationsSchema.parse_obj(operations) + schemas.OperationsSchema.parse_obj(operations) self.operations = operations def format_into_yaml(self) -> str: @@ -105,13 +105,15 @@ class APIRule(Rule): method = operation.get("method") if isinstance(method, list): for i in method: - operations.append(Operation(method=i.upper(), path=operation.get("path", ""))) + operations.append( + schemas.Operation(method=i.upper(), path=operation.get("path", "")) + ) elif isinstance(method, str): operations.append( - Operation(method=method.upper(), path=operation.get("path", "")), + schemas.Operation(method=method.upper(), path=operation.get("path", "")), ) else: - operations.append(Operation(method="GET", path=operation.get("path", ""))) + operations.append(schemas.Operation(method="GET", path=operation.get("path", ""))) return cls( name=rule.name, check_str=rule.check_str, diff --git a/skyline_apiserver/schemas/__init__.py b/skyline_apiserver/schemas/__init__.py index 8dafb42..8cc9d6b 100644 --- a/skyline_apiserver/schemas/__init__.py +++ b/skyline_apiserver/schemas/__init__.py @@ -42,8 +42,9 @@ from .extension import ( ExtVolumeSortKey, ExtVolumeStatus, ) -from .login import Credential, Domain, License, Payload, Profile, Project, Region, Role +from .login import Credential, Payload, Profile from .policy import Policies, PoliciesRules +from .policy_manager import Operation, OperationsSchema, ScopeTypesSchema from .prometheus import ( PrometheusQueryData, PrometheusQueryRangeData, diff --git a/skyline_apiserver/schemas/login.py b/skyline_apiserver/schemas/login.py index 6f4ee01..3be341f 100644 --- a/skyline_apiserver/schemas/login.py +++ b/skyline_apiserver/schemas/login.py @@ -17,17 +17,17 @@ from __future__ import annotations from typing import Any, Dict, List, Optional from jose import jwt -from pydantic import BaseModel +from pydantic import BaseModel, Field from skyline_apiserver import config from skyline_apiserver.types import constants class Credential(BaseModel): - region: str - domain: str - username: str - password: str + region: str = Field(..., description="Credential user region") + domain: str = Field(..., description="Credential user domain") + username: str = Field(..., description="Credential username") + password: str = Field(..., description="Credential password for user") class Config: schema_extra = { @@ -41,46 +41,35 @@ class Credential(BaseModel): class Domain(BaseModel): - id: str - name: str - - -class License(BaseModel): - name: str - summary: str - macs: List[str] - features: List[Dict[str, Any]] - start: str - end: str - - -class Region(BaseModel): - id: str + id: str = Field(..., description="Domain ID") + name: str = Field(..., description="Domain name") class Role(BaseModel): - id: str - name: str + id: str = Field(..., description="Role ID") + name: str = Field(..., description="Role name") class Project(BaseModel): - id: str - name: str - domain: Domain + id: str = Field(..., description="Project ID") + name: str = Field(..., description="Project name") + domain: Domain = Field(..., description="Project domain") class User(BaseModel): - id: str - name: str - domain: Domain + id: str = Field(..., description="User ID") + name: str = Field(..., description="User name") + domain: Domain = Field(..., description="User domain") -class Payload(BaseModel): - keystone_token: str - region: str - exp: int - uuid: str +class PayloadBase(BaseModel): + keystone_token: str = Field(..., description="Keystone token") + region: str = Field(..., description="User region") + exp: int = Field(..., description="Token expiration time") + uuid: str = Field(..., description="UUID") + +class Payload(PayloadBase): def toDict(self) -> Dict[str, Any]: return { "keystone_token": self.keystone_token, @@ -97,20 +86,16 @@ class Payload(BaseModel): ) -class Profile(BaseModel): - keystone_token: str - region: str - project: Project - user: User - roles: List[Role] - keystone_token_exp: str - base_roles: Optional[List[str]] - base_domains: Optional[List[str]] - endpoints: Optional[Dict[str, Any]] - projects: Optional[Dict[str, Any]] - exp: int - uuid: str - version: str +class Profile(PayloadBase): + project: Project = Field(..., description="User project") + user: User = Field(..., description="User") + roles: List[Role] = Field(..., description="User roles") + keystone_token_exp: str = Field(..., description="Keystone token expiration time") + base_roles: Optional[List[str]] = Field(None, description="User base roles") + base_domains: Optional[List[str]] = Field(None, description="User base domains") + endpoints: Optional[Dict[str, Any]] = Field(None, description="Keystone endpoints") + projects: Optional[Dict[str, Any]] = Field(None, description="User projects") + version: str = Field(..., description="Version") def toPayLoad(self) -> Payload: return Payload( diff --git a/skyline_apiserver/schemas/policy.py b/skyline_apiserver/schemas/policy.py index 8179ba6..3aaa0a4 100644 --- a/skyline_apiserver/schemas/policy.py +++ b/skyline_apiserver/schemas/policy.py @@ -16,17 +16,17 @@ from __future__ import annotations from typing import List -from pydantic import BaseModel +from pydantic import BaseModel, Field class Policy(BaseModel): - rule: str - allowed: bool + rule: str = Field(..., description="Policy rule") + allowed: bool = Field(..., description="Policy allowed") class Policies(BaseModel): - policies: List[Policy] + policies: List[Policy] = Field(..., description="Policies list") class PoliciesRules(BaseModel): - rules: List[str] + rules: List[str] = Field(..., description="Policies rules list") diff --git a/skyline_apiserver/schemas/policy_manager.py b/skyline_apiserver/schemas/policy_manager.py index 961ac8d..16eb1c1 100644 --- a/skyline_apiserver/schemas/policy_manager.py +++ b/skyline_apiserver/schemas/policy_manager.py @@ -17,7 +17,7 @@ from __future__ import annotations from enum import Enum from typing import List, TypedDict -from pydantic import BaseModel +from pydantic import BaseModel, Field class ScopeType(str, Enum): @@ -27,7 +27,7 @@ class ScopeType(str, Enum): class ScopeTypesSchema(BaseModel): - __root__: List[ScopeType] + __root__: List[ScopeType] = Field(..., description="Scope types list") class Method(str, Enum): @@ -45,12 +45,12 @@ class Operation(TypedDict): class OperationSchema(BaseModel): - method: Method - path: str + method: Method = Field(..., description="Operation method") + path: str = Field(..., description="Operation path") class OperationsSchema(BaseModel): - __root__: List[OperationSchema] + __root__: List[OperationSchema] = Field(..., description="Operations list") -__all__ = ("ScopeType", "ScopeTypesSchema", "Method", "Operation", "OperationsSchema") +__all__ = ("ScopeTypesSchema", "Operation", "OperationsSchema") diff --git a/skyline_apiserver/schemas/prometheus.py b/skyline_apiserver/schemas/prometheus.py index 96f0e99..29fceaf 100644 --- a/skyline_apiserver/schemas/prometheus.py +++ b/skyline_apiserver/schemas/prometheus.py @@ -2,40 +2,48 @@ from __future__ import annotations from typing import Any, Dict, List, Optional -from pydantic import BaseModel +from pydantic import BaseModel, Field -class PrometheusQueryResult(BaseModel): - metric: Dict[str, str] - value: List[Any] +class PrometheusQueryResultBase(BaseModel): + metric: Dict[str, str] = Field(..., description="Prometheus metric") + value: List[Any] = Field(..., description="Prometheus metric value") -class PrometheusQueryData(BaseModel): - result: List[PrometheusQueryResult] - resultType: str +class PrometheusQueryDataBase(BaseModel): + resultType: str = Field(..., description="Prometheus result type") -class PrometheusQueryResponse(BaseModel): - status: str - data: Optional[PrometheusQueryData] - errorType: Optional[str] - error: Optional[str] - warnings: Optional[str] +class PrometheusResponseBase(BaseModel): + status: str = Field(..., description="Prometheus status") + errorType: Optional[str] = Field(None, description="Prometheus error type") + error: Optional[str] = Field(None, description="Prometheus error") + warnings: Optional[str] = Field(None, description="Prometheus warnings") -class PrometheusQueryRangeResult(BaseModel): - metric: Dict[str, str] - values: List[Any] +class PrometheusQueryResult(PrometheusQueryResultBase): + """""" -class PrometheusQueryRangeData(BaseModel): - result: List[PrometheusQueryRangeResult] - resultType: str +class PrometheusQueryData(PrometheusQueryDataBase): + result: List[PrometheusQueryResult] = Field(..., description="Prometheus query result") -class PrometheusQueryRangeResponse(BaseModel): - status: str - data: Optional[PrometheusQueryRangeData] - errorType: Optional[str] - error: Optional[str] - warnings: Optional[str] +class PrometheusQueryResponse(PrometheusResponseBase): + data: Optional[PrometheusQueryData] = Field(None, description="Prometheus query data") + + +class PrometheusQueryRangeResult(PrometheusQueryResultBase): + """""" + + +class PrometheusQueryRangeData(PrometheusQueryDataBase): + result: List[PrometheusQueryRangeResult] = Field( + ..., description="Prometheus query range result" + ) + + +class PrometheusQueryRangeResponse(PrometheusResponseBase): + data: Optional[PrometheusQueryRangeData] = Field( + None, description="Prometheus query range data" + ) diff --git a/skyline_apiserver/schemas/setting.py b/skyline_apiserver/schemas/setting.py index f493f76..6f1bcac 100644 --- a/skyline_apiserver/schemas/setting.py +++ b/skyline_apiserver/schemas/setting.py @@ -14,20 +14,22 @@ from typing import Any, List, Optional -from pydantic import BaseModel +from pydantic import BaseModel, Field -class Setting(BaseModel): - key: str - value: Any - hidden: Optional[bool] - restart_service: bool +class SettingBase(BaseModel): + key: str = Field(..., description="Key of setting") + value: Any = Field(..., description="Value of setting") -class UpdateSetting(BaseModel): - key: str - value: Any +class Setting(SettingBase): + hidden: Optional[bool] = Field(None, description="Hidden setting or not") + restart_service: bool = Field(..., description="Restart service or not to apply setting") + + +class UpdateSetting(SettingBase): + """""" class Settings(BaseModel): - settings: List[Setting] + settings: List[Setting] = Field(..., description="Settings")