From 2249e1e3bcedcf7e30d25d658317fbf1ad32f2ba Mon Sep 17 00:00:00 2001 From: SDK Generator Bot Date: Fri, 8 Nov 2024 11:20:52 +0000 Subject: [PATCH] Generate membership --- services/membership/pyproject.toml | 105 ++ .../src/stackit/membership/__init__.py | 82 + .../src/stackit/membership/api/__init__.py | 4 + .../src/stackit/membership/api/default_api.py | 1602 +++++++++++++++++ .../src/stackit/membership/api_client.py | 627 +++++++ .../src/stackit/membership/api_response.py | 23 + .../src/stackit/membership/configuration.py | 111 ++ .../src/stackit/membership/exceptions.py | 199 ++ .../src/stackit/membership/models/__init__.py | 63 + .../membership/models/add_members_payload.py | 107 ++ .../membership/models/add_roles_payload.py | 109 ++ .../models/add_roles_payload_item.py | 111 ++ .../stackit/membership/models/consistency.py | 104 ++ .../models/create_resource_payload.py | 137 ++ .../models/create_resource_response.py | 160 ++ .../models/delete_resource_response.py | 89 + .../models/delete_subject_response.py | 93 + .../models/enforce_permission_payload.py | 109 ++ .../membership/models/error_response.py | 95 + .../membership/models/existing_permission.py | 91 + .../models/list_members_response.py | 116 ++ .../models/list_permissions_response.py | 99 + .../models/list_subject_ids_response.py | 84 + .../models/list_subjects_response.py | 93 + .../models/list_user_memberships_response.py | 99 + .../models/list_user_permissions_response.py | 99 + .../src/stackit/membership/models/member.py | 91 + .../membership/models/members_response.py | 122 ++ .../stackit/membership/models/permission.py | 91 + .../membership/models/permission_request.py | 90 + .../models/remove_members_payload.py | 109 ++ .../membership/models/remove_role_request.py | 90 + .../membership/models/remove_roles_payload.py | 109 ++ .../src/stackit/membership/models/resource.py | 107 ++ .../src/stackit/membership/models/role.py | 111 ++ .../membership/models/roles_response.py | 114 ++ .../src/stackit/membership/models/subject.py | 91 + .../transfer_subject_memberships_payload.py | 82 + .../membership/models/user_membership.py | 114 ++ .../membership/models/user_permission.py | 118 ++ .../models/user_resources_response.py | 101 ++ .../models/validate_child_members_payload.py | 116 ++ .../membership/models/write_schema_payload.py | 82 + .../models/write_schema_response.py | 89 + .../src/stackit/membership/models/zookie.py | 82 + .../src/stackit/membership/py.typed | 0 .../membership/src/stackit/membership/rest.py | 149 ++ 47 files changed, 6669 insertions(+) create mode 100644 services/membership/pyproject.toml create mode 100644 services/membership/src/stackit/membership/__init__.py create mode 100644 services/membership/src/stackit/membership/api/__init__.py create mode 100644 services/membership/src/stackit/membership/api/default_api.py create mode 100644 services/membership/src/stackit/membership/api_client.py create mode 100644 services/membership/src/stackit/membership/api_response.py create mode 100644 services/membership/src/stackit/membership/configuration.py create mode 100644 services/membership/src/stackit/membership/exceptions.py create mode 100644 services/membership/src/stackit/membership/models/__init__.py create mode 100644 services/membership/src/stackit/membership/models/add_members_payload.py create mode 100644 services/membership/src/stackit/membership/models/add_roles_payload.py create mode 100644 services/membership/src/stackit/membership/models/add_roles_payload_item.py create mode 100644 services/membership/src/stackit/membership/models/consistency.py create mode 100644 services/membership/src/stackit/membership/models/create_resource_payload.py create mode 100644 services/membership/src/stackit/membership/models/create_resource_response.py create mode 100644 services/membership/src/stackit/membership/models/delete_resource_response.py create mode 100644 services/membership/src/stackit/membership/models/delete_subject_response.py create mode 100644 services/membership/src/stackit/membership/models/enforce_permission_payload.py create mode 100644 services/membership/src/stackit/membership/models/error_response.py create mode 100644 services/membership/src/stackit/membership/models/existing_permission.py create mode 100644 services/membership/src/stackit/membership/models/list_members_response.py create mode 100644 services/membership/src/stackit/membership/models/list_permissions_response.py create mode 100644 services/membership/src/stackit/membership/models/list_subject_ids_response.py create mode 100644 services/membership/src/stackit/membership/models/list_subjects_response.py create mode 100644 services/membership/src/stackit/membership/models/list_user_memberships_response.py create mode 100644 services/membership/src/stackit/membership/models/list_user_permissions_response.py create mode 100644 services/membership/src/stackit/membership/models/member.py create mode 100644 services/membership/src/stackit/membership/models/members_response.py create mode 100644 services/membership/src/stackit/membership/models/permission.py create mode 100644 services/membership/src/stackit/membership/models/permission_request.py create mode 100644 services/membership/src/stackit/membership/models/remove_members_payload.py create mode 100644 services/membership/src/stackit/membership/models/remove_role_request.py create mode 100644 services/membership/src/stackit/membership/models/remove_roles_payload.py create mode 100644 services/membership/src/stackit/membership/models/resource.py create mode 100644 services/membership/src/stackit/membership/models/role.py create mode 100644 services/membership/src/stackit/membership/models/roles_response.py create mode 100644 services/membership/src/stackit/membership/models/subject.py create mode 100644 services/membership/src/stackit/membership/models/transfer_subject_memberships_payload.py create mode 100644 services/membership/src/stackit/membership/models/user_membership.py create mode 100644 services/membership/src/stackit/membership/models/user_permission.py create mode 100644 services/membership/src/stackit/membership/models/user_resources_response.py create mode 100644 services/membership/src/stackit/membership/models/validate_child_members_payload.py create mode 100644 services/membership/src/stackit/membership/models/write_schema_payload.py create mode 100644 services/membership/src/stackit/membership/models/write_schema_response.py create mode 100644 services/membership/src/stackit/membership/models/zookie.py create mode 100644 services/membership/src/stackit/membership/py.typed create mode 100644 services/membership/src/stackit/membership/rest.py diff --git a/services/membership/pyproject.toml b/services/membership/pyproject.toml new file mode 100644 index 00000000..cfa0fddb --- /dev/null +++ b/services/membership/pyproject.toml @@ -0,0 +1,105 @@ +[tool.poetry] +name = "stackit-membership" +version = "1.0.0" +authors = [ + "SIT-STACKIT-Core-Platform-Security ", +] +description = "STACKIT Membership API" +#readme = "README.md" +#license = "NoLicense" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", +] +packages = [ + { include = "stackit", from="src" } +] + +[tool.poetry.dependencies] +python = ">=3.8,<4.0" +stackit-core = "^0.0.1" +requests = "^2.32.3" +pydantic = "^2.9.2" +python-dateutil = "^2.9.0.post0" + +[tool.poetry.group.dev.dependencies] +black = ">=24.8.0" +pytest = ">=8.3.3" +flake8 = [ + { version= ">=5.0.3", python="<3.12"}, + { version= ">=6.0.1", python=">=3.12"} +] +flake8-black = ">=0.3.6" +flake8-pyproject = ">=1.2.3" +autoimport = ">=1.6.1" +flake8-eol = ">=0.0.8" +flake8-eradicate = ">=1.5.0" +flake8-bandit = ">=4.1.1" +flake8-bugbear = ">=23.1.14" +flake8-quotes = ">=3.4.0" +isort = ">=5.13.2" + +[project.urls] +Homepage = "https://github.com/stackitcloud/stackit-sdk-python" +Issues = "https://github.com/stackitcloud/stackit-sdk-python/issues" + +[build-system] +requires = ["setuptools", "poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.pytest.ini_options] +pythonpath = [ + "src" +] +testpaths = [ + "tests" +] + +[tool.black] +line-length = 120 +exclude = """ +/( + .eggs + | .git + | .hg + | .mypy_cache + | .nox + | .pants.d + | .tox + | .venv + | _build + | buck-out + | build + | dist + | node_modules + | venv +)/ +""" + +[tool.isort] +profile = 'black' + +[tool.flake8] +exclude= [".eggs", ".git", ".hg", ".mypy_cache", ".tox", ".venv", ".devcontainer", "venv", "_build", "buck-out", "build", "dist"] +statistics = true +show-source = false +max-line-length = 120 +# E203,W503 and E704 are incompatible with the formatter black +# W291 needs to be disabled because some doc-strings get generated with trailing whitespace but black won't re-format comments +ignore = ["E203", "W503", "E704", "W291"] +inline-quotes = '"' +docstring-quotes = '"""' +multiline-quotes = '"""' +ban-relative-imports = true +per-file-ignores = """ + # asserts are fine in tests, tests shouldn't be build optimized + ./tests/*: S101, + # F841: some variables get generated but may not be used, depending on the api-spec + # E501: long descriptions/string values might lead to lines that are too long + ./src/stackit/*/models/*: F841,E501 + # F841: some variables get generated but may not be used, depending on the api-spec + # E501: long descriptions/string values might lead to lines that are too long + # B028: stacklevel for deprecation warning is irrelevant + ./src/stackit/*/api/default_api.py: F841,B028,E501 +""" \ No newline at end of file diff --git a/services/membership/src/stackit/membership/__init__.py b/services/membership/src/stackit/membership/__init__.py new file mode 100644 index 00000000..8eb7c4eb --- /dev/null +++ b/services/membership/src/stackit/membership/__init__.py @@ -0,0 +1,82 @@ +# coding: utf-8 + +# flake8: noqa + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + + +__version__ = "1.0.0" + +# import apis into sdk package +from stackit.membership.api.default_api import DefaultApi +from stackit.membership.api_client import ApiClient + +# import ApiClient +from stackit.membership.api_response import ApiResponse +from stackit.membership.configuration import HostConfiguration +from stackit.membership.exceptions import ( + ApiAttributeError, + ApiException, + ApiKeyError, + ApiTypeError, + ApiValueError, + OpenApiException, +) + +# import models into sdk package +from stackit.membership.models.add_members_payload import AddMembersPayload +from stackit.membership.models.add_roles_payload import AddRolesPayload +from stackit.membership.models.add_roles_payload_item import AddRolesPayloadItem +from stackit.membership.models.consistency import Consistency +from stackit.membership.models.create_resource_payload import CreateResourcePayload +from stackit.membership.models.create_resource_response import CreateResourceResponse +from stackit.membership.models.delete_resource_response import DeleteResourceResponse +from stackit.membership.models.delete_subject_response import DeleteSubjectResponse +from stackit.membership.models.enforce_permission_payload import ( + EnforcePermissionPayload, +) +from stackit.membership.models.error_response import ErrorResponse +from stackit.membership.models.existing_permission import ExistingPermission +from stackit.membership.models.list_members_response import ListMembersResponse +from stackit.membership.models.list_permissions_response import ListPermissionsResponse +from stackit.membership.models.list_subject_ids_response import ListSubjectIdsResponse +from stackit.membership.models.list_subjects_response import ListSubjectsResponse +from stackit.membership.models.list_user_memberships_response import ( + ListUserMembershipsResponse, +) +from stackit.membership.models.list_user_permissions_response import ( + ListUserPermissionsResponse, +) +from stackit.membership.models.member import Member +from stackit.membership.models.members_response import MembersResponse +from stackit.membership.models.permission import Permission +from stackit.membership.models.permission_request import PermissionRequest +from stackit.membership.models.remove_members_payload import RemoveMembersPayload +from stackit.membership.models.remove_role_request import RemoveRoleRequest +from stackit.membership.models.remove_roles_payload import RemoveRolesPayload +from stackit.membership.models.resource import Resource +from stackit.membership.models.role import Role +from stackit.membership.models.roles_response import RolesResponse +from stackit.membership.models.subject import Subject +from stackit.membership.models.transfer_subject_memberships_payload import ( + TransferSubjectMembershipsPayload, +) +from stackit.membership.models.user_membership import UserMembership +from stackit.membership.models.user_permission import UserPermission +from stackit.membership.models.user_resources_response import UserResourcesResponse +from stackit.membership.models.validate_child_members_payload import ( + ValidateChildMembersPayload, +) +from stackit.membership.models.write_schema_payload import WriteSchemaPayload +from stackit.membership.models.write_schema_response import WriteSchemaResponse +from stackit.membership.models.zookie import Zookie diff --git a/services/membership/src/stackit/membership/api/__init__.py b/services/membership/src/stackit/membership/api/__init__.py new file mode 100644 index 00000000..88dac9e8 --- /dev/null +++ b/services/membership/src/stackit/membership/api/__init__.py @@ -0,0 +1,4 @@ +# flake8: noqa + +# import apis into api package +from stackit.membership.api.default_api import DefaultApi diff --git a/services/membership/src/stackit/membership/api/default_api.py b/services/membership/src/stackit/membership/api/default_api.py new file mode 100644 index 00000000..81cca1bf --- /dev/null +++ b/services/membership/src/stackit/membership/api/default_api.py @@ -0,0 +1,1602 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from typing import Any, Dict, List, Optional, Tuple, Union + +from pydantic import Field, StrictFloat, StrictInt, StrictStr, validate_call +from stackit.core.configuration import Configuration +from typing_extensions import Annotated + +from stackit.membership.api_client import ApiClient, RequestSerialized +from stackit.membership.api_response import ApiResponse +from stackit.membership.models.add_members_payload import AddMembersPayload +from stackit.membership.models.list_members_response import ListMembersResponse +from stackit.membership.models.list_permissions_response import ListPermissionsResponse +from stackit.membership.models.list_user_memberships_response import ( + ListUserMembershipsResponse, +) +from stackit.membership.models.members_response import MembersResponse +from stackit.membership.models.remove_members_payload import RemoveMembersPayload +from stackit.membership.models.roles_response import RolesResponse +from stackit.membership.rest import RESTResponseType + + +class DefaultApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, configuration: Configuration = None) -> None: + if configuration is None: + configuration = Configuration() + self.configuration = configuration + self.api_client = ApiClient(self.configuration) + + @validate_call + def add_members( + self, + resource_id: StrictStr, + add_members_payload: AddMembersPayload, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> MembersResponse: + """Add members to a resource + + Add members to the given resource with specified roles. + + :param resource_id: (required) + :type resource_id: str + :param add_members_payload: (required) + :type add_members_payload: AddMembersPayload + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._add_members_serialize( + resource_id=resource_id, + add_members_payload=add_members_payload, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "MembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def add_members_with_http_info( + self, + resource_id: StrictStr, + add_members_payload: AddMembersPayload, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[MembersResponse]: + """Add members to a resource + + Add members to the given resource with specified roles. + + :param resource_id: (required) + :type resource_id: str + :param add_members_payload: (required) + :type add_members_payload: AddMembersPayload + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._add_members_serialize( + resource_id=resource_id, + add_members_payload=add_members_payload, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "MembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def add_members_without_preload_content( + self, + resource_id: StrictStr, + add_members_payload: AddMembersPayload, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Add members to a resource + + Add members to the given resource with specified roles. + + :param resource_id: (required) + :type resource_id: str + :param add_members_payload: (required) + :type add_members_payload: AddMembersPayload + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._add_members_serialize( + resource_id=resource_id, + add_members_payload=add_members_payload, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "MembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _add_members_serialize( + self, + resource_id, + add_members_payload, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if resource_id is not None: + _path_params["resourceId"] = resource_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if add_members_payload is not None: + _body_params = add_members_payload + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json"]) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params["Content-Type"] = _content_type + else: + _default_content_type = self.api_client.select_header_content_type(["application/json"]) + if _default_content_type is not None: + _header_params["Content-Type"] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="PATCH", + resource_path="/v2/{resourceId}/members", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + + @validate_call + def list_members( + self, + resource_type: StrictStr, + resource_id: StrictStr, + subject: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ListMembersResponse: + """Get members to a resource + + List members of the given resource. + + :param resource_type: (required) + :type resource_type: str + :param resource_id: (required) + :type resource_id: str + :param subject: + :type subject: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_members_serialize( + resource_type=resource_type, + resource_id=resource_id, + subject=subject, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListMembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def list_members_with_http_info( + self, + resource_type: StrictStr, + resource_id: StrictStr, + subject: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ListMembersResponse]: + """Get members to a resource + + List members of the given resource. + + :param resource_type: (required) + :type resource_type: str + :param resource_id: (required) + :type resource_id: str + :param subject: + :type subject: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_members_serialize( + resource_type=resource_type, + resource_id=resource_id, + subject=subject, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListMembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def list_members_without_preload_content( + self, + resource_type: StrictStr, + resource_id: StrictStr, + subject: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get members to a resource + + List members of the given resource. + + :param resource_type: (required) + :type resource_type: str + :param resource_id: (required) + :type resource_id: str + :param subject: + :type subject: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_members_serialize( + resource_type=resource_type, + resource_id=resource_id, + subject=subject, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListMembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _list_members_serialize( + self, + resource_type, + resource_id, + subject, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if resource_type is not None: + _path_params["resourceType"] = resource_type + if resource_id is not None: + _path_params["resourceId"] = resource_id + # process the query parameters + if subject is not None: + + _query_params.append(("subject", subject)) + + # process the header parameters + # process the form parameters + # process the body parameter + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json"]) + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="GET", + resource_path="/v2/{resourceType}/{resourceId}/members", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + + @validate_call + def list_permissions( + self, + resource_type: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ListPermissionsResponse: + """Get available permissions + + Get available permissions + + :param resource_type: + :type resource_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_permissions_serialize( + resource_type=resource_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListPermissionsResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def list_permissions_with_http_info( + self, + resource_type: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ListPermissionsResponse]: + """Get available permissions + + Get available permissions + + :param resource_type: + :type resource_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_permissions_serialize( + resource_type=resource_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListPermissionsResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def list_permissions_without_preload_content( + self, + resource_type: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get available permissions + + Get available permissions + + :param resource_type: + :type resource_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_permissions_serialize( + resource_type=resource_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListPermissionsResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _list_permissions_serialize( + self, + resource_type, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if resource_type is not None: + + _query_params.append(("resourceType", resource_type)) + + # process the header parameters + # process the form parameters + # process the body parameter + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json"]) + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="GET", + resource_path="/v2/permissions", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + + @validate_call + def list_roles( + self, + resource_type: StrictStr, + resource_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RolesResponse: + """Get roles and permissions of a resource + + Get roles and permissions of a resource + + :param resource_type: (required) + :type resource_type: str + :param resource_id: (required) + :type resource_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_roles_serialize( + resource_type=resource_type, + resource_id=resource_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "RolesResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def list_roles_with_http_info( + self, + resource_type: StrictStr, + resource_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[RolesResponse]: + """Get roles and permissions of a resource + + Get roles and permissions of a resource + + :param resource_type: (required) + :type resource_type: str + :param resource_id: (required) + :type resource_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_roles_serialize( + resource_type=resource_type, + resource_id=resource_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "RolesResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def list_roles_without_preload_content( + self, + resource_type: StrictStr, + resource_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get roles and permissions of a resource + + Get roles and permissions of a resource + + :param resource_type: (required) + :type resource_type: str + :param resource_id: (required) + :type resource_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_roles_serialize( + resource_type=resource_type, + resource_id=resource_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "RolesResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _list_roles_serialize( + self, + resource_type, + resource_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if resource_type is not None: + _path_params["resourceType"] = resource_type + if resource_id is not None: + _path_params["resourceId"] = resource_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json"]) + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="GET", + resource_path="/v2/{resourceType}/{resourceId}/roles", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + + @validate_call + def list_user_memberships( + self, + email: StrictStr, + resource_type: Optional[StrictStr] = None, + resource_id: Optional[StrictStr] = None, + parent_resource_id: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ListUserMembershipsResponse: + """List memberships of a user + + List memberships of a user. An administrative access is needed to list any user's memberships, while the user can do it on his/her own email. You can use filters to scope the request to a project/folder/organization. In this case -if caller is not the subject-, owner permissions are required. Because of hierarchical role bindings, the user might have permissions on more resources. + + :param email: (required) + :type email: str + :param resource_type: + :type resource_type: str + :param resource_id: + :type resource_id: str + :param parent_resource_id: + :type parent_resource_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_user_memberships_serialize( + email=email, + resource_type=resource_type, + resource_id=resource_id, + parent_resource_id=parent_resource_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListUserMembershipsResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def list_user_memberships_with_http_info( + self, + email: StrictStr, + resource_type: Optional[StrictStr] = None, + resource_id: Optional[StrictStr] = None, + parent_resource_id: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ListUserMembershipsResponse]: + """List memberships of a user + + List memberships of a user. An administrative access is needed to list any user's memberships, while the user can do it on his/her own email. You can use filters to scope the request to a project/folder/organization. In this case -if caller is not the subject-, owner permissions are required. Because of hierarchical role bindings, the user might have permissions on more resources. + + :param email: (required) + :type email: str + :param resource_type: + :type resource_type: str + :param resource_id: + :type resource_id: str + :param parent_resource_id: + :type parent_resource_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_user_memberships_serialize( + email=email, + resource_type=resource_type, + resource_id=resource_id, + parent_resource_id=parent_resource_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListUserMembershipsResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def list_user_memberships_without_preload_content( + self, + email: StrictStr, + resource_type: Optional[StrictStr] = None, + resource_id: Optional[StrictStr] = None, + parent_resource_id: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List memberships of a user + + List memberships of a user. An administrative access is needed to list any user's memberships, while the user can do it on his/her own email. You can use filters to scope the request to a project/folder/organization. In this case -if caller is not the subject-, owner permissions are required. Because of hierarchical role bindings, the user might have permissions on more resources. + + :param email: (required) + :type email: str + :param resource_type: + :type resource_type: str + :param resource_id: + :type resource_id: str + :param parent_resource_id: + :type parent_resource_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._list_user_memberships_serialize( + email=email, + resource_type=resource_type, + resource_id=resource_id, + parent_resource_id=parent_resource_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListUserMembershipsResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _list_user_memberships_serialize( + self, + email, + resource_type, + resource_id, + parent_resource_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if email is not None: + _path_params["email"] = email + # process the query parameters + if resource_type is not None: + + _query_params.append(("resourceType", resource_type)) + + if resource_id is not None: + + _query_params.append(("resourceId", resource_id)) + + if parent_resource_id is not None: + + _query_params.append(("parentResourceId", parent_resource_id)) + + # process the header parameters + # process the form parameters + # process the body parameter + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json"]) + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="GET", + resource_path="/v2/users/{email}/memberships", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + + @validate_call + def remove_members( + self, + resource_id: StrictStr, + remove_members_payload: RemoveMembersPayload, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> MembersResponse: + """Remove members from a resource + + Remove members from the given resource with specified roles. + + :param resource_id: (required) + :type resource_id: str + :param remove_members_payload: (required) + :type remove_members_payload: RemoveMembersPayload + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._remove_members_serialize( + resource_id=resource_id, + remove_members_payload=remove_members_payload, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "MembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def remove_members_with_http_info( + self, + resource_id: StrictStr, + remove_members_payload: RemoveMembersPayload, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[MembersResponse]: + """Remove members from a resource + + Remove members from the given resource with specified roles. + + :param resource_id: (required) + :type resource_id: str + :param remove_members_payload: (required) + :type remove_members_payload: RemoveMembersPayload + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._remove_members_serialize( + resource_id=resource_id, + remove_members_payload=remove_members_payload, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "MembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def remove_members_without_preload_content( + self, + resource_id: StrictStr, + remove_members_payload: RemoveMembersPayload, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Remove members from a resource + + Remove members from the given resource with specified roles. + + :param resource_id: (required) + :type resource_id: str + :param remove_members_payload: (required) + :type remove_members_payload: RemoveMembersPayload + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 docstring might be too long + + _param = self._remove_members_serialize( + resource_id=resource_id, + remove_members_payload=remove_members_payload, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "MembersResponse", + "400": "ErrorResponse", + "401": "ErrorResponse", + "403": "ErrorResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _remove_members_serialize( + self, + resource_id, + remove_members_payload, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if resource_id is not None: + _path_params["resourceId"] = resource_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if remove_members_payload is not None: + _body_params = remove_members_payload + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json"]) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params["Content-Type"] = _content_type + else: + _default_content_type = self.api_client.select_header_content_type(["application/json"]) + if _default_content_type is not None: + _header_params["Content-Type"] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="POST", + resource_path="/v2/{resourceId}/members/remove", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) diff --git a/services/membership/src/stackit/membership/api_client.py b/services/membership/src/stackit/membership/api_client.py new file mode 100644 index 00000000..7f372b54 --- /dev/null +++ b/services/membership/src/stackit/membership/api_client.py @@ -0,0 +1,627 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +import datetime +import json +import mimetypes +import os +import re +import tempfile +from enum import Enum +from typing import Dict, List, Optional, Tuple, Union +from urllib.parse import quote + +from dateutil.parser import parse +from pydantic import SecretStr +from stackit.core.configuration import Configuration + +import stackit.membership.models +from stackit.membership import rest +from stackit.membership.api_response import ApiResponse +from stackit.membership.api_response import T as ApiResponseT +from stackit.membership.configuration import HostConfiguration +from stackit.membership.exceptions import ( + ApiException, +) + + +RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]] + + +class ApiClient: + """Generic API client for OpenAPI client library builds. + + OpenAPI generic API client. This client handles the client- + server communication, and is invariant across implementations. Specifics of + the methods and models for each application are generated from the OpenAPI + templates. + + :param configuration: .Configuration object for this client + :param header_name: a header to pass when making calls to the API. + :param header_value: a header value to pass when making calls to + the API. + :param cookie: a cookie to include in the header when making calls + to the API + """ + + PRIMITIVE_TYPES = (float, bool, bytes, str, int) + NATIVE_TYPES_MAPPING = { + "int": int, + "long": int, # TODO remove as only py3 is supported? + "float": float, + "str": str, + "bool": bool, + "date": datetime.date, + "datetime": datetime.datetime, + "object": object, + } + + def __init__(self, configuration, header_name=None, header_value=None, cookie=None) -> None: + self.config: Configuration = configuration + + if self.config.custom_endpoint is None: + host_config = HostConfiguration(region=self.config.region, server_index=self.config.server_index) + self.host = host_config.host + else: + self.host = self.config.custom_endpoint + + self.rest_client = rest.RESTClientObject(self.config) + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value + self.cookie = cookie + # Set default User-Agent. + self.user_agent = "OpenAPI-Generator/1.0.0/python" + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + pass + + @property + def user_agent(self): + """User agent for this API client""" + return self.default_headers["User-Agent"] + + @user_agent.setter + def user_agent(self, value): + self.default_headers["User-Agent"] = value + + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value + + _default = None + + @classmethod + def get_default(cls): + """Return new instance of ApiClient. + + This method returns newly created, based on default constructor, + object of ApiClient class or returns a copy of default + ApiClient. + + :return: The ApiClient object. + """ + if cls._default is None: + cls._default = ApiClient() + return cls._default + + @classmethod + def set_default(cls, default): + """Set default instance of ApiClient. + + It stores default ApiClient. + + :param default: object of ApiClient. + """ + cls._default = default + + def param_serialize( + self, + method, + resource_path, + path_params=None, + query_params=None, + header_params=None, + body=None, + post_params=None, + files=None, + auth_settings=None, + collection_formats=None, + _host=None, + _request_auth=None, + ) -> RequestSerialized: + """Builds the HTTP request params needed by the request. + :param method: Method to call. + :param resource_path: Path to method endpoint. + :param path_params: Path parameters in the url. + :param query_params: Query parameters in the url. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param auth_settings list: Auth Settings names for the request. + :param files dict: key -> filename, value -> filepath, + for `multipart/form-data`. + :param collection_formats: dict of collection formats for path, query, + header, and post parameters. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :return: tuple of form (path, http_method, query_params, header_params, + body, post_params, files) + """ + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params["Cookie"] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict(self.parameters_to_tuples(header_params, collection_formats)) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples(path_params, collection_formats) + for k, v in path_params: + # specified safe chars, encode everything + resource_path = resource_path.replace("{%s}" % k, quote(str(v))) + + # post parameters + if post_params or files: + post_params = post_params if post_params else [] + post_params = self.sanitize_for_serialization(post_params) + post_params = self.parameters_to_tuples(post_params, collection_formats) + if files: + post_params.extend(self.files_parameters(files)) + + # body + if body: + body = self.sanitize_for_serialization(body) + + # request url + if _host is None: + url = self.host + resource_path + else: + # use server/host defined in path or operation instead + url = _host + resource_path + + # query parameters + if query_params: + query_params = self.sanitize_for_serialization(query_params) + url_query = self.parameters_to_url_query(query_params, collection_formats) + url += "?" + url_query + + return method, url, header_params, body, post_params + + def call_api( + self, method, url, header_params=None, body=None, post_params=None, _request_timeout=None + ) -> rest.RESTResponse: + """Makes the HTTP request (synchronous) + :param method: Method to call. + :param url: Path to method endpoint. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param _request_timeout: timeout setting for this request. + :return: RESTResponse + """ + + try: + # perform request and return response + response_data = self.rest_client.request( + method, + url, + headers=header_params, + body=body, + post_params=post_params, + _request_timeout=_request_timeout, + ) + + except ApiException as e: + raise e + + return response_data + + def response_deserialize( + self, response_data: rest.RESTResponse, response_types_map: Optional[Dict[str, ApiResponseT]] = None + ) -> ApiResponse[ApiResponseT]: + """Deserializes response into an object. + :param response_data: RESTResponse object to be deserialized. + :param response_types_map: dict of response types. + :return: ApiResponse + """ + + msg = "RESTResponse.read() must be called before passing it to response_deserialize()" + if response_data.data is None: + raise ValueError(msg) + + response_type = response_types_map.get(str(response_data.status), None) + if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: + # if not found, look for '1XX', '2XX', etc. + response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) + + # deserialize response data + response_text = None + return_data = None + try: + if response_type == "bytearray": + return_data = response_data.data + elif response_type == "file": + return_data = self.__deserialize_file(response_data) + elif response_type is not None: + match = None + content_type = response_data.getheader("content-type") + if content_type is not None: + match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) + encoding = match.group(1) if match else "utf-8" + response_text = response_data.data.decode(encoding) + return_data = self.deserialize(response_text, response_type, content_type) + finally: + if not 200 <= response_data.status <= 299: + raise ApiException.from_response( + http_resp=response_data, + body=response_text, + data=return_data, + ) + + return ApiResponse( + status_code=response_data.status, + data=return_data, + headers=response_data.getheaders(), + raw_data=response_data.data, + ) + + def sanitize_for_serialization(self, obj): + """Builds a JSON POST object. + + If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() + If obj is str, int, long, float, bool, return directly. + If obj is datetime.datetime, datetime.date + convert to string in iso8601 format. + If obj is list, sanitize each element in the list. + If obj is dict, return the dict. + If obj is OpenAPI model, return the properties dict. + + :param obj: The data to serialize. + :return: The serialized form of data. + """ + if obj is None: + return None + elif isinstance(obj, Enum): + return obj.value + elif isinstance(obj, SecretStr): + return obj.get_secret_value() + elif isinstance(obj, self.PRIMITIVE_TYPES): + return obj + elif isinstance(obj, list): + return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj] + elif isinstance(obj, tuple): + return tuple(self.sanitize_for_serialization(sub_obj) for sub_obj in obj) + elif isinstance(obj, (datetime.datetime, datetime.date)): + return obj.isoformat() + + elif isinstance(obj, dict): + obj_dict = obj + else: + # Convert model obj to dict except + # attributes `openapi_types`, `attribute_map` + # and attributes which value is not None. + # Convert attribute name to json key in + # model definition for request. + if hasattr(obj, "to_dict") and callable(obj.to_dict): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ + + return {key: self.sanitize_for_serialization(val) for key, val in obj_dict.items()} + + def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]): + """Deserializes response into an object. + + :param response: RESTResponse object to be deserialized. + :param response_type: class literal for + deserialized object, or string of class name. + :param content_type: content type of response. + + :return: deserialized object. + """ + + # fetch data from response object + if content_type is None: + try: + data = json.loads(response_text) + except ValueError: + data = response_text + elif content_type.startswith("application/json"): + if response_text == "": + data = "" + else: + data = json.loads(response_text) + elif content_type.startswith("text/plain"): + data = response_text + else: + raise ApiException(status=0, reason="Unsupported content type: {0}".format(content_type)) + + return self.__deserialize(data, response_type) + + def __deserialize(self, data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if isinstance(klass, str): + if klass.startswith("List["): + m = re.match(r"List\[(.*)]", klass) + if m is None: + raise ValueError("Malformed List type definition") + sub_kls = m.group(1) + return [self.__deserialize(sub_data, sub_kls) for sub_data in data] + + if klass.startswith("Dict["): + m = re.match(r"Dict\[([^,]*), (.*)]", klass) + if m is None: + raise ValueError("Malformed Dict type definition") + sub_kls = m.group(2) + return {k: self.__deserialize(v, sub_kls) for k, v in data.items()} + + # convert str to class + if klass in self.NATIVE_TYPES_MAPPING: + klass = self.NATIVE_TYPES_MAPPING[klass] + else: + klass = getattr(stackit.membership.models, klass) + + if klass in self.PRIMITIVE_TYPES: + return self.__deserialize_primitive(data, klass) + elif klass == object: + return self.__deserialize_object(data) + elif klass == datetime.date: + return self.__deserialize_date(data) + elif klass == datetime.datetime: + return self.__deserialize_datetime(data) + elif issubclass(klass, Enum): + return self.__deserialize_enum(data, klass) + else: + return self.__deserialize_model(data, klass) + + def parameters_to_tuples(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: Parameters as list of tuples, collections formatted + """ + new_params: List[Tuple[str, str]] = [] + if collection_formats is None: + collection_formats = {} + for k, v in params.items() if isinstance(params, dict) else params: + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == "multi": + new_params.extend((k, value) for value in v) + else: + if collection_format == "ssv": + delimiter = " " + elif collection_format == "tsv": + delimiter = "\t" + elif collection_format == "pipes": + delimiter = "|" + else: # csv is the default + delimiter = "," + new_params.append((k, delimiter.join(str(value) for value in v))) + else: + new_params.append((k, v)) + return new_params + + def parameters_to_url_query(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: URL query string (e.g. a=Hello%20World&b=123) + """ + new_params: List[Tuple[str, str]] = [] + if collection_formats is None: + collection_formats = {} + for k, v in params.items() if isinstance(params, dict) else params: + if isinstance(v, bool): + v = str(v).lower() + if isinstance(v, (int, float)): + v = str(v) + if isinstance(v, dict): + v = json.dumps(v) + + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == "multi": + new_params.extend((k, str(value)) for value in v) + else: + if collection_format == "ssv": + delimiter = " " + elif collection_format == "tsv": + delimiter = "\t" + elif collection_format == "pipes": + delimiter = "|" + else: # csv is the default + delimiter = "," + new_params.append((k, delimiter.join(quote(str(value)) for value in v))) + else: + new_params.append((k, quote(str(v)))) + + return "&".join(["=".join(map(str, item)) for item in new_params]) + + def files_parameters(self, files: Dict[str, Union[str, bytes]]): + """Builds form parameters. + + :param files: File parameters. + :return: Form parameters with files. + """ + params = [] + for k, v in files.items(): + if isinstance(v, str): + with open(v, "rb") as f: + filename = os.path.basename(f.name) + filedata = f.read() + elif isinstance(v, bytes): + filename = k + filedata = v + else: + raise ValueError("Unsupported file value") + mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream" + params.append(tuple([k, tuple([filename, filedata, mimetype])])) + return params + + def select_header_accept(self, accepts: List[str]) -> Optional[str]: + """Returns `Accept` based on an array of accepts provided. + + :param accepts: List of headers. + :return: Accept (e.g. application/json). + """ + if not accepts: + return None + + for accept in accepts: + if re.search("json", accept, re.IGNORECASE): + return accept + + return accepts[0] + + def select_header_content_type(self, content_types): + """Returns `Content-Type` based on an array of content_types provided. + + :param content_types: List of content-types. + :return: Content-Type (e.g. application/json). + """ + if not content_types: + return None + + for content_type in content_types: + if re.search("json", content_type, re.IGNORECASE): + return content_type + + return content_types[0] + + def __deserialize_file(self, response): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + handle file downloading + save response body into a tmp file and return the instance + + :param response: RESTResponse. + :return: file path. + """ + fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + content_disposition = response.getheader("Content-Disposition") + if content_disposition: + m = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition) + if m is None: + raise ValueError("Unexpected 'content-disposition' header value") + filename = m.group(1) + path = os.path.join(os.path.dirname(path), filename) + + with open(path, "wb") as f: + f.write(response.data) + + return path + + def __deserialize_primitive(self, data, klass): + """Deserializes string to primitive type. + + :param data: str. + :param klass: class literal. + + :return: int, long, float, str, bool. + """ + try: + return klass(data) + except UnicodeEncodeError: + return str(data) + except TypeError: + return data + + def __deserialize_object(self, value): + """Return an original value. + + :return: object. + """ + return value + + def __deserialize_date(self, string): + """Deserializes string to date. + + :param string: str. + :return: date. + """ + try: + return parse(string).date() + except ImportError: + return string + except ValueError: + raise rest.ApiException(status=0, reason="Failed to parse `{0}` as date object".format(string)) + + def __deserialize_datetime(self, string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :return: datetime. + """ + try: + return parse(string) + except ImportError: + return string + except ValueError: + raise rest.ApiException(status=0, reason=("Failed to parse `{0}` as datetime object".format(string))) + + def __deserialize_enum(self, data, klass): + """Deserializes primitive type to enum. + + :param data: primitive type. + :param klass: class literal. + :return: enum value. + """ + try: + return klass(data) + except ValueError: + raise rest.ApiException(status=0, reason=("Failed to parse `{0}` as `{1}`".format(data, klass))) + + def __deserialize_model(self, data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :param klass: class literal. + :return: model object. + """ + + return klass.from_dict(data) diff --git a/services/membership/src/stackit/membership/api_response.py b/services/membership/src/stackit/membership/api_response.py new file mode 100644 index 00000000..b3ba14a1 --- /dev/null +++ b/services/membership/src/stackit/membership/api_response.py @@ -0,0 +1,23 @@ +"""API response object.""" + +from __future__ import annotations + +from typing import Generic, Mapping, Optional, TypeVar + +from pydantic import BaseModel, Field, StrictBytes, StrictInt + + +T = TypeVar("T") + + +class ApiResponse(BaseModel, Generic[T]): + """ + API response object + """ + + status_code: StrictInt = Field(description="HTTP status code") + headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers") + data: T = Field(description="Deserialized data given the data type") + raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") + + model_config = {"arbitrary_types_allowed": True} diff --git a/services/membership/src/stackit/membership/configuration.py b/services/membership/src/stackit/membership/configuration.py new file mode 100644 index 00000000..17c0e247 --- /dev/null +++ b/services/membership/src/stackit/membership/configuration.py @@ -0,0 +1,111 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + + +class HostConfiguration: + def __init__( + self, + region=None, + server_index=None, + server_variables=None, + server_operation_index=None, + server_operation_variables=None, + ignore_operation_servers=False, + ) -> None: + """Constructor""" + self._base_path = "https://authorization.api.stackit.cloud" + """Default Base url + """ + self.server_index = 0 if server_index is None else server_index + self.server_operation_index = server_operation_index or {} + """Default server index + """ + self.server_variables = server_variables or {} + if region: + self.server_variables["region"] = "{}.".format(region) + self.server_operation_variables = server_operation_variables or {} + """Default server variables + """ + self.ignore_operation_servers = ignore_operation_servers + """Ignore operation servers + """ + + def get_host_settings(self): + """Gets an array of host settings + + :return: An array of host settings + """ + return [ + { + "url": "https://authorization.api.{region}stackit.cloud", + "description": "No description provided", + "variables": { + "region": { + "description": "No description provided", + "default_value": "", + } + }, + } + ] + + def get_host_from_settings(self, index, variables=None, servers=None): + """Gets host URL based on the index and variables + :param index: array index of the host settings + :param variables: hash of variable and the corresponding value + :param servers: an array of host settings or None + :return: URL based on host settings + """ + if index is None: + return self._base_path + + variables = {} if variables is None else variables + servers = self.get_host_settings() if servers is None else servers + + try: + server = servers[index] + except IndexError: + raise ValueError( + "Invalid index {0} when selecting the host settings. " + "Must be less than {1}".format(index, len(servers)) + ) + + url = server["url"] + + # go through variables and replace placeholders + for variable_name, variable in server.get("variables", {}).items(): + used_value = variables.get(variable_name, variable["default_value"]) + + if "enum_values" in variable and used_value not in variable["enum_values"]: + given_value = variables[variable_name].replace(".", "") + valid_values = [v.replace(".", "") for v in variable["enum_values"]] + raise ValueError( + "The variable `{0}` in the host URL has invalid value '{1}'. Must be '{2}'.".format( + variable_name, given_value, valid_values + ) + ) + + url = url.replace("{" + variable_name + "}", used_value) + + return url + + @property + def host(self): + """Return generated host.""" + return self.get_host_from_settings(self.server_index, variables=self.server_variables) + + @host.setter + def host(self, value): + """Fix base path.""" + self._base_path = value + self.server_index = None diff --git a/services/membership/src/stackit/membership/exceptions.py b/services/membership/src/stackit/membership/exceptions.py new file mode 100644 index 00000000..48a55e23 --- /dev/null +++ b/services/membership/src/stackit/membership/exceptions.py @@ -0,0 +1,199 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from typing import Any, Optional + +from typing_extensions import Self + + +class OpenApiException(Exception): + """The base exception class for all OpenAPIExceptions""" + + +class ApiTypeError(OpenApiException, TypeError): + def __init__(self, msg, path_to_item=None, valid_classes=None, key_type=None) -> None: + """Raises an exception for TypeErrors + + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (list): a list of keys an indices to get to the + current_item + None if unset + valid_classes (tuple): the primitive classes that current item + should be an instance of + None if unset + key_type (bool): False if our value is a value in a dict + True if it is a key in a dict + False if our item is an item in a list + None if unset + """ + self.path_to_item = path_to_item + self.valid_classes = valid_classes + self.key_type = key_type + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiTypeError, self).__init__(full_msg) + + +class ApiValueError(OpenApiException, ValueError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (list) the path to the exception in the + received_data dict. None if unset + """ + + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiValueError, self).__init__(full_msg) + + +class ApiAttributeError(OpenApiException, AttributeError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Raised when an attribute reference or assignment fails. + + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (None/list) the path to the exception in the + received_data dict + """ + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiAttributeError, self).__init__(full_msg) + + +class ApiKeyError(OpenApiException, KeyError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (None/list) the path to the exception in the + received_data dict + """ + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiKeyError, self).__init__(full_msg) + + +class ApiException(OpenApiException): + + def __init__( + self, + status=None, + reason=None, + http_resp=None, + *, + body: Optional[str] = None, + data: Optional[Any] = None, + ) -> None: + self.status = status + self.reason = reason + self.body = body + self.data = data + self.headers = None + + if http_resp: + if self.status is None: + self.status = http_resp.status + if self.reason is None: + self.reason = http_resp.reason + if self.body is None: + try: + self.body = http_resp.data.decode("utf-8") + except Exception: # noqa: S110 + pass + self.headers = http_resp.getheaders() + + @classmethod + def from_response( + cls, + *, + http_resp, + body: Optional[str], + data: Optional[Any], + ) -> Self: + if http_resp.status == 400: + raise BadRequestException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 401: + raise UnauthorizedException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 403: + raise ForbiddenException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 404: + raise NotFoundException(http_resp=http_resp, body=body, data=data) + + if 500 <= http_resp.status <= 599: + raise ServiceException(http_resp=http_resp, body=body, data=data) + raise ApiException(http_resp=http_resp, body=body, data=data) + + def __str__(self): + """Custom error messages for exception""" + error_message = "({0})\n" "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}\n".format(self.headers) + + if self.data or self.body: + error_message += "HTTP response body: {0}\n".format(self.data or self.body) + + return error_message + + +class BadRequestException(ApiException): + pass + + +class NotFoundException(ApiException): + pass + + +class UnauthorizedException(ApiException): + pass + + +class ForbiddenException(ApiException): + pass + + +class ServiceException(ApiException): + pass + + +def render_path(path_to_item): + """Returns a string representation of a path""" + result = "" + for pth in path_to_item: + if isinstance(pth, int): + result += "[{0}]".format(pth) + else: + result += "['{0}']".format(pth) + return result diff --git a/services/membership/src/stackit/membership/models/__init__.py b/services/membership/src/stackit/membership/models/__init__.py new file mode 100644 index 00000000..803829ae --- /dev/null +++ b/services/membership/src/stackit/membership/models/__init__.py @@ -0,0 +1,63 @@ +# coding: utf-8 + +# flake8: noqa +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + + +# import models into model package +from stackit.membership.models.add_members_payload import AddMembersPayload +from stackit.membership.models.add_roles_payload import AddRolesPayload +from stackit.membership.models.add_roles_payload_item import AddRolesPayloadItem +from stackit.membership.models.consistency import Consistency +from stackit.membership.models.create_resource_payload import CreateResourcePayload +from stackit.membership.models.create_resource_response import CreateResourceResponse +from stackit.membership.models.delete_resource_response import DeleteResourceResponse +from stackit.membership.models.delete_subject_response import DeleteSubjectResponse +from stackit.membership.models.enforce_permission_payload import ( + EnforcePermissionPayload, +) +from stackit.membership.models.error_response import ErrorResponse +from stackit.membership.models.existing_permission import ExistingPermission +from stackit.membership.models.list_members_response import ListMembersResponse +from stackit.membership.models.list_permissions_response import ListPermissionsResponse +from stackit.membership.models.list_subject_ids_response import ListSubjectIdsResponse +from stackit.membership.models.list_subjects_response import ListSubjectsResponse +from stackit.membership.models.list_user_memberships_response import ( + ListUserMembershipsResponse, +) +from stackit.membership.models.list_user_permissions_response import ( + ListUserPermissionsResponse, +) +from stackit.membership.models.member import Member +from stackit.membership.models.members_response import MembersResponse +from stackit.membership.models.permission import Permission +from stackit.membership.models.permission_request import PermissionRequest +from stackit.membership.models.remove_members_payload import RemoveMembersPayload +from stackit.membership.models.remove_role_request import RemoveRoleRequest +from stackit.membership.models.remove_roles_payload import RemoveRolesPayload +from stackit.membership.models.resource import Resource +from stackit.membership.models.role import Role +from stackit.membership.models.roles_response import RolesResponse +from stackit.membership.models.subject import Subject +from stackit.membership.models.transfer_subject_memberships_payload import ( + TransferSubjectMembershipsPayload, +) +from stackit.membership.models.user_membership import UserMembership +from stackit.membership.models.user_permission import UserPermission +from stackit.membership.models.user_resources_response import UserResourcesResponse +from stackit.membership.models.validate_child_members_payload import ( + ValidateChildMembersPayload, +) +from stackit.membership.models.write_schema_payload import WriteSchemaPayload +from stackit.membership.models.write_schema_response import WriteSchemaResponse +from stackit.membership.models.zookie import Zookie diff --git a/services/membership/src/stackit/membership/models/add_members_payload.py b/services/membership/src/stackit/membership/models/add_members_payload.py new file mode 100644 index 00000000..71a5f00a --- /dev/null +++ b/services/membership/src/stackit/membership/models/add_members_payload.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member + + +class AddMembersPayload(BaseModel): + """ + AddMembersPayload + """ + + members: List[Member] + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + __properties: ClassVar[List[str]] = ["members", "resourceType"] + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AddMembersPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AddMembersPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "resourceType": obj.get("resourceType"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/add_roles_payload.py b/services/membership/src/stackit/membership/models/add_roles_payload.py new file mode 100644 index 00000000..75c6f25a --- /dev/null +++ b/services/membership/src/stackit/membership/models/add_roles_payload.py @@ -0,0 +1,109 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.add_roles_payload_item import AddRolesPayloadItem + + +class AddRolesPayload(BaseModel): + """ + AddRolesPayload + """ + + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + roles: List[AddRolesPayloadItem] + __properties: ClassVar[List[str]] = ["resourceType", "roles"] + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AddRolesPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in roles (list) + _items = [] + if self.roles: + for _item in self.roles: + if _item: + _items.append(_item.to_dict()) + _dict["roles"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AddRolesPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "resourceType": obj.get("resourceType"), + "roles": ( + [AddRolesPayloadItem.from_dict(_item) for _item in obj["roles"]] + if obj.get("roles") is not None + else None + ), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/add_roles_payload_item.py b/services/membership/src/stackit/membership/models/add_roles_payload_item.py new file mode 100644 index 00000000..a5d098d6 --- /dev/null +++ b/services/membership/src/stackit/membership/models/add_roles_payload_item.py @@ -0,0 +1,111 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.permission_request import PermissionRequest + + +class AddRolesPayloadItem(BaseModel): + """ + AddRolesPayloadItem + """ + + description: Annotated[str, Field(min_length=1, strict=True, max_length=255)] + name: Annotated[str, Field(strict=True)] + permissions: List[PermissionRequest] + __properties: ClassVar[List[str]] = ["description", "name", "permissions"] + + @field_validator("name") + def name_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AddRolesPayloadItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in permissions (list) + _items = [] + if self.permissions: + for _item in self.permissions: + if _item: + _items.append(_item.to_dict()) + _dict["permissions"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AddRolesPayloadItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "description": obj.get("description"), + "name": obj.get("name"), + "permissions": ( + [PermissionRequest.from_dict(_item) for _item in obj["permissions"]] + if obj.get("permissions") is not None + else None + ), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/consistency.py b/services/membership/src/stackit/membership/models/consistency.py new file mode 100644 index 00000000..4cca36a0 --- /dev/null +++ b/services/membership/src/stackit/membership/models/consistency.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictBool +from typing_extensions import Self + +from stackit.membership.models.zookie import Zookie + + +class Consistency(BaseModel): + """ + Consistency + """ + + at_exact_snapshot: Optional[Zookie] = Field(default=None, alias="atExactSnapshot") + at_least_as_fresh: Optional[Zookie] = Field(default=None, alias="atLeastAsFresh") + fully_consistent: Optional[StrictBool] = Field(default=None, alias="fullyConsistent") + minimize_latency: Optional[StrictBool] = Field(default=None, alias="minimizeLatency") + __properties: ClassVar[List[str]] = ["atExactSnapshot", "atLeastAsFresh", "fullyConsistent", "minimizeLatency"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Consistency from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of at_exact_snapshot + if self.at_exact_snapshot: + _dict["atExactSnapshot"] = self.at_exact_snapshot.to_dict() + # override the default output from pydantic by calling `to_dict()` of at_least_as_fresh + if self.at_least_as_fresh: + _dict["atLeastAsFresh"] = self.at_least_as_fresh.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Consistency from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "atExactSnapshot": ( + Zookie.from_dict(obj["atExactSnapshot"]) if obj.get("atExactSnapshot") is not None else None + ), + "atLeastAsFresh": ( + Zookie.from_dict(obj["atLeastAsFresh"]) if obj.get("atLeastAsFresh") is not None else None + ), + "fullyConsistent": obj.get("fullyConsistent"), + "minimizeLatency": obj.get("minimizeLatency"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/create_resource_payload.py b/services/membership/src/stackit/membership/models/create_resource_payload.py new file mode 100644 index 00000000..d80e7417 --- /dev/null +++ b/services/membership/src/stackit/membership/models/create_resource_payload.py @@ -0,0 +1,137 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member + + +class CreateResourcePayload(BaseModel): + """ + CreateResourcePayload + """ + + members: Optional[List[Member]] = None + parent_id: Annotated[str, Field(strict=True)] = Field(alias="parentId") + parent_type: Annotated[str, Field(strict=True)] = Field(alias="parentType") + resource_alias: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, alias="resourceAlias") + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + __properties: ClassVar[List[str]] = ["members", "parentId", "parentType", "resourceAlias", "resourceId"] + + @field_validator("parent_id") + def parent_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("parent_type") + def parent_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + @field_validator("resource_alias") + def resource_alias_validate_regular_expression(cls, value): + """Validates the regular expression""" + if value is None: + return value + + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateResourcePayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateResourcePayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "parentId": obj.get("parentId"), + "parentType": obj.get("parentType"), + "resourceAlias": obj.get("resourceAlias"), + "resourceId": obj.get("resourceId"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/create_resource_response.py b/services/membership/src/stackit/membership/models/create_resource_response.py new file mode 100644 index 00000000..3156059a --- /dev/null +++ b/services/membership/src/stackit/membership/models/create_resource_response.py @@ -0,0 +1,160 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member +from stackit.membership.models.zookie import Zookie + + +class CreateResourceResponse(BaseModel): + """ + CreateResourceResponse + """ + + members: Optional[List[Member]] = None + parent_id: Annotated[str, Field(strict=True)] = Field(alias="parentId") + parent_type: Annotated[str, Field(strict=True, max_length=255)] = Field(alias="parentType") + resource_alias: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, alias="resourceAlias") + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + written_at: Optional[Zookie] = Field(default=None, alias="writtenAt") + __properties: ClassVar[List[str]] = [ + "members", + "parentId", + "parentType", + "resourceAlias", + "resourceId", + "resourceType", + "writtenAt", + ] + + @field_validator("parent_id") + def parent_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("parent_type") + def parent_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + @field_validator("resource_alias") + def resource_alias_validate_regular_expression(cls, value): + """Validates the regular expression""" + if value is None: + return value + + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateResourceResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + # override the default output from pydantic by calling `to_dict()` of written_at + if self.written_at: + _dict["writtenAt"] = self.written_at.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateResourceResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "parentId": obj.get("parentId"), + "parentType": obj.get("parentType"), + "resourceAlias": obj.get("resourceAlias"), + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + "writtenAt": Zookie.from_dict(obj["writtenAt"]) if obj.get("writtenAt") is not None else None, + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/delete_resource_response.py b/services/membership/src/stackit/membership/models/delete_resource_response.py new file mode 100644 index 00000000..6fea568b --- /dev/null +++ b/services/membership/src/stackit/membership/models/delete_resource_response.py @@ -0,0 +1,89 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field +from typing_extensions import Self + +from stackit.membership.models.zookie import Zookie + + +class DeleteResourceResponse(BaseModel): + """ + DeleteResourceResponse + """ + + written_at: Optional[Zookie] = Field(default=None, alias="writtenAt") + __properties: ClassVar[List[str]] = ["writtenAt"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of DeleteResourceResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of written_at + if self.written_at: + _dict["writtenAt"] = self.written_at.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of DeleteResourceResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + {"writtenAt": Zookie.from_dict(obj["writtenAt"]) if obj.get("writtenAt") is not None else None} + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/delete_subject_response.py b/services/membership/src/stackit/membership/models/delete_subject_response.py new file mode 100644 index 00000000..67e33be5 --- /dev/null +++ b/services/membership/src/stackit/membership/models/delete_subject_response.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing_extensions import Self + +from stackit.membership.models.zookie import Zookie + + +class DeleteSubjectResponse(BaseModel): + """ + DeleteSubjectResponse + """ + + deleted_at: Optional[Zookie] = Field(default=None, alias="deletedAt") + deleted_from_resource_ids: List[StrictStr] = Field(alias="deletedFromResourceIds") + __properties: ClassVar[List[str]] = ["deletedAt", "deletedFromResourceIds"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of DeleteSubjectResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of deleted_at + if self.deleted_at: + _dict["deletedAt"] = self.deleted_at.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of DeleteSubjectResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "deletedAt": Zookie.from_dict(obj["deletedAt"]) if obj.get("deletedAt") is not None else None, + "deletedFromResourceIds": obj.get("deletedFromResourceIds"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/enforce_permission_payload.py b/services/membership/src/stackit/membership/models/enforce_permission_payload.py new file mode 100644 index 00000000..96bdbecd --- /dev/null +++ b/services/membership/src/stackit/membership/models/enforce_permission_payload.py @@ -0,0 +1,109 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.consistency import Consistency + + +class EnforcePermissionPayload(BaseModel): + """ + EnforcePermissionPayload + """ + + actions: List[StrictStr] + consistency: Optional[Consistency] = None + resource: StrictStr + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + subject: Annotated[str, Field(strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["actions", "consistency", "resource", "resourceType", "subject"] + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EnforcePermissionPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of consistency + if self.consistency: + _dict["consistency"] = self.consistency.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of EnforcePermissionPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "actions": obj.get("actions"), + "consistency": ( + Consistency.from_dict(obj["consistency"]) if obj.get("consistency") is not None else None + ), + "resource": obj.get("resource"), + "resourceType": obj.get("resourceType"), + "subject": obj.get("subject"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/error_response.py b/services/membership/src/stackit/membership/models/error_response.py new file mode 100644 index 00000000..b936cec4 --- /dev/null +++ b/services/membership/src/stackit/membership/models/error_response.py @@ -0,0 +1,95 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from datetime import datetime +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from typing_extensions import Self + + +class ErrorResponse(BaseModel): + """ + ErrorResponse + """ + + error: StrictStr + message: StrictStr + path: StrictStr + status: StrictInt + time_stamp: datetime = Field(alias="timeStamp") + __properties: ClassVar[List[str]] = ["error", "message", "path", "status", "timeStamp"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ErrorResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ErrorResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "error": obj.get("error"), + "message": obj.get("message"), + "path": obj.get("path"), + "status": obj.get("status"), + "timeStamp": obj.get("timeStamp"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/existing_permission.py b/services/membership/src/stackit/membership/models/existing_permission.py new file mode 100644 index 00000000..627fea5e --- /dev/null +++ b/services/membership/src/stackit/membership/models/existing_permission.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class ExistingPermission(BaseModel): + """ + ExistingPermission + """ + + description: Annotated[str, Field(strict=True, max_length=255)] + name: Annotated[str, Field(strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["description", "name"] + + @field_validator("name") + def name_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ExistingPermission from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ExistingPermission from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"description": obj.get("description"), "name": obj.get("name")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/list_members_response.py b/services/membership/src/stackit/membership/models/list_members_response.py new file mode 100644 index 00000000..49fb671a --- /dev/null +++ b/services/membership/src/stackit/membership/models/list_members_response.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member + + +class ListMembersResponse(BaseModel): + """ + ListMembersResponse + """ + + members: List[Member] + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + __properties: ClassVar[List[str]] = ["members", "resourceId", "resourceType"] + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListMembersResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListMembersResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/list_permissions_response.py b/services/membership/src/stackit/membership/models/list_permissions_response.py new file mode 100644 index 00000000..afb2522b --- /dev/null +++ b/services/membership/src/stackit/membership/models/list_permissions_response.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Self + +from stackit.membership.models.permission import Permission + + +class ListPermissionsResponse(BaseModel): + """ + ListPermissionsResponse + """ + + permissions: List[Permission] + __properties: ClassVar[List[str]] = ["permissions"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListPermissionsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in permissions (list) + _items = [] + if self.permissions: + for _item in self.permissions: + if _item: + _items.append(_item.to_dict()) + _dict["permissions"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListPermissionsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "permissions": ( + [Permission.from_dict(_item) for _item in obj["permissions"]] + if obj.get("permissions") is not None + else None + ) + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/list_subject_ids_response.py b/services/membership/src/stackit/membership/models/list_subject_ids_response.py new file mode 100644 index 00000000..02b99d79 --- /dev/null +++ b/services/membership/src/stackit/membership/models/list_subject_ids_response.py @@ -0,0 +1,84 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing_extensions import Self + + +class ListSubjectIdsResponse(BaseModel): + """ + ListSubjectIdsResponse + """ + + cursor: Optional[StrictStr] = None + items: List[StrictStr] + limit: Optional[StrictInt] = None + __properties: ClassVar[List[str]] = ["cursor", "items", "limit"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListSubjectIdsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListSubjectIdsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"cursor": obj.get("cursor"), "items": obj.get("items"), "limit": obj.get("limit")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/list_subjects_response.py b/services/membership/src/stackit/membership/models/list_subjects_response.py new file mode 100644 index 00000000..b4733a97 --- /dev/null +++ b/services/membership/src/stackit/membership/models/list_subjects_response.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Self + +from stackit.membership.models.subject import Subject + + +class ListSubjectsResponse(BaseModel): + """ + ListSubjectsResponse + """ + + items: List[Subject] + __properties: ClassVar[List[str]] = ["items"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListSubjectsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in items (list) + _items = [] + if self.items: + for _item in self.items: + if _item: + _items.append(_item.to_dict()) + _dict["items"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListSubjectsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + {"items": [Subject.from_dict(_item) for _item in obj["items"]] if obj.get("items") is not None else None} + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/list_user_memberships_response.py b/services/membership/src/stackit/membership/models/list_user_memberships_response.py new file mode 100644 index 00000000..57a6ae62 --- /dev/null +++ b/services/membership/src/stackit/membership/models/list_user_memberships_response.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Self + +from stackit.membership.models.user_membership import UserMembership + + +class ListUserMembershipsResponse(BaseModel): + """ + ListUserMembershipsResponse + """ + + items: List[UserMembership] + __properties: ClassVar[List[str]] = ["items"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListUserMembershipsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in items (list) + _items = [] + if self.items: + for _item in self.items: + if _item: + _items.append(_item.to_dict()) + _dict["items"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListUserMembershipsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "items": ( + [UserMembership.from_dict(_item) for _item in obj["items"]] + if obj.get("items") is not None + else None + ) + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/list_user_permissions_response.py b/services/membership/src/stackit/membership/models/list_user_permissions_response.py new file mode 100644 index 00000000..7f993509 --- /dev/null +++ b/services/membership/src/stackit/membership/models/list_user_permissions_response.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Self + +from stackit.membership.models.user_permission import UserPermission + + +class ListUserPermissionsResponse(BaseModel): + """ + ListUserPermissionsResponse + """ + + items: List[UserPermission] + __properties: ClassVar[List[str]] = ["items"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListUserPermissionsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in items (list) + _items = [] + if self.items: + for _item in self.items: + if _item: + _items.append(_item.to_dict()) + _dict["items"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListUserPermissionsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "items": ( + [UserPermission.from_dict(_item) for _item in obj["items"]] + if obj.get("items") is not None + else None + ) + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/member.py b/services/membership/src/stackit/membership/models/member.py new file mode 100644 index 00000000..293dcb8b --- /dev/null +++ b/services/membership/src/stackit/membership/models/member.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class Member(BaseModel): + """ + Member + """ + + role: Annotated[str, Field(strict=True)] + subject: Annotated[str, Field(min_length=1, strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["role", "subject"] + + @field_validator("role") + def role_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Member from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Member from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"role": obj.get("role"), "subject": obj.get("subject")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/members_response.py b/services/membership/src/stackit/membership/models/members_response.py new file mode 100644 index 00000000..10c61bb7 --- /dev/null +++ b/services/membership/src/stackit/membership/models/members_response.py @@ -0,0 +1,122 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member +from stackit.membership.models.zookie import Zookie + + +class MembersResponse(BaseModel): + """ + MembersResponse + """ + + members: List[Member] + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + written_at: Optional[Zookie] = Field(default=None, alias="writtenAt") + __properties: ClassVar[List[str]] = ["members", "resourceId", "resourceType", "writtenAt"] + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MembersResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + # override the default output from pydantic by calling `to_dict()` of written_at + if self.written_at: + _dict["writtenAt"] = self.written_at.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MembersResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + "writtenAt": Zookie.from_dict(obj["writtenAt"]) if obj.get("writtenAt") is not None else None, + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/permission.py b/services/membership/src/stackit/membership/models/permission.py new file mode 100644 index 00000000..20208caa --- /dev/null +++ b/services/membership/src/stackit/membership/models/permission.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class Permission(BaseModel): + """ + Permission + """ + + description: Annotated[str, Field(min_length=1, strict=True, max_length=255)] + name: Annotated[str, Field(strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["description", "name"] + + @field_validator("name") + def name_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Permission from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Permission from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"description": obj.get("description"), "name": obj.get("name")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/permission_request.py b/services/membership/src/stackit/membership/models/permission_request.py new file mode 100644 index 00000000..07b71eed --- /dev/null +++ b/services/membership/src/stackit/membership/models/permission_request.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class PermissionRequest(BaseModel): + """ + PermissionRequest + """ + + name: Annotated[str, Field(strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["name"] + + @field_validator("name") + def name_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of PermissionRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of PermissionRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"name": obj.get("name")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/remove_members_payload.py b/services/membership/src/stackit/membership/models/remove_members_payload.py new file mode 100644 index 00000000..7c3f18fc --- /dev/null +++ b/services/membership/src/stackit/membership/models/remove_members_payload.py @@ -0,0 +1,109 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member + + +class RemoveMembersPayload(BaseModel): + """ + RemoveMembersPayload + """ + + force_remove: Optional[StrictBool] = Field(default=None, alias="forceRemove") + members: List[Member] + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + __properties: ClassVar[List[str]] = ["forceRemove", "members", "resourceType"] + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RemoveMembersPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RemoveMembersPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "forceRemove": obj.get("forceRemove"), + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "resourceType": obj.get("resourceType"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/remove_role_request.py b/services/membership/src/stackit/membership/models/remove_role_request.py new file mode 100644 index 00000000..cd5cf702 --- /dev/null +++ b/services/membership/src/stackit/membership/models/remove_role_request.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class RemoveRoleRequest(BaseModel): + """ + RemoveRoleRequest + """ + + name: Annotated[str, Field(strict=True)] + __properties: ClassVar[List[str]] = ["name"] + + @field_validator("name") + def name_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RemoveRoleRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RemoveRoleRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"name": obj.get("name")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/remove_roles_payload.py b/services/membership/src/stackit/membership/models/remove_roles_payload.py new file mode 100644 index 00000000..aee700be --- /dev/null +++ b/services/membership/src/stackit/membership/models/remove_roles_payload.py @@ -0,0 +1,109 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.remove_role_request import RemoveRoleRequest + + +class RemoveRolesPayload(BaseModel): + """ + RemoveRolesPayload + """ + + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + roles: List[RemoveRoleRequest] + __properties: ClassVar[List[str]] = ["resourceType", "roles"] + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RemoveRolesPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in roles (list) + _items = [] + if self.roles: + for _item in self.roles: + if _item: + _items.append(_item.to_dict()) + _dict["roles"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RemoveRolesPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "resourceType": obj.get("resourceType"), + "roles": ( + [RemoveRoleRequest.from_dict(_item) for _item in obj["roles"]] + if obj.get("roles") is not None + else None + ), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/resource.py b/services/membership/src/stackit/membership/models/resource.py new file mode 100644 index 00000000..59927e02 --- /dev/null +++ b/services/membership/src/stackit/membership/models/resource.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class Resource(BaseModel): + """ + Resource + """ + + resource_alias: Optional[Annotated[str, Field(strict=True, max_length=255)]] = Field( + default=None, alias="resourceAlias" + ) + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + __properties: ClassVar[List[str]] = ["resourceAlias", "resourceId", "resourceType"] + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Resource from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Resource from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "resourceAlias": obj.get("resourceAlias"), + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/role.py b/services/membership/src/stackit/membership/models/role.py new file mode 100644 index 00000000..764a5867 --- /dev/null +++ b/services/membership/src/stackit/membership/models/role.py @@ -0,0 +1,111 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.permission import Permission + + +class Role(BaseModel): + """ + Role + """ + + description: Annotated[str, Field(strict=True, max_length=255)] + name: Annotated[str, Field(strict=True)] + permissions: List[Permission] + __properties: ClassVar[List[str]] = ["description", "name", "permissions"] + + @field_validator("name") + def name_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Role from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in permissions (list) + _items = [] + if self.permissions: + for _item in self.permissions: + if _item: + _items.append(_item.to_dict()) + _dict["permissions"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Role from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "description": obj.get("description"), + "name": obj.get("name"), + "permissions": ( + [Permission.from_dict(_item) for _item in obj["permissions"]] + if obj.get("permissions") is not None + else None + ), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/roles_response.py b/services/membership/src/stackit/membership/models/roles_response.py new file mode 100644 index 00000000..1bff50f5 --- /dev/null +++ b/services/membership/src/stackit/membership/models/roles_response.py @@ -0,0 +1,114 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.role import Role + + +class RolesResponse(BaseModel): + """ + RolesResponse + """ + + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + roles: List[Role] + __properties: ClassVar[List[str]] = ["resourceId", "resourceType", "roles"] + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RolesResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in roles (list) + _items = [] + if self.roles: + for _item in self.roles: + if _item: + _items.append(_item.to_dict()) + _dict["roles"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RolesResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + "roles": [Role.from_dict(_item) for _item in obj["roles"]] if obj.get("roles") is not None else None, + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/subject.py b/services/membership/src/stackit/membership/models/subject.py new file mode 100644 index 00000000..7cf40de9 --- /dev/null +++ b/services/membership/src/stackit/membership/models/subject.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing_extensions import Annotated, Self + + +class Subject(BaseModel): + """ + Subject + """ + + email: Annotated[str, Field(strict=True, max_length=255)] + id: Annotated[str, Field(strict=True, max_length=255)] + type: StrictStr + __properties: ClassVar[List[str]] = ["email", "id", "type"] + + @field_validator("type") + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(["user", "client", "service-account"]): + raise ValueError("must be one of enum values ('user', 'client', 'service-account')") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Subject from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Subject from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"email": obj.get("email"), "id": obj.get("id"), "type": obj.get("type")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/transfer_subject_memberships_payload.py b/services/membership/src/stackit/membership/models/transfer_subject_memberships_payload.py new file mode 100644 index 00000000..0a64c775 --- /dev/null +++ b/services/membership/src/stackit/membership/models/transfer_subject_memberships_payload.py @@ -0,0 +1,82 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field +from typing_extensions import Annotated, Self + + +class TransferSubjectMembershipsPayload(BaseModel): + """ + TransferSubjectMembershipsPayload + """ + + target_subject_id: Annotated[str, Field(min_length=1, strict=True, max_length=255)] = Field(alias="targetSubjectId") + __properties: ClassVar[List[str]] = ["targetSubjectId"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TransferSubjectMembershipsPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TransferSubjectMembershipsPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"targetSubjectId": obj.get("targetSubjectId")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/user_membership.py b/services/membership/src/stackit/membership/models/user_membership.py new file mode 100644 index 00000000..77a3a384 --- /dev/null +++ b/services/membership/src/stackit/membership/models/user_membership.py @@ -0,0 +1,114 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + + +class UserMembership(BaseModel): + """ + UserMembership + """ + + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + role: Annotated[str, Field(strict=True)] + subject: Annotated[str, Field(strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["resourceId", "resourceType", "role", "subject"] + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + @field_validator("role") + def role_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?\.?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?\.?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UserMembership from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UserMembership from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + "role": obj.get("role"), + "subject": obj.get("subject"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/user_permission.py b/services/membership/src/stackit/membership/models/user_permission.py new file mode 100644 index 00000000..8b0cb1d4 --- /dev/null +++ b/services/membership/src/stackit/membership/models/user_permission.py @@ -0,0 +1,118 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.existing_permission import ExistingPermission + + +class UserPermission(BaseModel): + """ + UserPermission + """ + + permissions: List[ExistingPermission] + resource_id: Annotated[str, Field(strict=True)] = Field(alias="resourceId") + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + __properties: ClassVar[List[str]] = ["permissions", "resourceId", "resourceType"] + + @field_validator("resource_id") + def resource_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^([a-zA-Z0-9\/_|\-=+]{1,})$", value): + raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9\/_|\-=+]{1,})$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UserPermission from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in permissions (list) + _items = [] + if self.permissions: + for _item in self.permissions: + if _item: + _items.append(_item.to_dict()) + _dict["permissions"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UserPermission from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "permissions": ( + [ExistingPermission.from_dict(_item) for _item in obj["permissions"]] + if obj.get("permissions") is not None + else None + ), + "resourceId": obj.get("resourceId"), + "resourceType": obj.get("resourceType"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/user_resources_response.py b/services/membership/src/stackit/membership/models/user_resources_response.py new file mode 100644 index 00000000..d378369c --- /dev/null +++ b/services/membership/src/stackit/membership/models/user_resources_response.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing_extensions import Annotated, Self + +from stackit.membership.models.resource import Resource + + +class UserResourcesResponse(BaseModel): + """ + UserResourcesResponse + """ + + cursor: StrictStr + items: List[Resource] + limit: Annotated[int, Field(le=100, strict=True)] + __properties: ClassVar[List[str]] = ["cursor", "items", "limit"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UserResourcesResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in items (list) + _items = [] + if self.items: + for _item in self.items: + if _item: + _items.append(_item.to_dict()) + _dict["items"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UserResourcesResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "cursor": obj.get("cursor"), + "items": ( + [Resource.from_dict(_item) for _item in obj["items"]] if obj.get("items") is not None else None + ), + "limit": obj.get("limit") if obj.get("limit") is not None else 50, + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/validate_child_members_payload.py b/services/membership/src/stackit/membership/models/validate_child_members_payload.py new file mode 100644 index 00000000..dba23501 --- /dev/null +++ b/services/membership/src/stackit/membership/models/validate_child_members_payload.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +import re +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing_extensions import Annotated, Self + +from stackit.membership.models.member import Member + + +class ValidateChildMembersPayload(BaseModel): + """ + ValidateChildMembersPayload + """ + + child_resource_type: Annotated[str, Field(strict=True)] = Field(alias="childResourceType") + members: List[Member] + resource_type: Annotated[str, Field(strict=True)] = Field(alias="resourceType") + __properties: ClassVar[List[str]] = ["childResourceType", "members", "resourceType"] + + @field_validator("child_resource_type") + def child_resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + @field_validator("resource_type") + def resource_type_validate_regular_expression(cls, value): + """Validates the regular expression""" + if not re.match(r"^[a-z](?:-?[a-z]){1,63}$", value): + raise ValueError(r"must validate the regular expression /^[a-z](?:-?[a-z]){1,63}$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ValidateChildMembersPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in members (list) + _items = [] + if self.members: + for _item in self.members: + if _item: + _items.append(_item.to_dict()) + _dict["members"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ValidateChildMembersPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "childResourceType": obj.get("childResourceType"), + "members": ( + [Member.from_dict(_item) for _item in obj["members"]] if obj.get("members") is not None else None + ), + "resourceType": obj.get("resourceType"), + } + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/write_schema_payload.py b/services/membership/src/stackit/membership/models/write_schema_payload.py new file mode 100644 index 00000000..dd475ae7 --- /dev/null +++ b/services/membership/src/stackit/membership/models/write_schema_payload.py @@ -0,0 +1,82 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing_extensions import Self + + +class WriteSchemaPayload(BaseModel): + """ + WriteSchemaPayload + """ + + var_schema: StrictStr = Field(alias="schema") + __properties: ClassVar[List[str]] = ["schema"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WriteSchemaPayload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WriteSchemaPayload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"schema": obj.get("schema")}) + return _obj diff --git a/services/membership/src/stackit/membership/models/write_schema_response.py b/services/membership/src/stackit/membership/models/write_schema_response.py new file mode 100644 index 00000000..d1f455a5 --- /dev/null +++ b/services/membership/src/stackit/membership/models/write_schema_response.py @@ -0,0 +1,89 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field +from typing_extensions import Self + +from stackit.membership.models.zookie import Zookie + + +class WriteSchemaResponse(BaseModel): + """ + WriteSchemaResponse + """ + + written_at: Zookie = Field(alias="writtenAt") + __properties: ClassVar[List[str]] = ["writtenAt"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WriteSchemaResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of written_at + if self.written_at: + _dict["writtenAt"] = self.written_at.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WriteSchemaResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + {"writtenAt": Zookie.from_dict(obj["writtenAt"]) if obj.get("writtenAt") is not None else None} + ) + return _obj diff --git a/services/membership/src/stackit/membership/models/zookie.py b/services/membership/src/stackit/membership/models/zookie.py new file mode 100644 index 00000000..6a952387 --- /dev/null +++ b/services/membership/src/stackit/membership/models/zookie.py @@ -0,0 +1,82 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing_extensions import Self + + +class Zookie(BaseModel): + """ + Zookie + """ + + zookie: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["zookie"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Zookie from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Zookie from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"zookie": obj.get("zookie")}) + return _obj diff --git a/services/membership/src/stackit/membership/py.typed b/services/membership/src/stackit/membership/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/services/membership/src/stackit/membership/rest.py b/services/membership/src/stackit/membership/rest.py new file mode 100644 index 00000000..98409262 --- /dev/null +++ b/services/membership/src/stackit/membership/rest.py @@ -0,0 +1,149 @@ +# coding: utf-8 + +""" + STACKIT Membership API + + The Membership API is used to manage memberships, roles and permissions of STACKIT resources, like projects, folders, organizations and other resources. + + The version of the OpenAPI document: 2.0 + Contact: SIT-STACKIT-Core-Platform-Security@mail.schwarz + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 docstring might be too long + +import io +import json +import re + +import requests +from stackit.core.authorization import Authorization +from stackit.core.configuration import Configuration + +from stackit.membership.exceptions import ApiException, ApiValueError + + +RESTResponseType = requests.Response + + +class RESTResponse(io.IOBase): + + def __init__(self, resp) -> None: + self.response = resp + self.status = resp.status_code + self.reason = resp.reason + self.data = None + + def read(self): + if self.data is None: + self.data = self.response.content + return self.data + + def getheaders(self): + """Returns a dictionary of the response headers.""" + return self.response.headers + + def getheader(self, name, default=None): + """Returns a given response header.""" + return self.response.headers.get(name, default) + + +class RESTClientObject: + def __init__(self, config: Configuration) -> None: + self.session = config.custom_http_session if config.custom_http_session else requests.Session() + authorization = Authorization(config) + self.session.auth = authorization.auth_method + + def request(self, method, url, headers=None, body=None, post_params=None, _request_timeout=None): + """Perform requests. + + :param method: http request method + :param url: http request url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, + `application/x-www-form-urlencoded` + and `multipart/form-data` + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + """ + method = method.upper() + if method not in ["GET", "HEAD", "DELETE", "POST", "PUT", "PATCH", "OPTIONS"]: + raise ValueError("Method %s not allowed", method) + + if post_params and body: + raise ApiValueError("body parameter cannot be used with post_params parameter.") + + post_params = post_params or {} + headers = headers or {} + + try: + # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` + if method in ["POST", "PUT", "PATCH", "OPTIONS", "DELETE"]: + + # no content type provided or payload is json + content_type = headers.get("Content-Type") + if not content_type or re.search("json", content_type, re.IGNORECASE): + request_body = None + if body is not None: + request_body = json.dumps(body) + r = self.session.request( + method, + url, + data=request_body, + headers=headers, + ) + elif content_type == "application/x-www-form-urlencoded": + r = self.session.request( + method, + url, + params=post_params, + headers=headers, + ) + elif content_type == "multipart/form-data": + # must del headers['Content-Type'], or the correct + # Content-Type which generated by urllib3 will be + # overwritten. + del headers["Content-Type"] + # Ensures that dict objects are serialized + post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a, b) for a, b in post_params] + r = self.session.request( + method, + url, + files=post_params, + headers=headers, + ) + # Pass a `string` parameter directly in the body to support + # other content types than JSON when `body` argument is + # provided in serialized form. + elif isinstance(body, str) or isinstance(body, bytes): + r = self.session.request( + method, + url, + data=body, + headers=headers, + ) + elif headers["Content-Type"] == "text/plain" and isinstance(body, bool): + request_body = "true" if body else "false" + r = self.session.request(method, url, data=request_body, headers=headers) + else: + # Cannot generate the request from given parameters + msg = """Cannot prepare a request message for provided + arguments. Please check that your arguments match + declared content type.""" + raise ApiException(status=0, reason=msg) + # For `GET`, `HEAD` + else: + r = self.session.request( + method, + url, + params={}, + headers=headers, + ) + except requests.exceptions.SSLError as e: + msg = "\n".join([type(e).__name__, str(e)]) + raise ApiException(status=0, reason=msg) + + return RESTResponse(r)