diff --git a/otcextensions/sdk/__init__.py b/otcextensions/sdk/__init__.py index f9c76b8e2..a02385686 100644 --- a/otcextensions/sdk/__init__.py +++ b/otcextensions/sdk/__init__.py @@ -82,6 +82,9 @@ 'service_type': 'kms', 'append_project_id': True, }, + 'nat': { + 'service_type': 'nat' + }, 'obs': { 'service_type': 'obs', 'require_ak': True, diff --git a/otcextensions/sdk/nat/__init__.py b/otcextensions/sdk/nat/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/otcextensions/sdk/nat/nat_service.py b/otcextensions/sdk/nat/nat_service.py new file mode 100644 index 000000000..d5fbc32f1 --- /dev/null +++ b/otcextensions/sdk/nat/nat_service.py @@ -0,0 +1,22 @@ +# 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 service_description + +from otcextensions.sdk.nat.v2 import _proxy + + +class NatService(service_description.ServiceDescription): + """The NAT service.""" + + supported_versions = { + '2': _proxy.Proxy + } diff --git a/otcextensions/sdk/nat/v2/__init__.py b/otcextensions/sdk/nat/v2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/otcextensions/sdk/nat/v2/_proxy.py b/otcextensions/sdk/nat/v2/_proxy.py new file mode 100644 index 000000000..4df1a1a06 --- /dev/null +++ b/otcextensions/sdk/nat/v2/_proxy.py @@ -0,0 +1,178 @@ +# 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.sdk.nat.v2 import gateway as _gateway +from otcextensions.sdk.nat.v2 import snat as _snat +from otcextensions.sdk.nat.v2 import dnat as _dnat + +from openstack import proxy + + +class Proxy(proxy.Proxy): + + skip_discovery = True + + # ======== Gateway ======== + def create_gateway(self, **attrs): + """Create a new gateway from attributes + + :param dict attrs: Keyword arguments which will be used to create + a :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + """ + return self._create(_gateway.Gateway, **attrs) + + def delete_gateway(self, gateway, ignore_missing=True): + """Delete a gateway + + :param gateway: key id or an instance of + :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised when + the gateway does not exist. + When set to ``True``, no exception will be set when attempting to + delete a nonexistent gateway. + + :returns: Gateway been deleted + :rtype: :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + """ + return self._delete(_gateway.Gateway, gateway, + ignore_missing=ignore_missing) + + def gateways(self, **query): + """Return a generator of gateways + + :param dict query: Optional query parameters to be sent to limit + the resources being returned. + :returns: A generator of gateway objects + :rtype: :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + """ + return self._list(_gateway.Gateway, **query) + + def get_gateway(self, gateway): + """Get a single gateway + + :param gateway: The value can be the ID of a NAT Gatway or a + :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + instance. + + :returns: One :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_gateway.Gateway, gateway) + + def update_gateway(self, gateway, **attrs): + """Update a gateway + + :param gateway: Either the ID of a gateway or a + :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + instance. + :param dict attrs: The attributes to update on the gateway represented + by ``gateway``. + + :returns: The updated gateway + :rtype: :class:`~otcextensions.sdk.nat.v2.gateway.Gateway` + """ + return self._update(_gateway.Gateway, gateway, **attrs) + + # ======== SNAT rules ======== + def create_snat_rule(self, **attrs): + """Create a new SNAT rule from attributes + + :param dict attrs: Keyword arguments which will be used to create + a :class:`~otcextensions.sdk.nat.v2.snat.Snat` + """ + return self._create(_snat.Snat, **attrs) + + def delete_snat_rule(self, snat, ignore_missing=True): + """Delete a SNAT rule + + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised when + the SNAT rule does not exist. + When set to ``True``, no exception will be set when attempting to + delete a nonexistent SNAT rule. + + :returns: SNAT rule been deleted + :rtype: :class:`~otcextensions.sdk.nat.v2.snat.Snat` + """ + return self._delete(_snat.Snat, snat, ignore_missing=ignore_missing) + + def get_snat_rule(self, snat_rule): + """Get a single SNAT rule + + :param snat_rule: The value can be the ID of a SNAT rule or a + :class:`~otcextensions.sdk.nat.v2.snat.Snat` + instance. + + :returns: One :class:`~otcextensions.sdk.nat.v2.snat.Snat` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_snat.Snat, snat_rule) + + def snat_rules(self, **query): + """Return a generator of SNAT rules + + :param dict query: Optional query parameters to be sent to limit + the resources being returned. + :returns: A generator of Snat rule objects + :rtype: :class:`~otcextensions.sdk.nat.v2.snat.Snat` + """ + return self._list(_snat.Snat, **query) + + # ======== DNAT rules ======== + def create_dnat_rule(self, **attrs): + """Create a new DNAT rule from attributes + + :param dict attrs: Keyword arguments which will be used to create + a :class:`~otcextensions.sdk.nat.v2.dnat.Dnat` + """ + return self._create(_dnat.Dnat, **attrs) + + def delete_dnat_rule(self, dnat, ignore_missing=True): + """Delete a DNAT rule + + :param dict attrs: Keyword arguments which will be used to delete + a :class:`~otcextensions.sdk.nat.v2.dnat.Dnat` + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised when + the DNAT rule does not exist. + When set to ``True``, no exception will be set when attempting to + delete a nonexistent DNAT rule. + + :returns: DNAT rule been deleted + :rtype: :class:`~otcextensions.sdk.nat.v2.dnat.Dnat` + """ + return self._delete(_dnat.Dnat, dnat, ignore_missing=ignore_missing) + + def get_dnat_rule(self, dnat_rule): + """Get a single DNAT rule + + :param dnat_rule: The value can be the ID of a DNAT rule or a + :class:`~otcextensions.sdk.nat.v2.dnat.Dnat` + instance. + + :returns: One :class:`~otcextensions.sdk.nat.v2.dnat.Dnat` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_dnat.Dnat, dnat_rule) + + def dnat_rules(self, **query): + """Return a generator of DNAT rules + + :param dict query: Optional query parameters to be sent to limit + the resources being returned. + :returns: A generator of DNAT rules objects + :rtype: :class:`~otcextensions.sdk.nat.v2.dnat.Dnat` + """ + return self._list(_dnat.Dnat, **query) diff --git a/otcextensions/sdk/nat/v2/dnat.py b/otcextensions/sdk/nat/v2/dnat.py new file mode 100644 index 000000000..5c71f7e2c --- /dev/null +++ b/otcextensions/sdk/nat/v2/dnat.py @@ -0,0 +1,69 @@ +# 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 + + +class Dnat(resource.Resource): + resources_key = 'dnat_rules' + resource_key = 'dnat_rule' + base_path = '/dnat_rules' + + # capabilities + allow_create = True + allow_fetch = True + allow_delete = True + allow_list = True + + _query_mapping = resource.QueryParameters( + 'admin_state_up', 'cidr', 'created_at', 'external_service_port', + 'floating_ip_address', 'floating_ip_id', 'id', + 'internal_service_port', 'limit', 'nat_gateway_id', 'network_id', + 'port_id', 'private_id', 'protocol', 'source_type', 'status', + 'project_id' + ) + + # Properties + #: Specifies whether DNAT rule is enabled / disabled + #: *true:* DNAT rule is enabled + #: *false:* DNAT rule is disabled + admin_state_up = resource.Body('admin_state_up', type=bool) + #: Specifies when the rule is created. + #: The format is yyyy-mm-dd hh:mm:ss. + created_at = resource.Body('created_at') + #: Specifies the port for providing external services. + external_service_port = resource.Body('external_service_port', type=int) + #: Specifies the EIP + floating_ip_address = resource.Body('floating_ip_address') + #: Specifies the EIP ID + floating_ip_id = resource.Body('floating_ip_id') + #: Specifies the gateway ID. + gateway_id = resource.Body('gateway_id') + #: Specifies the ID of the DNAT rule. + id = resource.Body('id') + #: Specifies port used by ECS/BMS to provide services for external systems + internal_service_port = resource.Body('internal_service_port', type=int) + #: Specifies the ID of the NAT gateway. + nat_gateway_id = resource.Body('nat_gateway_id') + #: Specifies the port ID of an ECS or BMS + #: Parameter is used in the VPC scenario. + #: This parameter is an alternative to private_ip + port_id = resource.Body('port_id') + #: Specifies the IP address of a Direct Connect connection. + #: Parameter is used in the Direct Connect scenario. + #: This parameter is an alternative to port_id. + private_ip = resource.Body('private_ip') + #: Specifies the project ID. + project_id = resource.Body('tenant_id') + #: Specifies the protocol type. Currently TCP(6), UDP(17) and ANY(0) + protocol = resource.Body('protocol') + #: Specifies the status of the DNAT rule + status = resource.Body('status') diff --git a/otcextensions/sdk/nat/v2/gateway.py b/otcextensions/sdk/nat/v2/gateway.py new file mode 100644 index 000000000..bcacd7f32 --- /dev/null +++ b/otcextensions/sdk/nat/v2/gateway.py @@ -0,0 +1,61 @@ +# 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 + + +class Gateway(resource.Resource): + resources_key = 'nat_gateways' + resource_key = 'nat_gateway' + base_path = '/nat_gateways' + + # capabilities + allow_create = True + allow_fetch = True + allow_commit = True + allow_delete = True + allow_list = True + + _query_mapping = resource.QueryParameters( + 'admin_state_up', 'created_at', 'description', 'id', + 'internal_network_id', 'limit', 'name', 'router_id', + 'spec', 'status', 'project_id' + ) + + # Properties + #: Specifies whether GW is up or down + #: *true:* Gw is up + #: *false:* GW is down + admin_state_up = resource.Body('admin_state_up', type=bool) + #: Specifies when GW was is created + #: format is *yyyy-mm-dd hh:mm:ss* + created_at = resource.Body('created_at') + #: Provides description of gateway + description = resource.Body('description') + #: Specifies the ID of the gateway. + id = resource.Body('id') + #: Specifies the network ID of the downstream interface + internal_network_id = resource.Body('internal_network_id') + #: Specifies the name of the gateway. + #: Contains only digits, letters, underscores and hyphens + name = resource.Body('name') + #: Specifies the project ID + project_id = resource.Body('tenant_id') + #: Specifies the router ID + router_id = resource.Body('router_id') + #: Specifies the type of the gateway. + #: *1:* small type, supports up to 10,000 SNAT connections + #: *2:* medium type, supports up to 50,000 SNAT connections + #: *3:* large type, supports up to 200,000 SNAT connections + #: *4:* extra-large type, supports up to 1,000,000 SNAT connections + spec = resource.Body('spec') + #: Specifies the status + status = resource.Body('status') diff --git a/otcextensions/sdk/nat/v2/snat.py b/otcextensions/sdk/nat/v2/snat.py new file mode 100644 index 000000000..57c75685f --- /dev/null +++ b/otcextensions/sdk/nat/v2/snat.py @@ -0,0 +1,62 @@ +# 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 + + +class Snat(resource.Resource): + resources_key = 'snat_rules' + resource_key = 'snat_rule' + base_path = '/snat_rules' + + # capabilities + allow_create = True + allow_fetch = True + allow_delete = True + allow_list = True + + _query_mapping = resource.QueryParameters( + 'admin_state_up', 'cidr', 'created_at', 'floating_ip_address', + 'floating_ip_id', 'id', 'limit', 'nat_gateway_id', 'network_id', + 'source_type', 'status', 'project_id' + ) + + # Properties + #: Specifies the status of the SNAT rule + admin_state_up = resource.Body('admin_state_up', type=bool) + #: Specifies a subset of the VPC subnet CIDR block or a + #: CIDR block of Direct Connect connection. + cidr = resource.Body('cidr') + #: Specifies when the rule is created. + #: The format is yyyy-mm-dd hh:mm:ss. + created_at = resource.Body('created_at') + #: Specifies the EIP + #: Multiple EIPs are separated using commas + floating_ip_address = resource.Body('floating_ip_address') + #: Specifies the EIP ID + #: Multiple EIPs are separated using commas + floating_ip_id = resource.Body('floating_ip_id') + #: Specifies the ID of the SNAT rule. + id = resource.Body('id') + #: Specifies the gateway ID. + nat_gateway_id = resource.Body('nat_gateway_id') + #: Specifies the network ID + network_id = resource.Body('network_id') + #: Specifies the project ID. + project_id = resource.Body('tenant_id') + #: *0:* Either network_id or cidr can be specified in VPC + #: *1:* only cidr can be specified over a Direct Connect connection + #: Default: 0 + source_type = resource.Body('source_type', type=int) + #: Specifies whether SNAT rule is enabled / disabled + #: *true:* SNAT rule is enabled + #: *false:* SNAT rule is disabled + status = resource.Body('status') diff --git a/otcextensions/tests/unit/sdk/nat/__init__.py b/otcextensions/tests/unit/sdk/nat/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/otcextensions/tests/unit/sdk/nat/v2/test_dnat.py b/otcextensions/tests/unit/sdk/nat/v2/test_dnat.py new file mode 100644 index 000000000..655773526 --- /dev/null +++ b/otcextensions/tests/unit/sdk/nat/v2/test_dnat.py @@ -0,0 +1,67 @@ +# 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.nat.v2 import dnat + + +INSTANCE_ID = '5b95c675-69c2-4656-ba06-58ff72e1d338' +EXAMPLE = { + 'floating_ip_id': 'bdc10a4c-d81a-41ec-adf7-de857f7c812a', + 'status': 'ACTIVE', + 'nat_gateway_id': 'a78fb3eb-1654-4710-8742-3fc49d5f04f8', + 'admin_state_up': True, + 'port_id': '9a469561-daac-4c94-88f5-39366e5ea193', + 'internal_service_port': 993, + 'protocol': 'TCP', + 'project_id': '27e25061336f4af590faeabeb7fcd9a3', + 'created_at': '2017-11-18 07:54:21.665430', + 'id': INSTANCE_ID, + 'floating_ip_address': '5.21.11.226', + 'external_service_port': 242, + 'private_ip': "", +} + + +class TestDnat(base.TestCase): + + def test_basic(self): + sot = dnat.Dnat() + self.assertEqual('dnat_rule', sot.resource_key) + self.assertEqual('dnat_rules', sot.resources_key) + path = '/dnat_rules' + self.assertEqual(path, sot.base_path) + self.assertTrue(sot.allow_list) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertFalse(sot.allow_commit) + self.assertTrue(sot.allow_delete) + + def test_make_it(self): + sot = dnat.Dnat(**EXAMPLE) + self.assertEqual(EXAMPLE['floating_ip_id'], sot.floating_ip_id) + self.assertEqual(EXAMPLE['status'], sot.status) + self.assertEqual(EXAMPLE['nat_gateway_id'], sot.nat_gateway_id) + self.assertEqual(EXAMPLE['admin_state_up'], sot.admin_state_up) + self.assertEqual(EXAMPLE['port_id'], sot.port_id) + self.assertEqual(EXAMPLE['internal_service_port'], + sot.internal_service_port) + self.assertEqual(EXAMPLE['protocol'], sot.protocol) + self.assertEqual(EXAMPLE['project_id'], sot.project_id) + self.assertEqual(EXAMPLE['created_at'], sot.created_at) + self.assertEqual(EXAMPLE['id'], sot.id) + self.assertEqual(EXAMPLE['floating_ip_address'], + sot.floating_ip_address) + self.assertEqual(EXAMPLE['external_service_port'], + sot.external_service_port) + self.assertEqual(EXAMPLE['private_ip'], sot.private_ip) diff --git a/otcextensions/tests/unit/sdk/nat/v2/test_gateway.py b/otcextensions/tests/unit/sdk/nat/v2/test_gateway.py new file mode 100644 index 000000000..327231eae --- /dev/null +++ b/otcextensions/tests/unit/sdk/nat/v2/test_gateway.py @@ -0,0 +1,60 @@ +# 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.nat.v2 import gateway + + +INSTANCE_NAME = 'GATEWAYNAME' +INSTANCE_ID = 'a78fb3eb-1654-4710-8742-3fc49d5f04f8' +EXAMPLE = { + 'router_id': 'd84f345c-80a1-4fa2-a39c-d0d397c3f09a', + 'status': 'PENDING_CREATE', + 'description': 'Test Gateway Response', + 'admin_state_up': True, + 'project_id': '27e25061336f4af590faeabeb7fcd9a3', + 'created_at': '2017-11-18 07:34:32.203044', + 'spec': '2', + 'internal_network_id': '89d66639-aacb-4929-969d-07080b0f9fd9', + 'id': INSTANCE_ID, + 'name': INSTANCE_NAME +} + + +class TestGateway(base.TestCase): + + def test_basic(self): + sot = gateway.Gateway() + self.assertEqual('nat_gateway', sot.resource_key) + self.assertEqual('nat_gateways', sot.resources_key) + path = '/nat_gateways' + self.assertEqual(path, sot.base_path) + self.assertTrue(sot.allow_list) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertTrue(sot.allow_commit) + self.assertTrue(sot.allow_delete) + + def test_make_it(self): + sot = gateway.Gateway(**EXAMPLE) + self.assertEqual(EXAMPLE['router_id'], sot.router_id) + self.assertEqual(EXAMPLE['status'], sot.status) + self.assertEqual(EXAMPLE['description'], sot.description) + self.assertEqual(EXAMPLE['admin_state_up'], sot.admin_state_up) + self.assertEqual(EXAMPLE['project_id'], sot.project_id) + self.assertEqual(EXAMPLE['created_at'], sot.created_at) + self.assertEqual(EXAMPLE['spec'], sot.spec) + self.assertEqual(EXAMPLE['internal_network_id'], + sot.internal_network_id) + self.assertEqual(EXAMPLE['id'], sot.id) + self.assertEqual(EXAMPLE['name'], sot.name) diff --git a/otcextensions/tests/unit/sdk/nat/v2/test_proxy.py b/otcextensions/tests/unit/sdk/nat/v2/test_proxy.py new file mode 100644 index 000000000..9f5140483 --- /dev/null +++ b/otcextensions/tests/unit/sdk/nat/v2/test_proxy.py @@ -0,0 +1,90 @@ +# 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. + +# 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.sdk.nat.v2 import _proxy +from otcextensions.sdk.nat.v2 import snat +from otcextensions.sdk.nat.v2 import dnat +from otcextensions.sdk.nat.v2 import gateway + +from openstack.tests.unit import test_proxy_base + + +class TestNatProxy(test_proxy_base.TestProxyBase): + def setUp(self): + super(TestNatProxy, self).setUp() + self.proxy = _proxy.Proxy(self.session) + + +class TestNatGateway(TestNatProxy): + def test_gateway_create(self): + self.verify_create(self.proxy.create_gateway, gateway.Gateway, + method_kwargs={'name': 'id'}, + expected_kwargs={'name': 'id'}) + + def test_gateway_delete(self): + self.verify_delete(self.proxy.delete_gateway, + gateway.Gateway, True) + + def test_gateway_get(self): + self.verify_get(self.proxy.get_gateway, gateway.Gateway) + + def test_gateways(self): + self.verify_list(self.proxy.gateways, gateway.Gateway) + + def test_gateway_update(self): + self.verify_update(self.proxy.update_gateway, gateway.Gateway) + + +class TestNatSnatRule(TestNatProxy): + def test_snat_rule_create(self): + self.verify_create(self.proxy.create_snat_rule, snat.Snat, + method_kwargs={'name': 'id'}, + expected_kwargs={'name': 'id'}) + + def test_snat_rule_delete(self): + self.verify_delete(self.proxy.delete_snat_rule, + snat.Snat, True) + + def test_snat_rule_get(self): + self.verify_get(self.proxy.get_snat_rule, snat.Snat) + + def test_snat_rules(self): + self.verify_list(self.proxy.snat_rules, snat.Snat) + + +class TestNatDnatRule(TestNatProxy): + def test_dnat_rule_create(self): + self.verify_create(self.proxy.create_dnat_rule, dnat.Dnat, + method_kwargs={'name': 'id'}, + expected_kwargs={'name': 'id'}) + + def test_dnat_rule_delete(self): + self.verify_delete(self.proxy.delete_dnat_rule, + dnat.Dnat, True) + + def test_dnat_rule_get(self): + self.verify_get(self.proxy.get_dnat_rule, dnat.Dnat) + + def test_dnat_rules(self): + self.verify_list(self.proxy.dnat_rules, dnat.Dnat) diff --git a/otcextensions/tests/unit/sdk/nat/v2/test_snat.py b/otcextensions/tests/unit/sdk/nat/v2/test_snat.py new file mode 100644 index 000000000..21cf7ee60 --- /dev/null +++ b/otcextensions/tests/unit/sdk/nat/v2/test_snat.py @@ -0,0 +1,61 @@ +# 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.nat.v2 import snat + + +INSTANCE_ID = '5b95c675-69c2-4656-ba06-58ff72e1d338' +EXAMPLE = { + 'floating_ip_id': 'bdc10a4c-d81a-41ec-adf7-de857f7c812a', + 'status': 'PENDING_CREATE', + 'nat_gateway_id': 'a78fb3eb-1654-4710-8742-3fc49d5f04f8', + 'admin_state_up': True, + 'network_id': 'eaad9cd6-2372-4be1-9535-9bd37210ae7b', + 'cidr': None, + 'source_type': 0, + 'project_id': '27e25061336f4af590faeabeb7fcd9a3', + 'created_at': '2017-11-18 07:54:21.665430', + 'id': INSTANCE_ID, + 'floating_ip_address': '5.21.11.226' +} + + +class TestSnat(base.TestCase): + + def test_basic(self): + sot = snat.Snat() + self.assertEqual('snat_rule', sot.resource_key) + self.assertEqual('snat_rules', sot.resources_key) + path = '/snat_rules' + self.assertEqual(path, sot.base_path) + self.assertTrue(sot.allow_list) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertFalse(sot.allow_commit) + self.assertTrue(sot.allow_delete) + + def test_make_it(self): + sot = snat.Snat(**EXAMPLE) + self.assertEqual(EXAMPLE['floating_ip_id'], sot.floating_ip_id) + self.assertEqual(EXAMPLE['status'], sot.status) + self.assertEqual(EXAMPLE['nat_gateway_id'], sot.nat_gateway_id) + self.assertEqual(EXAMPLE['admin_state_up'], sot.admin_state_up) + self.assertEqual(EXAMPLE['network_id'], sot.network_id) + self.assertIsNone(sot.cidr) + self.assertEqual(EXAMPLE['source_type'], sot.source_type) + self.assertEqual(EXAMPLE['project_id'], sot.project_id) + self.assertEqual(EXAMPLE['created_at'], sot.created_at) + self.assertEqual(EXAMPLE['id'], sot.id) + self.assertEqual(EXAMPLE['floating_ip_address'], + sot.floating_ip_address)