From 40cc84d53d8ddf2af333845d12bef9fc7a65c447 Mon Sep 17 00:00:00 2001 From: Polina Gubina Date: Thu, 13 May 2021 15:07:32 +0300 Subject: [PATCH] Add IPsecSiteConnection resource and proxy layer functionality for it Change-Id: I04b017f483f07e041cc429706cd92a39900d5eb6 --- doc/source/user/proxies/network.rst | 9 ++ doc/source/user/resources/network/index.rst | 1 + .../network/v2/ipsec_site_connection.rst | 13 +++ openstack/network/v2/_proxy.py | 96 ++++++++++++++++ openstack/network/v2/ipsec_site_connection.py | 105 ++++++++++++++++++ .../network/v2/test_ipsec_site_connection.py | 80 +++++++++++++ openstack/tests/unit/network/v2/test_proxy.py | 29 +++++ 7 files changed, 333 insertions(+) create mode 100644 doc/source/user/resources/network/v2/ipsec_site_connection.rst create mode 100644 openstack/network/v2/ipsec_site_connection.py create mode 100644 openstack/tests/unit/network/v2/test_ipsec_site_connection.py diff --git a/doc/source/user/proxies/network.rst b/doc/source/user/proxies/network.rst index d8eb64e51..3c5f76a76 100644 --- a/doc/source/user/proxies/network.rst +++ b/doc/source/user/proxies/network.rst @@ -234,6 +234,15 @@ VPN Operations :members: create_vpn_service, update_vpn_service, delete_vpn_service, get_vpn_service, find_vpn_service, vpn_services +IPSecSiteConnection Operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: openstack.network.v2._proxy.Proxy + :noindex: + :members: create_vpn_ipsec_site_connection, update_vpn_ipsec_site_connection, + delete_vpn_ipsec_site_connection, get_vpn_ipsec_site_connection, + find_vpn_ipsec_site_connection, vpn_ipsec_site_connections + Extension Operations ^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/user/resources/network/index.rst b/doc/source/user/resources/network/index.rst index 3884de78e..75fb5d928 100644 --- a/doc/source/user/resources/network/index.rst +++ b/doc/source/user/resources/network/index.rst @@ -13,6 +13,7 @@ Network Resources v2/flavor v2/floating_ip v2/health_monitor + v2/ipsec_site_connection v2/listener v2/load_balancer v2/metering_label diff --git a/doc/source/user/resources/network/v2/ipsec_site_connection.rst b/doc/source/user/resources/network/v2/ipsec_site_connection.rst new file mode 100644 index 000000000..3750344e7 --- /dev/null +++ b/doc/source/user/resources/network/v2/ipsec_site_connection.rst @@ -0,0 +1,13 @@ +openstack.network.v2.ipsec_site_connection +========================================== + +.. automodule:: openstack.network.v2.ipsec_site_connection + +The IPSecSiteConnection Class +----------------------------- + +The ``IPSecSiteConnection`` class inherits from +:class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.network.v2.ipsec_site_connection.IPSecSiteConnection + :members: diff --git a/openstack/network/v2/_proxy.py b/openstack/network/v2/_proxy.py index 8d2fecdc9..ac9d735d4 100644 --- a/openstack/network/v2/_proxy.py +++ b/openstack/network/v2/_proxy.py @@ -24,6 +24,8 @@ from openstack.network.v2 import firewall_rule as _firewall_rule from openstack.network.v2 import flavor as _flavor from openstack.network.v2 import floating_ip as _floating_ip from openstack.network.v2 import health_monitor as _health_monitor +from openstack.network.v2 import ipsec_site_connection as \ + _ipsec_site_connection from openstack.network.v2 import l3_conntrack_helper as _l3_conntrack_helper from openstack.network.v2 import listener as _listener from openstack.network.v2 import load_balancer as _load_balancer @@ -951,6 +953,100 @@ class Proxy(proxy.Proxy): return self._update(_health_monitor.HealthMonitor, health_monitor, **attrs) + def create_vpn_ipsec_site_connection(self, **attrs): + """Create a new ipsec site connection from attributes + + :param dict attrs: Keyword arguments which will be used to create a + :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection`, comprised of the properties on the + IPSecSiteConnection class. + + :returns: The results of ipsec site connection creation :rtype: + :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection` + """ + return self._create(_ipsec_site_connection.IPSecSiteConnection, + **attrs) + + def find_vpn_ipsec_site_connection(self, name_or_id, + ignore_missing=True, **args): + """Find a single ipsec site connection + + :param name_or_id: The name or ID of an ipsec site connection. + :param bool ignore_missing: When set to ``False`` :class:`~openstack. + exceptions.ResourceNotFound` will be raised when the resource does + not exist.When set to ``True``, None will be returned when + attempting to find a nonexistent resource. + :param dict args: Any additional parameters to be passed into + underlying methods such as query filters. + :returns: One :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection` or None + """ + return self._find(_ipsec_site_connection.IPSecSiteConnection, + name_or_id, ignore_missing=ignore_missing, **args) + + def get_vpn_ipsec_site_connection(self, ipsec_site_connection): + """Get a single ipsec site connection + + :param ipsec_site_connection: The value can be the ID of an ipsec site + connection or a :class:`~openstack.network.v2. + ipsec_site_connection.IPSecSiteConnection` instance. + + :returns: One :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_ipsec_site_connection.IPSecSiteConnection, + ipsec_site_connection) + + def vpn_ipsec_site_connections(self, **query): + """Return a generator of ipsec site connections + + :param dict query: Optional query parameters to be sent to limit the + resources being returned. + + :returns: A generator of ipsec site connection objects + :rtype: :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection` + """ + return self._list(_ipsec_site_connection.IPSecSiteConnection, **query) + + def update_vpn_ipsec_site_connection(self, ipsec_site_connection, **attrs): + """Update a ipsec site connection + + :ipsec_site_connection: Either the id of an ipsec site connection or + a :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection` instance. + :param dict attrs: The attributes to update on the ipsec site + connection represented by ``ipsec_site_connection``. + + :returns: The updated ipsec site connection + :rtype: :class:`~openstack.network.v2.ipsec_site_connection. + IPSecSiteConnection` + """ + return self._update(_ipsec_site_connection.IPSecSiteConnection, + ipsec_site_connection, **attrs) + + def delete_vpn_ipsec_site_connection(self, ipsec_site_connection, + ignore_missing=True): + """Delete a ipsec site connection + + :param ipsec_site_connection: The value can be either the ID of an + ipsec site connection, or a :class:`~openstack.network.v2. + ipsec_site_connection.IPSecSiteConnection` instance. + :param bool ignore_missing: + When set to ``False`` :class:`~openstack.exceptions. + ResourceNotFound` will be raised when the ipsec site connection + does not exist. + When set to ``True``, no exception will be set when attempting to + delete a nonexistent ipsec site connection. + + :returns: ``None`` + """ + self._delete(_ipsec_site_connection.IPSecSiteConnection, + ipsec_site_connection, ignore_missing=ignore_missing) + def create_listener(self, **attrs): """Create a new listener from attributes diff --git a/openstack/network/v2/ipsec_site_connection.py b/openstack/network/v2/ipsec_site_connection.py new file mode 100644 index 000000000..1b2aa29e6 --- /dev/null +++ b/openstack/network/v2/ipsec_site_connection.py @@ -0,0 +1,105 @@ +# 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 IPSecSiteConnection(resource.Resource): + resource_key = 'ipsec_site_connection' + resources_key = 'ipsec_site_connections' + base_path = '/vpn/ipsec-site-connections' + + # capabilities + allow_create = True + allow_fetch = True + allow_commit = True + allow_delete = True + allow_list = True + + # Properties + #: The dead peer detection (DPD) action. + # A valid value is clear, hold, restart, + # disabled, or restart-by-peer. Default value is hold. + action = resource.Body('action') + #: The authentication mode. A valid value + # is psk, which is the default. + auth_mode = resource.Body('auth_mode') + #: A human-readable description for the resource. + # Default is an empty string. + description = resource.Body('description') + #: A dictionary with dead peer detection (DPD) protocol controls. + dpd = resource.Body('dpd', type=dict) + #: The administrative state of the resource, + # which is up (true) or down (false). + is_admin_state_up = resource.Body('admin_state_up', type=bool) + #: The ID of the IKE policy. + ikepolicy_id = resource.Body('ikepolicy_id') + #: Indicates whether this VPN can only respond + # to connections or both respond + # to and initiate connections. A valid value is + # response- only or bi-directional. Default is bi-directional. + initiator = resource.Body('initiator') + #: The ID of the IPsec policy. + ipsecpolicy_id = resource.Body('ipsecpolicy_id') + #: The dead peer detection (DPD) interval, in seconds. + # A valid value is a positive integer. Default is 30. + interval = resource.Body('interval', type=int) + #: The ID for the endpoint group that contains + # private subnets for the local side of the connection. + # Yo must specify this parameter with the + # peer_ep_group_id parameter unless in backward- compatible + # mode where peer_cidrs is provided with + # a subnet_id for the VPN service. + local_ep_group_id = resource.Body('local_ep_group_id') + #: The peer gateway public IPv4 or IPv6 address or FQDN. + peer_address = resource.Body('peer_address') + #: An ID to be used instead of the external IP address for + # a virtual router used in traffic between + # instances on different networks in east-west traffic. + # Most often, local ID would be domain + # name, email address, etc. If this is not configured + # then the external IP address will be used as the ID. + local_id = resource.Body('local_id') + #: The maximum transmission unit (MTU) + # value to address fragmentation. Minimum value + # is 68 for IPv4, and 1280 for IPv6. + mtu = resource.Body('mtu', type=int) + #: Human-readable name of the resource. Default is an empty string. + name = resource.Body('name') + #: The peer router identity for authentication. + # A valid value is an IPv4 address, IPv6 address, e-mail address, + # key ID, or FQDN. Typically, this value matches + # the peer_address value. + peer_id = resource.Body('peer_id') + #: (Deprecated) Unique list of valid peer private + # CIDRs in the form < net_address > / < prefix > . + peer_cidrs = resource.Body('peer_cidrs', type=list) + #: The ID of the project. + project_id = resource.Body('tenant_id') + #: The pre-shared key. A valid value is any string. + psk = resource.Body('psk') + #: The ID for the endpoint group that contains + # private CIDRs in the form < net_address > / < prefix > + # for the peer side of the connection. You must + # specify this parameter with the local_ep_group_id + # parameter unless in backward-compatible mode + # where peer_cidrs is provided with a subnet_id for the VPN service. + peer_ep_group_id = resource.Body('peer_ep_group_id') + #: The route mode. A valid value is static, which is the default. + route_mode = resource.Body('route_mode') + #: The dead peer detection (DPD) timeout + # in seconds. A valid value is a + # positive integer that is greater + # than the DPD interval value. Default is 120. + timeout = resource.Body('timeout', type=int) + #: The ID of the VPN service. + vpnservice_id = resource.Body('vpnservice_id') diff --git a/openstack/tests/unit/network/v2/test_ipsec_site_connection.py b/openstack/tests/unit/network/v2/test_ipsec_site_connection.py new file mode 100644 index 000000000..bee693bf6 --- /dev/null +++ b/openstack/tests/unit/network/v2/test_ipsec_site_connection.py @@ -0,0 +1,80 @@ +# 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.network.v2 import ipsec_site_connection +from openstack.tests.unit import base + + +IDENTIFIER = 'IDENTIFIER' +EXAMPLE = { + "admin_state_up": True, + "auth_mode": "1", + "ikepolicy_id": "2", + "vpnservice_id": "3", + "local_ep_group_id": "4", + "peer_address": "5", + "route_mode": "6", + "ipsecpolicy_id": "7", + "peer_id": "8", + "psk": "9", + "description": "10", + "initiator": "11", + "peer_cidrs": ['1', '2'], + "name": "12", + "tenant_id": "13", + "interval": 5, + "mtu": 5, + "peer_ep_group_id": "14", + "dpd": {'a': 5}, + "timeout": 16, + "action": "17", + "local_id": "18" +} + + +class TestIPSecSiteConnection(base.TestCase): + + def test_basic(self): + sot = ipsec_site_connection.IPSecSiteConnection() + self.assertEqual('ipsec_site_connection', sot.resource_key) + self.assertEqual('ipsec_site_connections', sot.resources_key) + self.assertEqual('/vpn/ipsec-site-connections', sot.base_path) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertTrue(sot.allow_commit) + self.assertTrue(sot.allow_delete) + self.assertTrue(sot.allow_list) + + def test_make_it(self): + sot = ipsec_site_connection.IPSecSiteConnection(**EXAMPLE) + self.assertTrue(sot.is_admin_state_up) + self.assertEqual(EXAMPLE['auth_mode'], sot.auth_mode) + self.assertEqual(EXAMPLE['ikepolicy_id'], sot.ikepolicy_id) + self.assertEqual(EXAMPLE['vpnservice_id'], sot.vpnservice_id) + self.assertEqual(EXAMPLE['local_ep_group_id'], sot.local_ep_group_id) + self.assertEqual(EXAMPLE['peer_address'], sot.peer_address) + self.assertEqual(EXAMPLE['route_mode'], sot.route_mode) + self.assertEqual(EXAMPLE['ipsecpolicy_id'], sot.ipsecpolicy_id) + self.assertEqual(EXAMPLE['peer_id'], sot.peer_id) + self.assertEqual(EXAMPLE['psk'], sot.psk) + self.assertEqual(EXAMPLE['description'], sot.description) + self.assertEqual(EXAMPLE['initiator'], sot.initiator) + self.assertEqual(EXAMPLE['peer_cidrs'], sot.peer_cidrs) + self.assertEqual(EXAMPLE['name'], sot.name) + self.assertEqual(EXAMPLE['tenant_id'], sot.project_id) + self.assertEqual(EXAMPLE['interval'], sot.interval) + self.assertEqual(EXAMPLE['mtu'], sot.mtu) + self.assertEqual(EXAMPLE['peer_ep_group_id'], sot.peer_ep_group_id) + self.assertEqual(EXAMPLE['dpd'], sot.dpd) + self.assertEqual(EXAMPLE['timeout'], sot.timeout) + self.assertEqual(EXAMPLE['action'], sot.action) + self.assertEqual(EXAMPLE['local_id'], sot.local_id) diff --git a/openstack/tests/unit/network/v2/test_proxy.py b/openstack/tests/unit/network/v2/test_proxy.py index 9772d995b..369467b81 100644 --- a/openstack/tests/unit/network/v2/test_proxy.py +++ b/openstack/tests/unit/network/v2/test_proxy.py @@ -26,6 +26,7 @@ from openstack.network.v2 import firewall_rule from openstack.network.v2 import flavor from openstack.network.v2 import floating_ip from openstack.network.v2 import health_monitor +from openstack.network.v2 import ipsec_site_connection from openstack.network.v2 import l3_conntrack_helper from openstack.network.v2 import listener from openstack.network.v2 import load_balancer @@ -224,6 +225,34 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase): self.verify_update(self.proxy.update_health_monitor, health_monitor.HealthMonitor) + def test_ipsec_site_connection_create_attrs(self): + self.verify_create(self.proxy.create_vpn_ipsec_site_connection, + ipsec_site_connection.IPSecSiteConnection) + + def test_ipsec_site_connection_delete(self): + self.verify_delete(self.proxy.delete_vpn_ipsec_site_connection, + ipsec_site_connection.IPSecSiteConnection, False) + + def test_ipsec_site_connection_delete_ignore(self): + self.verify_delete(self.proxy.delete_vpn_ipsec_site_connection, + ipsec_site_connection.IPSecSiteConnection, True) + + def test_ipsec_site_connection_find(self): + self.verify_find(self.proxy.find_vpn_ipsec_site_connection, + ipsec_site_connection.IPSecSiteConnection) + + def test_ipsec_site_connection_get(self): + self.verify_get(self.proxy.get_vpn_ipsec_site_connection, + ipsec_site_connection.IPSecSiteConnection) + + def test_ipsec_site_connections(self): + self.verify_list(self.proxy.vpn_ipsec_site_connections, + ipsec_site_connection.IPSecSiteConnection) + + def test_ipsec_site_connection_update(self): + self.verify_update(self.proxy.update_vpn_ipsec_site_connection, + ipsec_site_connection.IPSecSiteConnection) + def test_listener_create_attrs(self): self.verify_create(self.proxy.create_listener, listener.Listener)