From d5e8cef306ed9d2aa638e879c8b7ec5f84f4f049 Mon Sep 17 00:00:00 2001 From: Valeriia Ziukina Date: Fri, 7 Feb 2025 14:04:21 +0100 Subject: [PATCH 1/2] implemented methods --- otcextensions/sdk/apig/v2/_proxy.py | 37 +++++++++ otcextensions/sdk/apig/v2/apigroup.py | 83 +++++++++++++++++++ .../functional/sdk/apig/v2/test_api_group.py | 65 +++++++++++++++ .../sdk/apig/v2/test_environment.py | 3 - 4 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 otcextensions/sdk/apig/v2/apigroup.py create mode 100644 otcextensions/tests/functional/sdk/apig/v2/test_api_group.py diff --git a/otcextensions/sdk/apig/v2/_proxy.py b/otcextensions/sdk/apig/v2/_proxy.py index fc5b22bac..28203a778 100644 --- a/otcextensions/sdk/apig/v2/_proxy.py +++ b/otcextensions/sdk/apig/v2/_proxy.py @@ -16,6 +16,7 @@ from otcextensions.sdk.apig.v2 import gateway as _gateway from otcextensions.sdk.apig.v2 import az as _az from otcextensions.sdk.apig.v2 import apienvironment as _api_environment +from otcextensions.sdk.apig.v2 import apigroup as _api_group class Proxy(proxy.Proxy): @@ -330,3 +331,39 @@ def environments(self, gateway, **attrs): paginated=False, gateway_id=gateway.id, **attrs) + + def create_api_group(self, gateway, **attrs): + gateway = self._get_resource(_gateway.Gateway, gateway) + return self._create(_api_group.ApiGroup, + gateway_id=gateway.id, + **attrs) + + def update_api_group(self, gateway, api_group, **attrs): + gateway = self._get_resource(_gateway.Gateway, gateway) + api_group = self._get_resource(_api_group.ApiGroup, api_group) + return api_group._update_group(self, gateway=gateway, **attrs) + + def delete_api_group(self, gateway, api_group): + gateway = self._get_resource(_gateway.Gateway, gateway) + api_group = self._get_resource(_api_group.ApiGroup, api_group) + return self._delete(_api_group.ApiGroup, + api_group, + gateway_id=gateway.id) + + def get_api_group(self, gateway, api_group): + gateway = self._get_resource(_gateway.Gateway, gateway) + return self._get(_api_group.ApiGroup, + api_group, + gateway_id=gateway.id) + + def api_groups(self, gateway, **attrs): + gateway = self._get_resource(_gateway.Gateway, gateway) + return self._list(_api_group.ApiGroup, + paginated=False, + gateway_id=gateway.id, + **attrs) + + def verify_api_group_name(self, gateway, **attrs): + gateway = self._get_resource(_gateway.Gateway, gateway) + api_group = _api_group.ApiGroup(gateway_id=gateway.id) + return api_group._verify_name(self, gateway=gateway, **attrs) diff --git a/otcextensions/sdk/apig/v2/apigroup.py b/otcextensions/sdk/apig/v2/apigroup.py new file mode 100644 index 000000000..641cdd92e --- /dev/null +++ b/otcextensions/sdk/apig/v2/apigroup.py @@ -0,0 +1,83 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from openstack import resource +from openstack import exceptions + +class UrlDomainSpec(resource.Resource): + id = resource.Body('id') + domain = resource.Body('domain') + cname_status = resource.Body('cname_status', type=int) + ssl_id = resource.Body('ssl_id') + ssl_name = resource.Body('ssl_name') + min_ssl_version = resource.Body('min_ssl_version') + verified_client_certificate_enabled = resource.Body( + 'verified_client_certificate_enabled', + type=bool) + is_has_trusted_root_ca = resource.Body('is_has_trusted_root_ca', + type=bool) + + +class ApiGroup(resource.Resource): + base_path = f'/apigw/instances/%(gateway_id)s/api-groups' + + allow_list = True + allow_create = True + allow_commit = True + allow_delete = True + allow_fetch = True + + _query_mapping = resource.QueryParameters('limit', 'offset', 'id', + 'name', 'precise_search') + resources_key = 'groups' + + gateway_id = resource.URI('gateway_id') + name = resource.Body('name') + remark = resource.Body('remark') + roma_app_id = resource.Body('roma_app_id') + version = resource.Body('version') + + + id = resource.Body('id') + status = resource.Body('status') + sl_domain = resource.Body('sl_domain') + register_time = resource.Body('register_time') + update_time = resource.Body('update_time') + on_sell_status = resource.Body('on_sell_status', type=int) + url_domains = resource.Body('url_domains', + type=list, + list_type=UrlDomainSpec) + sl_domain_access_enabled = resource.Body('sl_domain_access_enabled', + type=bool) + sl_domains = resource.Body('sl_domains', type=list) + call_limits = resource.Body('call_limits', type=int) + time_interval = resource.Body('time_interval', type=int) + time_unit = resource.Body('time_unit') + is_default = resource.Body('is_default', type=bool) + roma_app_name = resource.Body('roma_app_name') + + def _verify_name(self, session, gateway, **attrs): + """Verify the name of an API group. + """ + uri = f'/apigw/instances/{gateway.id}/api-groups/check' + response = session.post(uri, json=attrs) + exceptions.raise_from_response(response) + self._translate_response(response) + return self + + def _update_group(self, session, gateway, **attrs): + """Update API group. + """ + url = f'/apigw/instances/{gateway.id}/api-groups/{self.id}' + response = session.put(url, json=attrs) + exceptions.raise_from_response(response) + self._translate_response(response) + return self diff --git a/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py b/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py new file mode 100644 index 000000000..c057814e9 --- /dev/null +++ b/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py @@ -0,0 +1,65 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from otcextensions.tests.functional.sdk.apig import TestApiG + + +class TestApiGroup(TestApiG): + api_group = None + + def setUp(self): + super(TestApiGroup, self).setUp() + self.create_gateway() + + def test_01_create_api_group(self): + attrs = { + "name": "api_group_001", + "remark": "API group 1" + } + created = self.client.create_api_group(gateway=TestApiG.gateway, + **attrs) + self.assertIsNotNone(created.id) + TestApiGroup.api_group = created + + def test_02_get_api_group(self): + found = self.client.get_api_group( + gateway=TestApiG.gateway, + api_group=TestApiGroup.api_group.id) + self.assertEqual(TestApiGroup.api_group.name, found.name) + + def test_03_update_api_group(self): + new_remark = 'Brand new remark' + attrs = { + 'name': TestApiGroup.api_group.name, + 'remark': new_remark + } + updated = self.client.update_api_group( + gateway=TestApiG.gateway, + api_group=TestApiGroup.api_group.id, + **attrs) + self.assertEqual(updated.remark, new_remark) + + def test_04_list_api_group(self): + groups = list(self.client.api_groups(gateway=TestApiG.gateway)) + self.assertGreater(len(groups), 1) + + + def test_05_verify_api_group(self): + attrs = { + "group_name" : "api_group_001" + } + result = self.client.verify_api_group_name(gateway=TestApiG.gateway) + + def test_06_delete_api_group(self): + self.client.delete_api_group(gateway=TestApiG.gateway, + api_group=TestApiGroup.api_group) + self.delete_gateway() diff --git a/otcextensions/tests/functional/sdk/apig/v2/test_environment.py b/otcextensions/tests/functional/sdk/apig/v2/test_environment.py index d137e1157..2123b49e4 100644 --- a/otcextensions/tests/functional/sdk/apig/v2/test_environment.py +++ b/otcextensions/tests/functional/sdk/apig/v2/test_environment.py @@ -20,9 +20,6 @@ def setUp(self): super(TestEnvironment, self).setUp() self.create_gateway() - def tearDown(self): - super(TestEnvironment, self).tearDown() - def test_01_create_environment(self): attrs = { "name": "DEV", From 7f71624dd2eeb9452dd751e4a0e3329870dd317a Mon Sep 17 00:00:00 2001 From: Valeriia Ziukina Date: Fri, 7 Feb 2025 18:08:00 +0100 Subject: [PATCH 2/2] all tests for apig group management --- .stestr.blacklist.functional | 3 +- doc/source/sdk/guides/apig.rst | 56 +++++++++ doc/source/sdk/proxies/apig.rst | 7 ++ doc/source/sdk/resources/apig/index.rst | 1 + doc/source/sdk/resources/apig/v2/group.rst | 13 ++ examples/apig/create_api_group.py | 25 ++++ examples/apig/delete_api_group.py | 21 ++++ examples/apig/get_api_group.py | 21 ++++ examples/apig/list_api_groups.py | 20 ++++ examples/apig/update_api_group.py | 27 +++++ examples/apig/verify_api_group_name.py | 23 ++++ otcextensions/sdk/apig/v2/_proxy.py | 58 ++++++++- otcextensions/sdk/apig/v2/apigroup.py | 5 +- .../functional/sdk/apig/v2/test_api_group.py | 6 +- .../tests/unit/sdk/apig/v2/test_api_group.py | 112 ++++++++++++++++++ .../tests/unit/sdk/apig/v2/test_proxy.py | 64 ++++++++++ ...pig-group-management-9416e9bfeaf5e9b3.yaml | 4 + 17 files changed, 455 insertions(+), 11 deletions(-) create mode 100644 doc/source/sdk/resources/apig/v2/group.rst create mode 100644 examples/apig/create_api_group.py create mode 100644 examples/apig/delete_api_group.py create mode 100644 examples/apig/get_api_group.py create mode 100644 examples/apig/list_api_groups.py create mode 100644 examples/apig/update_api_group.py create mode 100644 examples/apig/verify_api_group_name.py create mode 100644 otcextensions/tests/unit/sdk/apig/v2/test_api_group.py create mode 100644 releasenotes/notes/apig-group-management-9416e9bfeaf5e9b3.yaml diff --git a/.stestr.blacklist.functional b/.stestr.blacklist.functional index d169cd8d3..96466bbc3 100644 --- a/.stestr.blacklist.functional +++ b/.stestr.blacklist.functional @@ -40,5 +40,4 @@ otcextensions.tests.functional.sdk.function_graph.v2.test_dependency* otcextensions.tests.functional.sdk.function_graph.v2.test_log* otcextensions.tests.functional.sdk.function_graph.v2.test_template* otcextensions.tests.functional.sdk.function_graph.v2.test_import_export* -otcextensions.tests.functional.sdk.apig.v2.test_gateway -otcextensions.tests.functional.sdk.apig.v2.test_environment +otcextensions.tests.functional.sdk.apig.v2* diff --git a/doc/source/sdk/guides/apig.rst b/doc/source/sdk/guides/apig.rst index 520963078..e2475de41 100644 --- a/doc/source/sdk/guides/apig.rst +++ b/doc/source/sdk/guides/apig.rst @@ -205,3 +205,59 @@ with a specific API Gateway. .. literalinclude:: ../examples/apig/list_envs.py :lines: 16-20 + +Api Group +_________ + +Create Api Group +^^^^^^^^^^^^^^^^ + +This example demonstrates how to create a new API group in the API Gateway. + +.. literalinclude:: ../examples/apig/create_api_group.py + :lines: 16-25 + +Update Api Group +^^^^^^^^^^^^^^^^ + +This example demonstrates how to update an existing API group +in the API Gateway. + +.. literalinclude:: ../examples/apig/update_api_group.py + :lines: 16-27 + +Delete Api Group +^^^^^^^^^^^^^^^^ + +This example demonstrates how to delete an existing API group from +the API Gateway. + +.. literalinclude:: ../examples/apig/delete_api_group.py + :lines: 16-21 + +List Api Groups +^^^^^^^^^^^^^^^ + +This example demonstrates how to list all API groups associated +with a specific API Gateway. + +.. literalinclude:: ../examples/apig/list_api_groups.py + :lines: 16-20 + +Get Api Group +^^^^^^^^^^^^^ + +This example demonstrates how to retrieve details of a specific +API group from the API Gateway. + +.. literalinclude:: ../examples/apig/get_api_group.py + :lines: 16-21 + +Verify Api Group Name +^^^^^^^^^^^^^^^^^^^^^ + +This example demonstrates how to verify whether a given API group +name is available in the API Gateway. + +.. literalinclude:: ../examples/apig/verify_api_group_name.py + :lines: 16-23 diff --git a/doc/source/sdk/proxies/apig.rst b/doc/source/sdk/proxies/apig.rst index 43fc656b2..3317b9bcb 100644 --- a/doc/source/sdk/proxies/apig.rst +++ b/doc/source/sdk/proxies/apig.rst @@ -26,3 +26,10 @@ Environment Operations :noindex: :members: create_environment, update_environment, environments, delete_environment + +Api Group Operations +^^^^^^^^^^^^^^^^^^^^ +.. autoclass:: otcextensions.sdk.apig.v2._proxy.Proxy + :noindex: + :members: create_api_group, update_api_group, delete_api_group, + get_api_group, api_groups, verify_api_group_name diff --git a/doc/source/sdk/resources/apig/index.rst b/doc/source/sdk/resources/apig/index.rst index 86b6bac71..7a7de7643 100644 --- a/doc/source/sdk/resources/apig/index.rst +++ b/doc/source/sdk/resources/apig/index.rst @@ -7,3 +7,4 @@ ApiGateway Resources v2/gateway v2/az v2/env + v2/group diff --git a/doc/source/sdk/resources/apig/v2/group.rst b/doc/source/sdk/resources/apig/v2/group.rst new file mode 100644 index 000000000..eedee990c --- /dev/null +++ b/doc/source/sdk/resources/apig/v2/group.rst @@ -0,0 +1,13 @@ +otcextensions.sdk.apig.v2.apigroup +================================== + +.. automodule:: otcextensions.sdk.apig.v2.apigroup + +The ApiGroup Class +------------------ + +The ``ApiGroup`` class inherits from +:class:`~otcextensions.sdk.sdk_resource.Resource`. + +.. autoclass:: otcextensions.sdk.apig.v2.apigroup.ApiGroup + :members: diff --git a/examples/apig/create_api_group.py b/examples/apig/create_api_group.py new file mode 100644 index 000000000..5a335a4da --- /dev/null +++ b/examples/apig/create_api_group.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Create API group for gateway +""" +import openstack + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +attrs = { + "name": "api_group_001", + "remark": "API group 1" +} +created = conn.apig.create_api_group(gateway="gateway_id", + **attrs) diff --git a/examples/apig/delete_api_group.py b/examples/apig/delete_api_group.py new file mode 100644 index 000000000..0a5abe28b --- /dev/null +++ b/examples/apig/delete_api_group.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Delete API group from gateway +""" +import openstack + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +conn.apig.delete_api_group(gateway='gateway_id', + api_group='api_group_id') diff --git a/examples/apig/get_api_group.py b/examples/apig/get_api_group.py new file mode 100644 index 000000000..607cea399 --- /dev/null +++ b/examples/apig/get_api_group.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Get API group for gateway +""" +import openstack + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +found = conn.apig.get_api_group(gateway='gateway_id', + api_group='api_group_id') diff --git a/examples/apig/list_api_groups.py b/examples/apig/list_api_groups.py new file mode 100644 index 000000000..4a7a3b8d1 --- /dev/null +++ b/examples/apig/list_api_groups.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Get list of API groups for gateway +""" +import openstack + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +groups = list(conn.apig.api_groups(gateway="gateway_id")) diff --git a/examples/apig/update_api_group.py b/examples/apig/update_api_group.py new file mode 100644 index 000000000..db817f77c --- /dev/null +++ b/examples/apig/update_api_group.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Update API group for gateway +""" +import openstack + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +attrs = { + 'name': 'name', + 'remark': 'new_remark' +} +updated = conn.apig.update_api_group( + gateway='gateway_id', + api_group='api_group_id', + **attrs) diff --git a/examples/apig/verify_api_group_name.py b/examples/apig/verify_api_group_name.py new file mode 100644 index 000000000..bd0d1c23d --- /dev/null +++ b/examples/apig/verify_api_group_name.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Verify name of API group for gateway +""" +import openstack + +openstack.enable_logging(True) +conn = openstack.connect(cloud='otc') +attrs = { + "group_name": "api_group_002" +} +conn.apig.verify_api_group_name(gateway="gateway_id", **attrs) diff --git a/otcextensions/sdk/apig/v2/_proxy.py b/otcextensions/sdk/apig/v2/_proxy.py index 28203a778..9a5c1bf7d 100644 --- a/otcextensions/sdk/apig/v2/_proxy.py +++ b/otcextensions/sdk/apig/v2/_proxy.py @@ -333,24 +333,76 @@ def environments(self, gateway, **attrs): **attrs) def create_api_group(self, gateway, **attrs): + """Create a new API group for a specific API Gateway. + + This method creates an API group associated with the given API Gateway. + + :param gateway: The ID of the gateway or an instance of + :class:`~otcextensions.sdk.apig.v2.gateway.Gateway` + :param attrs: Additional attributes for creating the API group. + + :returns: An instance of + :class:`~otcextensions.sdk.apig.v2.api_group.ApiGroup` + """ gateway = self._get_resource(_gateway.Gateway, gateway) return self._create(_api_group.ApiGroup, gateway_id=gateway.id, **attrs) def update_api_group(self, gateway, api_group, **attrs): + """Update an existing API group for a specific API Gateway. + + This method updates the attributes of an API group associated with + the given API Gateway. + + :param gateway: The ID of the gateway or an instance of + :class:`~otcextensions.sdk.apig.v2.gateway.Gateway` + :param api_group: The ID of the API group or an instance of + :class:`~otcextensions.sdk.apig.v2.api_group.ApiGroup` + :param attrs: Additional attributes for updating the API group. + + :returns: The updated instance of + :class:`~otcextensions.sdk.apig.v2.api_group.ApiGroup` + """ gateway = self._get_resource(_gateway.Gateway, gateway) api_group = self._get_resource(_api_group.ApiGroup, api_group) return api_group._update_group(self, gateway=gateway, **attrs) - def delete_api_group(self, gateway, api_group): + def delete_api_group(self, gateway, api_group, **attrs): + """Delete an API group from a specific API Gateway. + + This method deletes the specified API group associated with + the given API Gateway. + + :param gateway: The ID of the gateway or an instance of + :class:`~otcextensions.sdk.apig.v2.gateway.Gateway` + :param api_group: The ID of the API group or an instance of + :class:`~otcextensions.sdk.apig.v2.api_group.ApiGroup` + :param attrs: Additional parameters for deleting the API group. + + :returns: None + """ gateway = self._get_resource(_gateway.Gateway, gateway) api_group = self._get_resource(_api_group.ApiGroup, api_group) return self._delete(_api_group.ApiGroup, api_group, - gateway_id=gateway.id) + gateway_id=gateway.id, + **attrs) def get_api_group(self, gateway, api_group): + """Retrieve details of a specific API group. + + This method retrieves the details of an API group associated + with the given API Gateway. + + :param gateway: The ID of the gateway or an instance of + :class:`~otcextensions.sdk.apig.v2.gateway.Gateway` + :param api_group: The ID of the API group or an instance of + :class:`~otcextensions.sdk.apig.v2.api_group.ApiGroup` + + :returns: An instance of + :class:`~otcextensions.sdk.apig.v2.api_group.ApiGroup` + """ gateway = self._get_resource(_gateway.Gateway, gateway) return self._get(_api_group.ApiGroup, api_group, @@ -365,5 +417,5 @@ def api_groups(self, gateway, **attrs): def verify_api_group_name(self, gateway, **attrs): gateway = self._get_resource(_gateway.Gateway, gateway) - api_group = _api_group.ApiGroup(gateway_id=gateway.id) + api_group = _api_group.ApiGroup() return api_group._verify_name(self, gateway=gateway, **attrs) diff --git a/otcextensions/sdk/apig/v2/apigroup.py b/otcextensions/sdk/apig/v2/apigroup.py index 641cdd92e..442fdfc78 100644 --- a/otcextensions/sdk/apig/v2/apigroup.py +++ b/otcextensions/sdk/apig/v2/apigroup.py @@ -12,6 +12,7 @@ from openstack import resource from openstack import exceptions + class UrlDomainSpec(resource.Resource): id = resource.Body('id') domain = resource.Body('domain') @@ -45,7 +46,6 @@ class ApiGroup(resource.Resource): roma_app_id = resource.Body('roma_app_id') version = resource.Body('version') - id = resource.Body('id') status = resource.Body('status') sl_domain = resource.Body('sl_domain') @@ -70,8 +70,7 @@ def _verify_name(self, session, gateway, **attrs): uri = f'/apigw/instances/{gateway.id}/api-groups/check' response = session.post(uri, json=attrs) exceptions.raise_from_response(response) - self._translate_response(response) - return self + return None def _update_group(self, session, gateway, **attrs): """Update API group. diff --git a/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py b/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py index c057814e9..71deb8c2e 100644 --- a/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py +++ b/otcextensions/tests/functional/sdk/apig/v2/test_api_group.py @@ -52,12 +52,12 @@ def test_04_list_api_group(self): groups = list(self.client.api_groups(gateway=TestApiG.gateway)) self.assertGreater(len(groups), 1) - def test_05_verify_api_group(self): attrs = { - "group_name" : "api_group_001" + "group_name": "api_group_002" } - result = self.client.verify_api_group_name(gateway=TestApiG.gateway) + self.client.verify_api_group_name(gateway=TestApiG.gateway, + **attrs) def test_06_delete_api_group(self): self.client.delete_api_group(gateway=TestApiG.gateway, diff --git a/otcextensions/tests/unit/sdk/apig/v2/test_api_group.py b/otcextensions/tests/unit/sdk/apig/v2/test_api_group.py new file mode 100644 index 000000000..40177f529 --- /dev/null +++ b/otcextensions/tests/unit/sdk/apig/v2/test_api_group.py @@ -0,0 +1,112 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from openstack.tests.unit import base +from otcextensions.sdk.apig.v2 import apigroup + + +EXAMPLE_API_GROUP = { + 'id': 'group-12345', + 'gateway_id': 'gateway-67890', + 'name': 'Test API Group', + 'remark': 'This is a test API group', + 'roma_app_id': 'app-54321', + 'version': 'v1', + 'status': 1, + 'sl_domain': 'api.example.com', + 'register_time': '2025-02-07T12:00:00Z', + 'update_time': '2025-02-07T12:30:00Z', + 'on_sell_status': 1, + 'url_domains': [ + { + 'id': 'domain-1', + 'domain': 'example.com', + 'cname_status': 1, + 'ssl_id': 'ssl-123', + 'ssl_name': 'SSL Cert', + 'min_ssl_version': 'TLSv1.2', + 'verified_client_certificate_enabled': True, + 'is_has_trusted_root_ca': False + } + ], + 'sl_domain_access_enabled': True, + 'sl_domains': ['sl1.example.com', 'sl2.example.com'], + 'call_limits': 1000, + 'time_interval': 60, + 'time_unit': 'second', + 'is_default': False, + 'roma_app_name': 'Test App' +} + + +class TestApiGroup(base.TestCase): + + def test_basic(self): + sot = apigroup.ApiGroup() + self.assertEqual('/apigw/instances/%(gateway_id)s/api-groups', + sot.base_path) + self.assertTrue(sot.allow_list) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_commit) + self.assertTrue(sot.allow_delete) + self.assertTrue(sot.allow_fetch) + self.assertEqual('groups', sot.resources_key) + + def test_make_it(self): + sot = apigroup.ApiGroup(**EXAMPLE_API_GROUP) + self.assertEqual(EXAMPLE_API_GROUP['id'], sot.id) + self.assertEqual(EXAMPLE_API_GROUP['gateway_id'], sot.gateway_id) + self.assertEqual(EXAMPLE_API_GROUP['name'], sot.name) + self.assertEqual(EXAMPLE_API_GROUP['remark'], sot.remark) + self.assertEqual(EXAMPLE_API_GROUP['roma_app_id'], sot.roma_app_id) + self.assertEqual(EXAMPLE_API_GROUP['version'], sot.version) + self.assertEqual(EXAMPLE_API_GROUP['status'], sot.status) + self.assertEqual(EXAMPLE_API_GROUP['sl_domain'], sot.sl_domain) + self.assertEqual(EXAMPLE_API_GROUP['register_time'], sot.register_time) + self.assertEqual(EXAMPLE_API_GROUP['update_time'], sot.update_time) + self.assertEqual(EXAMPLE_API_GROUP['on_sell_status'], + sot.on_sell_status) + self.assertEqual(EXAMPLE_API_GROUP['sl_domain_access_enabled'], + sot.sl_domain_access_enabled) + self.assertEqual(EXAMPLE_API_GROUP['sl_domains'], sot.sl_domains) + self.assertEqual(EXAMPLE_API_GROUP['call_limits'], sot.call_limits) + self.assertEqual(EXAMPLE_API_GROUP['time_interval'], sot.time_interval) + self.assertEqual(EXAMPLE_API_GROUP['time_unit'], sot.time_unit) + self.assertEqual(EXAMPLE_API_GROUP['is_default'], sot.is_default) + self.assertEqual(EXAMPLE_API_GROUP['roma_app_name'], sot.roma_app_name) + + self.assertEqual(len(EXAMPLE_API_GROUP['url_domains']), + len(sot.url_domains)) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['id'], + sot.url_domains[0].id) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['domain'], + sot.url_domains[0].domain) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['cname_status'], + sot.url_domains[0].cname_status) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['ssl_id'], + sot.url_domains[0].ssl_id) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['ssl_name'], + sot.url_domains[0].ssl_name) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['min_ssl_version'], + sot.url_domains[0].min_ssl_version) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0] + ['verified_client_certificate_enabled'], + sot.url_domains[0].verified_client_certificate_enabled) + self.assertEqual( + EXAMPLE_API_GROUP['url_domains'][0]['is_has_trusted_root_ca'], + sot.url_domains[0].is_has_trusted_root_ca) diff --git a/otcextensions/tests/unit/sdk/apig/v2/test_proxy.py b/otcextensions/tests/unit/sdk/apig/v2/test_proxy.py index db7c6a525..184dfda3f 100644 --- a/otcextensions/tests/unit/sdk/apig/v2/test_proxy.py +++ b/otcextensions/tests/unit/sdk/apig/v2/test_proxy.py @@ -13,6 +13,7 @@ from otcextensions.sdk.apig.v2 import gateway as _gateway from otcextensions.sdk.apig.v2 import az as _az from otcextensions.sdk.apig.v2 import apienvironment as _env +from otcextensions.sdk.apig.v2 import apigroup as _api_group from openstack.tests.unit import test_proxy_base from unittest import mock @@ -200,3 +201,66 @@ def test_list_envs(self): expected_args=[], expected_kwargs={'gateway_id': None} ) + + def test_create_api_group(self): + gateway = _gateway.Gateway() + self.verify_create(self.proxy.create_api_group, + _api_group.ApiGroup, + method_args=[gateway], + expected_args=[], + method_kwargs={}, + expected_kwargs={'gateway_id': None} + ) + + def test_update_api_group(self): + gateway = _gateway.Gateway() + api_group = _api_group.ApiGroup() + self._verify( + 'otcextensions.sdk.apig.v2.apigroup.' + 'ApiGroup._update_group', + self.proxy.update_api_group, + method_args=[gateway, api_group], + expected_args=[self.proxy], + expected_kwargs={'gateway': gateway} + ) + + def test_delete_api_group(self): + gateway = _gateway.Gateway() + api_group = _api_group.ApiGroup() + self.verify_delete(self.proxy.delete_api_group, + _api_group.ApiGroup, + method_args=[gateway, api_group], + expected_args=[gateway], + method_kwargs={}, + expected_kwargs={'gateway_id': None} + ) + + def test_list_api_groups(self): + gateway = _gateway.Gateway() + self.verify_list(self.proxy.api_groups, + _api_group.ApiGroup, + method_args=[gateway], + expected_args=[], + expected_kwargs={'gateway_id': None} + ) + + def test_get_api_group(self): + gateway = _gateway.Gateway() + api_group = _api_group.ApiGroup() + self.verify_get(self.proxy.get_api_group, + _api_group.ApiGroup, + method_args=[gateway, api_group], + expected_args=[api_group], + expected_kwargs={'gateway_id': None} + ) + + def test_verify_name(self): + gateway = _gateway.Gateway() + self._verify( + 'otcextensions.sdk.apig.v2.apigroup.' + 'ApiGroup._verify_name', + self.proxy.verify_api_group_name, + method_args=[gateway], + expected_args=[self.proxy], + expected_kwargs={'gateway': gateway} + ) diff --git a/releasenotes/notes/apig-group-management-9416e9bfeaf5e9b3.yaml b/releasenotes/notes/apig-group-management-9416e9bfeaf5e9b3.yaml new file mode 100644 index 000000000..9fcba49dc --- /dev/null +++ b/releasenotes/notes/apig-group-management-9416e9bfeaf5e9b3.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Add API group management support for API Gateway