diff --git a/codegenerator/metadata/__init__.py b/codegenerator/metadata/__init__.py index 5ba9e5f..3eb8985 100644 --- a/codegenerator/metadata/__init__.py +++ b/codegenerator/metadata/__init__.py @@ -29,6 +29,7 @@ from codegenerator.metadata.compute import ComputeMetadata from codegenerator.metadata.dns import DnsMetadata from codegenerator.metadata.identity import IdentityMetadata from codegenerator.metadata.image import ImageMetadata +from codegenerator.metadata.key_manager import KeyManagerMetadata from codegenerator.metadata.load_balancer import LoadBalancerMetadata from codegenerator.metadata.network import NetworkMetadata from codegenerator.metadata.object_store import ObjectStorageMetadata @@ -57,6 +58,7 @@ SERVICE_METADATA_MAP: dict[str, ty.Type[MetadataBase]] = { "dns": DnsMetadata, "identity": IdentityMetadata, "image": ImageMetadata, + "key-manager": KeyManagerMetadata, "load-balancer": LoadBalancerMetadata, "network": NetworkMetadata, "object-store": ObjectStorageMetadata, diff --git a/codegenerator/metadata/key_manager.py b/codegenerator/metadata/key_manager.py new file mode 100644 index 0000000..ffc6998 --- /dev/null +++ b/codegenerator/metadata/key_manager.py @@ -0,0 +1,33 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# +import typing as ty + +from codegenerator.types import OperationModel +from codegenerator.metadata.base import MetadataBase + + +class KeyManagerMetadata(MetadataBase): + @staticmethod + def get_operation_key( + operation, path: str, method: str, resource_name: str + ) -> ty.Tuple[str | None, bool]: + skip: bool = False + operation_key: str | None = None + + return (operation_key, skip) + + @staticmethod + def post_process_operation( + resource_name: str, operation_name: str, operation + ): + return operation diff --git a/codegenerator/openapi/barbican.py b/codegenerator/openapi/barbican.py new file mode 100644 index 0000000..1b0c45c --- /dev/null +++ b/codegenerator/openapi/barbican.py @@ -0,0 +1,462 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# +import inspect +from multiprocessing import Process +from pathlib import Path +from unittest import mock + +import fixtures + +from codegenerator.common.schema import SpecSchema +from codegenerator.openapi.base import OpenStackServerSourceBase +from codegenerator.openapi.utils import merge_api_ref_doc + +from ruamel.yaml.scalarstring import LiteralScalarString + + +class BarbicanGenerator(OpenStackServerSourceBase): + URL_TAG_MAP = {} + + def __init__(self): + pass + + def _api_ver_major(self, ver): + return ver.ver_major + + def _api_ver_minor(self, ver): + return ver.ver_minor + + def _api_ver(self, ver): + return (ver.ver_major, ver.ver_minor) + + def _build_routes( + self, mapper, node, path="", param_url_map: dict[str, str] = {} + ): + resource: str | None = None + # Construct resource name from the path + parent = path.split("/")[-1] + if parent == "v1": + resource = "" + elif parent.endswith("ies"): + resource = parent[0 : len(parent) - 3] + "y" + else: + resource = parent[0:-1] + + for part in [x for x in dir(node) if callable(getattr(node, x))]: + # Iterate over functions to find what is exposed on the current + # level + obj = getattr(node, part) + _pecan = getattr(obj, "_pecan", None) + exposed = getattr(obj, "exposed", None) + if _pecan and exposed: + # Only whatever is pecan exposed is of interest + conditions = {} + action = None + url = path + # resource = None + # parent = url.split("/")[-1] + # Identify the action from function name + # https://pecan.readthedocs.io/en/latest/rest.html#url-mapping + if part == "on_get": + if not resource: + continue + conditions["method"] = ["GET"] + action = "show" + url += f"/{{{resource}_id}}" + elif part == "index": + conditions["method"] = ["GET"] + action = "list" + elif part == "get": + conditions["method"] = ["GET"] + action = "get" + # "Get" is tricky, it can be normal and root, so need to inspect params + sig = inspect.signature(obj) + for pname, pval in sig.parameters.items(): + if "id" in pname and pval.default == pval.empty: + url += f"/{{{resource}_id}}" + elif part == "on_post": + conditions["method"] = ["POST"] + action = "create" + # url += f"/{{{resource}_id}}" + elif part == "on_put": + conditions["method"] = ["PUT"] + action = "update" + url += f"/{{{resource}_id}}" + elif part == "on_delete": + conditions["method"] = ["DELETE"] + action = "delete" + url += f"/{{{resource}_id}}" + elif part.startswith("get_"): + conditions["method"] = ["GET"] + action = part[4:] + url += f"/{action.replace('_', '-')}" + + if action: + # If we identified method as "interesting" register it into + # the routes mapper + mapper.connect( + None, + url, + controller=obj, + action=action, + conditions=conditions, + ) + + if not hasattr(node, "__dict__"): + return + + for subcontroller, v in ( + node.__dict__.items() + if isinstance(node, object) + else node.__class__.__dict__.items() + ): + # Iterate over node attributes for subcontrollers + if subcontroller.startswith("_"): + continue + # if subcontroller in ["central_api", "__wrapped__", "SORT_KEYS"]: + # # Not interested in those + # continue + subpath = f"{path}/{subcontroller}" + next_param_url_map: dict = { + k: f"{v}/{subcontroller}" for k, v in param_url_map.items() + } + self._build_routes(mapper, v, subpath, next_param_url_map) + + return + + def generate(self, target_dir, args): + proc = Process(target=self._generate, args=[target_dir, args]) + proc.start() + proc.join() + if proc.exitcode != 0: + raise RuntimeError("Error generating Barbican OpenAPI schema") + + def _generate(self, target_dir, args): + from barbican.api import app + from barbican.api.controllers import acls + from barbican.api.controllers import containers + from barbican.api.controllers import consumers + from barbican.api.controllers import orders + from barbican.api.controllers import quotas + from barbican.api.controllers import secrets + from barbican.api.controllers import secretmeta + from barbican.api.controllers import secretstores + from barbican.api.controllers import transportkeys + from barbican.api.controllers import versions + + from routes import Mapper + + self.api_version = versions.MAX_API_VERSION + self.min_api_version = versions.MIN_API_VERSION + + work_dir = Path(target_dir) + work_dir.mkdir(parents=True, exist_ok=True) + + impl_path = Path( + work_dir, + "openapi_specs", + "key-manager", + f"v{self.api_version}.yaml", + ) + impl_path.parent.mkdir(parents=True, exist_ok=True) + openapi_spec = self.load_openapi(Path(impl_path)) + if not openapi_spec: + openapi_spec = SpecSchema( + info={ + "title": "OpenStack key-manager API", + "description": LiteralScalarString( + "key-manager API provided by Barbican service" + ), + "version": self.api_version, + }, + openapi="3.1.0", + security=[{"ApiKeyAuth": []}], + components={ + "securitySchemes": { + "ApiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "X-Auth-Token", + } + } + }, + ) + + self.app = app.build_wsgi_app(controller=None) + self.root = self.app.root + mapper = Mapper() + self._build_routes(mapper, self.root, "/v1") + mapper.connect( + None, + "/v1/secrets/{secret_id}", + controller=secrets.SecretController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}", + controller=secrets.SecretController.on_put, + action="create", + conditions={"method": ["PUT"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}", + controller=secrets.SecretController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/payload", + controller=secrets.SecretController.payload, + action="payload", + conditions={"method": ["GET"]}, + ) + # Secret ACL + mapper.connect( + None, + "/v1/secrets/{secret_id}/acl", + controller=acls.SecretACLsController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/acl", + controller=acls.SecretACLsController.on_put, + action="create", + conditions={"method": ["PUT"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/acl", + controller=acls.SecretACLsController.on_patch, + action="update", + conditions={"method": ["PATCH"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/acl", + controller=acls.SecretACLsController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + + # Secret metadata + mapper.connect( + None, + "/v1/secrets/{secret_id}/metadata", + controller=secretmeta.SecretMetadataController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/metadata", + controller=secretmeta.SecretMetadataController.on_put, + action="create", + conditions={"method": ["PUT"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/metadata", + controller=secretmeta.SecretMetadataController.on_post, + action="replace", + conditions={"method": ["POST"]}, + ) + + mapper.connect( + None, + "/v1/secrets/{secret_id}/metadata/{key}", + controller=secretmeta.SecretMetadatumController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/metadata/{key}", + controller=secretmeta.SecretMetadatumController.on_put, + action="create", + conditions={"method": ["PUT"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/metadata/{key}", + controller=secretmeta.SecretMetadatumController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + + mapper.connect( + None, + "/v1/secrets/{secret_id}/consumers", + controller=consumers.SecretConsumersController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/consumers", + controller=consumers.SecretConsumersController.on_post, + action="create", + conditions={"method": ["POST"]}, + ) + mapper.connect( + None, + "/v1/secrets/{secret_id}/consumers", + controller=consumers.SecretConsumersController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + # Secret stores + mapper.connect( + None, + "/v1/secret-stores/{secret_store_id}", + controller=secretstores.SecretStoreController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/secret-stores/{secret_store_id}/preferred", + controller=secretstores.PreferredSecretStoreController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + mapper.connect( + None, + "/v1/secret-stores/{secret_store_id}/preferred", + controller=secretstores.PreferredSecretStoreController.on_post, + action="get", + conditions={"method": ["GET"]}, + ) + + # Containers + mapper.connect( + None, + "/v1/containers/{container_id}", + controller=containers.ContainerController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/containers/{container_id}", + controller=containers.ContainerController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + + mapper.connect( + None, + "/v1/containers/{container_id}/secrets", + controller=containers.ContainersSecretsController.on_post, + action="create", + conditions={"method": ["POST"]}, + ) + mapper.connect( + None, + "/v1/containers/{container_id}/secrets", + controller=containers.ContainersSecretsController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + # Contanier consumers + mapper.connect( + None, + "/v1/containers/{container_id}/consumers", + controller=consumers.ContainerConsumersController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/containers/{container_id}/consumers", + controller=consumers.ContainerConsumersController.on_post, + action="post", + conditions={"method": ["POST"]}, + ) + mapper.connect( + None, + "/v1/containers/{container_id}/consumers", + controller=consumers.ContainerConsumersController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + + # Orders + mapper.connect( + None, + "/v1/orders/{order_id}", + controller=orders.OrderController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/orders/{order_id}", + controller=orders.OrderController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + + # Transport keys + mapper.connect( + None, + "/v1/transport_keys/{transport_key_id}", + controller=transportkeys.TransportKeyController.on_get, + action="get", + conditions={"method": ["GET"]}, + ) + mapper.connect( + None, + "/v1/transport_keys/{transport_key_id}", + controller=transportkeys.TransportKeyController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + # Quotas + mapper.connect( + None, + "/v1/project-quotas/{project_id}", + controller=quotas.ProjectQuotasController.on_put, + action="update", + conditions={"method": ["PUT"]}, + ) + mapper.connect( + None, + "/v1/project-quotas/{project_id}", + controller=quotas.ProjectQuotasController.on_delete, + action="delete", + conditions={"method": ["DELETE"]}, + ) + + for route in mapper.matchlist: + self._process_route(route, openapi_spec, framework="pecan") + + if args.api_ref_src: + merge_api_ref_doc( + openapi_spec, args.api_ref_src, allow_strip_version=False + ) + + self.dump_openapi( + openapi_spec, Path(impl_path), args.validate, "key-manager" + ) + + lnk = Path(impl_path.parent, "v1.yaml") + lnk.unlink(missing_ok=True) + lnk.symlink_to(impl_path.name) + + return impl_path diff --git a/codegenerator/openapi/base.py b/codegenerator/openapi/base.py index ba691b9..6654a6a 100644 --- a/codegenerator/openapi/base.py +++ b/codegenerator/openapi/base.py @@ -317,6 +317,7 @@ class OpenStackServerSourceBase: if path_elements and VERSION_RE.match(path_elements[0]): path_elements.pop(0) operation_tags = self._get_tags_for_url(path) + print(f"tags={operation_tags} for {path}") # Build path parameters (/foo/{foo_id}/bar/{id} => $foo_id, $foo_bar_id) # Since for same path we are here multiple times check presence of diff --git a/codegenerator/openapi_spec.py b/codegenerator/openapi_spec.py index 69e4789..5dc1b94 100644 --- a/codegenerator/openapi_spec.py +++ b/codegenerator/openapi_spec.py @@ -78,6 +78,11 @@ class OpenApiSchemaGenerator(BaseGenerator): IronicGenerator().generate(target_dir, args) + def generate_barbican(self, target_dir, args): + from codegenerator.openapi.barbican import BarbicanGenerator + + BarbicanGenerator().generate(target_dir, args) + def generate( self, res, target_dir, openapi_spec=None, operation_id=None, args=None ): @@ -98,6 +103,8 @@ class OpenApiSchemaGenerator(BaseGenerator): self.generate_glance(target_dir, args) elif args.service_type == "identity": self.generate_keystone(target_dir, args) + elif args.service_type == "key-manager": + self.generate_barbican(target_dir, args) elif args.service_type == "load-balancer": self.generate_octavia(target_dir, args) elif args.service_type == "network": diff --git a/metadata/key-manager_metadata.yaml b/metadata/key-manager_metadata.yaml new file mode 100644 index 0000000..14fcc66 --- /dev/null +++ b/metadata/key-manager_metadata.yaml @@ -0,0 +1,555 @@ +resources: + key-manager.version: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: :get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: version get + key-manager.secret: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: secrets:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: secret list + create: + operation_id: secrets:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: secret create + show: + operation_id: secrets/secret_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: secret show + update: + operation_id: secrets/secret_id:put + operation_type: set + targets: + rust-sdk: + module_name: set + rust-cli: + module_name: set + sdk_mod_name: set + cli_full_command: secret set + delete: + operation_id: secrets/secret_id:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: secret delete + key-manager.order: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: orders:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: order list + create: + operation_id: orders:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: order create + show: + operation_id: orders/order_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: order show + update: + operation_id: orders/order_id:put + operation_type: set + targets: + rust-sdk: + module_name: set + rust-cli: + module_name: set + sdk_mod_name: set + cli_full_command: order set + delete: + operation_id: orders/order_id:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: order delete + key-manager.container: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: containers:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: container list + create: + operation_id: containers:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: container create + show: + operation_id: containers/container_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: container show + delete: + operation_id: containers/container_id:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: container delete + key-manager.transport_key: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: transport_keys:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: transport-key list + create: + operation_id: transport_keys:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: transport-key create + show: + operation_id: transport_keys/transport_key_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: transport-key show + delete: + operation_id: transport_keys/transport_key_id:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: transport-key delete + key-manager.quota: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: quotas:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: quota list + show: + operation_id: quotas/quota_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: quota show + key-manager.project_quota: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: project-quotas:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: project-quota list + show: + operation_id: project-quotas/project-quota_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: project-quota show + update: + operation_id: project-quotas/project_id:put + operation_type: set + targets: + rust-sdk: + module_name: set + rust-cli: + module_name: set + sdk_mod_name: set + cli_full_command: project-quota set + delete: + operation_id: project-quotas/project_id:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: project-quota delete + key-manager.secret_store/global_default: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: secret-stores/global-default:get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: secret-store global-default get + key-manager.secret_store/preferred: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: secret-stores/secret_store_id/preferred:get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: secret-store preferred get + delete: + operation_id: secret-stores/secret_store_id/preferred:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: secret-store preferred delete + key-manager.secret_store: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: secret-stores:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: secret-store list + show: + operation_id: secret-stores/secret_store_id:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: secret-store show + key-manager.secret/payload: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: secrets/secret_id/payload:get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: secret payload get + key-manager.secret/acl: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: secrets/secret_id/acl:get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: secret acl get + acl: + operation_id: secrets/secret_id/acl:put + operation_type: action + targets: + rust-sdk: + module_name: acl + rust-cli: + module_name: acl + sdk_mod_name: acl + cli_full_command: secret acl acl + delete: + operation_id: secrets/secret_id/acl:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: secret acl delete + update: + operation_id: secrets/secret_id/acl:patch + operation_type: set + targets: + rust-sdk: + module_name: set + rust-cli: + module_name: set + sdk_mod_name: set + cli_full_command: secret acl set + key-manager.secret/metadata: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + list: + operation_id: secrets/secret_id/metadata:get + operation_type: list + targets: + rust-sdk: + module_name: list + rust-cli: + module_name: list + sdk_mod_name: list + cli_full_command: secret metadata list + replace: + operation_id: secrets/secret_id/metadata:put + operation_type: set + targets: + rust-sdk: + module_name: replace + rust-cli: + module_name: replace + sdk_mod_name: replace + cli_full_command: secret metadata replace + create: + operation_id: secrets/secret_id/metadata:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: secret metadata create + show: + operation_id: secrets/secret_id/metadata/key:get + operation_type: show + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: show + sdk_mod_name: get + cli_full_command: secret metadata show + update: + operation_id: secrets/secret_id/metadata/key:put + operation_type: set + targets: + rust-sdk: + module_name: set + rust-cli: + module_name: set + sdk_mod_name: set + cli_full_command: secret metadata set + delete: + operation_id: secrets/secret_id/metadata/key:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: secret metadata delete + key-manager.secret/consumer: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: secrets/secret_id/consumers:get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: secret consumer get + create: + operation_id: secrets/secret_id/consumers:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: secret consumer create + delete: + operation_id: secrets/secret_id/consumers:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: secret consumer delete + key-manager.container/secret: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + create: + operation_id: containers/container_id/secrets:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: container secret create + delete: + operation_id: containers/container_id/secrets:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: container secret delete + key-manager.container/consumer: + spec_file: wrk/openapi_specs/key-manager/v1.yaml + api_version: v1 + operations: + get: + operation_id: containers/container_id/consumers:get + operation_type: get + targets: + rust-sdk: + module_name: get + rust-cli: + module_name: get + sdk_mod_name: get + cli_full_command: container consumer get + create: + operation_id: containers/container_id/consumers:post + operation_type: create + targets: + rust-sdk: + module_name: create + rust-cli: + module_name: create + sdk_mod_name: create + cli_full_command: container consumer create + delete: + operation_id: containers/container_id/consumers:delete + operation_type: delete + targets: + rust-sdk: + module_name: delete + rust-cli: + module_name: delete + sdk_mod_name: delete + cli_full_command: container consumer delete diff --git a/tools/generate_openapi_specs.sh b/tools/generate_openapi_specs.sh index fab224e..158feca 100755 --- a/tools/generate_openapi_specs.sh +++ b/tools/generate_openapi_specs.sh @@ -23,6 +23,9 @@ if [ -z "$1" -o "$1" = "identity" ]; then openstack-codegenerator --work-dir wrk --target openapi-spec --service-type identity --api-ref-src ${API_REF_BUILD_ROOT}/keystone/api-ref/build/html/v3/index.html --api-ref-src ${API_REF_BUILD_ROOT}/keystone/api-ref/build/html/v3-ext/index.html --validate fi +if [ -z "$1" -o "$1" = "key-manager" ]; then + openstack-codegenerator --work-dir wrk --target openapi-spec --service-type key-manager --validate +fi if [ -z "$1" -o "$1" = "load-balancer" ]; then openstack-codegenerator --work-dir wrk --target openapi-spec --service-type load-balancer --api-ref-src ${API_REF_BUILD_ROOT}/octavia/api-ref/build/html/v2/index.html --validate fi diff --git a/zuul.d/openapi.yaml b/zuul.d/openapi.yaml index 7bbd580..d2ccba3 100644 --- a/zuul.d/openapi.yaml +++ b/zuul.d/openapi.yaml @@ -208,6 +208,20 @@ project: "opendev.org/openstack/glance" path: "/api-ref/build/html/v2/index.html" +- job: + name: codegenerator-openapi-key-manager-tips + parent: codegenerator-openapi-tips-base + description: | + Generate OpenAPI spec for Barbican + required-projects: + - name: openstack/barbican + + vars: + openapi_service: key-manager + install_additional_projects: + - project: "opendev.org/openstack/barbican" + name: "." + - job: name: codegenerator-openapi-load-balancing-tips parent: codegenerator-openapi-tips-base @@ -356,6 +370,8 @@ soft: true - name: codegenerator-openapi-image-tips-with-api-ref soft: true + - name: codegenerator-openapi-key-manager-tips + soft: true - name: codegenerator-openapi-load-balancing-tips-with-api-ref soft: true - name: codegenerator-openapi-network-tips-with-api-ref diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 69b9574..395f1cc 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -12,6 +12,7 @@ - codegenerator-openapi-dns-tips-with-api-ref - codegenerator-openapi-identity-tips-with-api-ref - codegenerator-openapi-image-tips-with-api-ref + - codegenerator-openapi-key-manager-tips - codegenerator-openapi-load-balancing-tips-with-api-ref - codegenerator-openapi-network-tips-with-api-ref - codegenerator-openapi-object-store-static @@ -29,6 +30,7 @@ - codegenerator-openapi-dns-tips-with-api-ref - codegenerator-openapi-identity-tips-with-api-ref - codegenerator-openapi-image-tips-with-api-ref + - codegenerator-openapi-key-manager-tips - codegenerator-openapi-load-balancing-tips-with-api-ref - codegenerator-openapi-network-tips-with-api-ref - codegenerator-openapi-object-store-static