From 9e4dd8ac59a79e3226cab7d3286ae0eed5a1b3d1 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Mon, 8 Apr 2019 15:04:01 +0300 Subject: [PATCH] Initial support for Policy IPSEC VPN resources Change-Id: Ic82dbcd18d1dbe0a444bb7bfb646931fe25f4d0a --- .../v3/policy/test_ipsec_vpn_resources.py | 709 ++++++++++++++++++ vmware_nsxlib/v3/policy/__init__.py | 2 + vmware_nsxlib/v3/policy/constants.py | 3 + vmware_nsxlib/v3/policy/core_defs.py | 13 +- vmware_nsxlib/v3/policy/core_resources.py | 5 +- vmware_nsxlib/v3/policy/ipsec_vpn_defs.py | 275 +++++++ .../v3/policy/ipsec_vpn_resources.py | 535 +++++++++++++ vmware_nsxlib/v3/vpn_ipsec.py | 15 +- 8 files changed, 1550 insertions(+), 7 deletions(-) create mode 100644 vmware_nsxlib/tests/unit/v3/policy/test_ipsec_vpn_resources.py create mode 100644 vmware_nsxlib/v3/policy/ipsec_vpn_defs.py create mode 100644 vmware_nsxlib/v3/policy/ipsec_vpn_resources.py diff --git a/vmware_nsxlib/tests/unit/v3/policy/test_ipsec_vpn_resources.py b/vmware_nsxlib/tests/unit/v3/policy/test_ipsec_vpn_resources.py new file mode 100644 index 00000000..948d864c --- /dev/null +++ b/vmware_nsxlib/tests/unit/v3/policy/test_ipsec_vpn_resources.py @@ -0,0 +1,709 @@ +# Copyright 2019 VMware, Inc. +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import mock + +from vmware_nsxlib.tests.unit.v3.policy import test_resources +from vmware_nsxlib.v3.policy import ipsec_vpn_defs +from vmware_nsxlib.v3 import vpn_ipsec + +TEST_TENANT = 'test' + + +class TestPolicyIkeProfileApi(test_resources.NsxPolicyLibTestCase): + + def setUp(self, *args, **kwargs): + super(TestPolicyIkeProfileApi, self).setUp() + self.resourceApi = self.policy_lib.ipsec_vpn.ike_profile + + def test_create(self): + name = 'd1' + obj_id = 'D1' + description = 'desc' + ike_version = vpn_ipsec.IkeVersionTypes.IKE_VERSION_V1 + encryption_algorithms = [ + vpn_ipsec.EncryptionAlgorithmTypes.ENCRYPTION_ALGORITHM_128] + digest_algorithms = [ + vpn_ipsec.DigestAlgorithmTypes.DIGEST_ALGORITHM_SHA256] + dh_groups = [vpn_ipsec.DHGroupTypes.DH_GROUP_15] + sa_life_time = vpn_ipsec.IkeSALifetimeLimits.SA_LIFETIME_MIN + 1 + tags = [] + with mock.patch.object(self.policy_api, + "create_or_update") as api_call: + result = self.resourceApi.create_or_overwrite( + name, + profile_id=obj_id, + description=description, + ike_version=ike_version, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + name=name, + description=description, + ike_version=ike_version, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result) + + def test_delete(self): + obj_id = '111' + with mock.patch.object(self.policy_api, "delete") as api_call: + self.resourceApi.delete(obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_get(self): + obj_id = '111' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + result = self.resourceApi.get(obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result['id']) + + def test_get_by_name(self): + name = 'd1' + with mock.patch.object( + self.policy_api, "list", + return_value={'results': [{'display_name': name}]}) as api_call: + obj = self.resourceApi.get_by_name(name, tenant=TEST_TENANT) + self.assertIsNotNone(obj) + expected_def = self.resourceApi.entry_def( + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_list(self): + with mock.patch.object(self.policy_api, "list", + return_value={'results': []}) as api_call: + result = self.resourceApi.list(tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual([], result) + + def test_update(self): + obj_id = '111' + name = 'new name' + description = 'new desc' + with self.mock_get(obj_id, 'old name'), \ + self.mock_create_update() as update_call: + self.resourceApi.update(obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + self.assert_called_with_def(update_call, expected_def) + + +class TestPolicyTunnelProfileApi(test_resources.NsxPolicyLibTestCase): + + def setUp(self, *args, **kwargs): + super(TestPolicyTunnelProfileApi, self).setUp() + self.resourceApi = self.policy_lib.ipsec_vpn.tunnel_profile + + def test_create(self): + name = 'd1' + obj_id = 'D1' + description = 'desc' + enable_perfect_forward_secrecy = True + encryption_algorithms = [ + vpn_ipsec.EncryptionAlgorithmTypes.ENCRYPTION_ALGORITHM_128] + digest_algorithms = [ + vpn_ipsec.DigestAlgorithmTypes.DIGEST_ALGORITHM_SHA256] + dh_groups = [vpn_ipsec.DHGroupTypes.DH_GROUP_15] + sa_life_time = vpn_ipsec.IkeSALifetimeLimits.SA_LIFETIME_MIN + 1 + tags = [] + with mock.patch.object(self.policy_api, + "create_or_update") as api_call: + result = self.resourceApi.create_or_overwrite( + name, + profile_id=obj_id, + description=description, + enable_perfect_forward_secrecy=enable_perfect_forward_secrecy, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + name=name, + description=description, + enable_perfect_forward_secrecy=enable_perfect_forward_secrecy, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result) + + def test_delete(self): + obj_id = '111' + with mock.patch.object(self.policy_api, "delete") as api_call: + self.resourceApi.delete(obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_get(self): + obj_id = '111' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + result = self.resourceApi.get(obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result['id']) + + def test_get_by_name(self): + name = 'd1' + with mock.patch.object( + self.policy_api, "list", + return_value={'results': [{'display_name': name}]}) as api_call: + obj = self.resourceApi.get_by_name(name, tenant=TEST_TENANT) + self.assertIsNotNone(obj) + expected_def = self.resourceApi.entry_def( + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_list(self): + with mock.patch.object(self.policy_api, "list", + return_value={'results': []}) as api_call: + result = self.resourceApi.list(tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual([], result) + + def test_update(self): + obj_id = '111' + name = 'new name' + description = 'new desc' + with self.mock_get(obj_id, 'old name'), \ + self.mock_create_update() as update_call: + self.resourceApi.update(obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + self.assert_called_with_def(update_call, expected_def) + + +class TestPolicyDpdProfileApi(test_resources.NsxPolicyLibTestCase): + + def setUp(self, *args, **kwargs): + super(TestPolicyDpdProfileApi, self).setUp() + self.resourceApi = self.policy_lib.ipsec_vpn.dpd_profile + + def test_create(self): + name = 'd1' + obj_id = 'D1' + description = 'desc' + dpd_probe_interval = 7 + enabled = True + tags = [] + with mock.patch.object(self.policy_api, + "create_or_update") as api_call: + result = self.resourceApi.create_or_overwrite( + name, + profile_id=obj_id, + description=description, + dpd_probe_interval=dpd_probe_interval, + enabled=enabled, + tags=tags, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + name=name, + description=description, + dpd_probe_interval=dpd_probe_interval, + enabled=enabled, + tags=tags, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result) + + def test_delete(self): + obj_id = '111' + with mock.patch.object(self.policy_api, "delete") as api_call: + self.resourceApi.delete(obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_get(self): + obj_id = '111' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + result = self.resourceApi.get(obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result['id']) + + def test_get_by_name(self): + name = 'd1' + with mock.patch.object( + self.policy_api, "list", + return_value={'results': [{'display_name': name}]}) as api_call: + obj = self.resourceApi.get_by_name(name, tenant=TEST_TENANT) + self.assertIsNotNone(obj) + expected_def = self.resourceApi.entry_def( + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_list(self): + with mock.patch.object(self.policy_api, "list", + return_value={'results': []}) as api_call: + result = self.resourceApi.list(tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual([], result) + + def test_update(self): + obj_id = '111' + name = 'new name' + description = 'new desc' + with self.mock_get(obj_id, 'old name'), \ + self.mock_create_update() as update_call: + self.resourceApi.update(obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + profile_id=obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + self.assert_called_with_def(update_call, expected_def) + + +class TestPolicyVpnServiceApi(test_resources.NsxPolicyLibTestCase): + + def setUp(self, *args, **kwargs): + super(TestPolicyVpnServiceApi, self).setUp() + self.resourceApi = self.policy_lib.ipsec_vpn.service + + def test_create(self): + name = 'd1' + tier1_id = 'tier1' + obj_id = 'D1' + description = 'desc' + ike_log_level = vpn_ipsec.IkeLogLevelTypes.LOG_LEVEL_ERROR + enabled = True + tags = [] + with mock.patch.object(self.policy_api, + "create_or_update") as api_call: + result = self.resourceApi.create_or_overwrite( + name, + tier1_id=tier1_id, + vpn_service_id=obj_id, + description=description, + ike_log_level=ike_log_level, + enabled=enabled, + tags=tags, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=obj_id, + name=name, + description=description, + ike_log_level=ike_log_level, + enabled=enabled, + tags=tags, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result) + + def test_delete(self): + obj_id = '111' + tier1_id = 'tier1' + with mock.patch.object(self.policy_api, "delete") as api_call: + self.resourceApi.delete(tier1_id, obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_get(self): + obj_id = '111' + tier1_id = 'tier1' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + result = self.resourceApi.get(tier1_id, obj_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result['id']) + + def test_get_by_name(self): + name = 'd1' + tier1_id = 'tier1' + with mock.patch.object( + self.policy_api, "list", + return_value={'results': [{'display_name': name}]}) as api_call: + obj = self.resourceApi.get_by_name(tier1_id, name, + tenant=TEST_TENANT) + self.assertIsNotNone(obj) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_list(self): + tier1_id = 'tier1' + with mock.patch.object(self.policy_api, "list", + return_value={'results': []}) as api_call: + result = self.resourceApi.list(tier1_id, tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual([], result) + + def test_update(self): + obj_id = '111' + tier1_id = 'tier1' + name = 'new name' + description = 'new desc' + with self.mock_get(obj_id, 'old name'), \ + self.mock_create_update() as update_call: + self.resourceApi.update(tier1_id, obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + self.assert_called_with_def(update_call, expected_def) + + +class TestPolicyVpnLocalEndpointApi(test_resources.NsxPolicyLibTestCase): + + def setUp(self, *args, **kwargs): + super(TestPolicyVpnLocalEndpointApi, self).setUp() + self.resourceApi = self.policy_lib.ipsec_vpn.local_endpoint + + def test_create(self): + name = 'EP1' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + obj_id = 'ep1' + description = 'desc' + local_address = '1.1.1.1' + local_id = '1' + tags = [] + with mock.patch.object(self.policy_api, + "create_or_update") as api_call: + result = self.resourceApi.create_or_overwrite( + name, + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + endpoint_id=obj_id, + description=description, + local_address=local_address, + local_id=local_id, + tags=tags, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + endpoint_id=obj_id, + name=name, + description=description, + local_address=local_address, + local_id=local_id, + tags=tags, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result) + + def test_delete(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "delete") as api_call: + self.resourceApi.delete(tier1_id, vpn_service_id, obj_id, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + endpoint_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_get(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + result = self.resourceApi.get(tier1_id, vpn_service_id, obj_id, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + endpoint_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result['id']) + + def test_get_by_name(self): + name = 'd1' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object( + self.policy_api, "list", + return_value={'results': [{'display_name': name}]}) as api_call: + obj = self.resourceApi.get_by_name(tier1_id, vpn_service_id, name, + tenant=TEST_TENANT) + self.assertIsNotNone(obj) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_list(self): + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "list", + return_value={'results': []}) as api_call: + result = self.resourceApi.list(tier1_id, vpn_service_id, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual([], result) + + def test_update(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + name = 'new name' + description = 'new desc' + with self.mock_get(obj_id, 'old name'), \ + self.mock_create_update() as update_call: + self.resourceApi.update(tier1_id, vpn_service_id, obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + endpoint_id=obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + self.assert_called_with_def(update_call, expected_def) + + +class TestPolicyVpnSessionApi(test_resources.NsxPolicyLibTestCase): + + def setUp(self, *args, **kwargs): + super(TestPolicyVpnSessionApi, self).setUp() + self.resourceApi = self.policy_lib.ipsec_vpn.session + + def test_create(self): + name = 'Sess1' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + obj_id = 'sess1' + description = 'desc' + enabled = True + peer_address = '2.2.2.2' + peer_id = '2' + psk = 'dummy' + rules = [self.resourceApi.build_rule( + 'rule', 'dummy_id', source_cidrs=['1.1.1.0/24'])] + dpd_profile_id = 'dpd1' + ike_profile_id = 'ike1' + tunnel_profile_id = 'tunnel1' + local_endpoint_id = 'ep1' + tags = [] + with mock.patch.object(self.policy_api, + "create_or_update") as api_call: + result = self.resourceApi.create_or_overwrite( + name, + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + session_id=obj_id, + description=description, + enabled=enabled, + peer_address=peer_address, + peer_id=peer_id, + psk=psk, + rules=rules, + dpd_profile_id=dpd_profile_id, + ike_profile_id=ike_profile_id, + tunnel_profile_id=tunnel_profile_id, + local_endpoint_id=local_endpoint_id, + tags=tags, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + service_id=self.resourceApi._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + session_id=obj_id, + name=name, + description=description, + enabled=enabled, + peer_address=peer_address, + peer_id=peer_id, + psk=psk, + rules=rules, + dpd_profile_id=dpd_profile_id, + ike_profile_id=ike_profile_id, + tunnel_profile_id=tunnel_profile_id, + local_endpoint_id=local_endpoint_id, + tags=tags, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result) + + def test_delete(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "delete") as api_call: + self.resourceApi.delete(tier1_id, vpn_service_id, obj_id, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + session_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_get(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + result = self.resourceApi.get(tier1_id, vpn_service_id, obj_id, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + session_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual(obj_id, result['id']) + + def test_get_by_name(self): + name = 'd1' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object( + self.policy_api, "list", + return_value={'results': [{'display_name': name}]}) as api_call: + obj = self.resourceApi.get_by_name(tier1_id, vpn_service_id, name, + tenant=TEST_TENANT) + self.assertIsNotNone(obj) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + + def test_list(self): + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "list", + return_value={'results': []}) as api_call: + result = self.resourceApi.list(tier1_id, vpn_service_id, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) + self.assertEqual([], result) + + def test_update(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + name = 'new name' + description = 'new desc' + with self.mock_get(obj_id, 'old name'), \ + self.mock_create_update() as update_call: + self.resourceApi.update(tier1_id, vpn_service_id, obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + expected_def = self.resourceApi.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + session_id=obj_id, + name=name, + description=description, + tenant=TEST_TENANT) + self.assert_called_with_def(update_call, expected_def) + + def test_get_status(self): + obj_id = '111' + tier1_id = 'tier1' + vpn_service_id = 'vpn1' + with mock.patch.object(self.policy_api, "get", + return_value={'id': obj_id}) as api_call: + self.resourceApi.get_status(tier1_id, vpn_service_id, obj_id, + tenant=TEST_TENANT) + expected_def = ipsec_vpn_defs.Tier1IPSecVpnSessionStatusDef( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + session_id=obj_id, + tenant=TEST_TENANT) + self.assert_called_with_def(api_call, expected_def) diff --git a/vmware_nsxlib/v3/policy/__init__.py b/vmware_nsxlib/v3/policy/__init__.py index 6e0e8b3a..4ed0a3e3 100644 --- a/vmware_nsxlib/v3/policy/__init__.py +++ b/vmware_nsxlib/v3/policy/__init__.py @@ -25,6 +25,7 @@ from vmware_nsxlib.v3 import nsx_constants from vmware_nsxlib.v3.policy import core_defs from vmware_nsxlib.v3.policy import core_resources +from vmware_nsxlib.v3.policy import ipsec_vpn_resources from vmware_nsxlib.v3.policy import lb_resources LOG = log.getLogger(__name__) @@ -117,6 +118,7 @@ class NsxPolicyLib(lib.NsxLibBase): self.certificate = core_resources.NsxPolicyCertApi(*args) self.exclude_list = core_resources.NsxPolicyExcludeListApi(*args) self.load_balancer = lb_resources.NsxPolicyLoadBalancerApi(*args) + self.ipsec_vpn = ipsec_vpn_resources.NsxPolicyIpsecVpnApi(*args) @property def keepalive_section(self): diff --git a/vmware_nsxlib/v3/policy/constants.py b/vmware_nsxlib/v3/policy/constants.py index a29c5264..8455eb61 100644 --- a/vmware_nsxlib/v3/policy/constants.py +++ b/vmware_nsxlib/v3/policy/constants.py @@ -108,3 +108,6 @@ ADV_RULE_TIER1_LB_VIP = 'TIER1_LB_VIP' ADV_RULE_TIER1_LB_SNAT = 'TIER1_LB_SNAT' ADV_RULE_TIER1_DNS_FORWARDER_IP = 'TIER1_DNS_FORWARDER_IP' ADV_RULE_TIER1_IPSEC_LOCAL_ENDPOINT = 'TIER1_IPSEC_LOCAL_ENDPOINT' + +IPSEC_VPN_RULE_PROTECT = 'PROTECT' +IPSEC_VPN_RULE_BYPASS = 'BYPASS' diff --git a/vmware_nsxlib/v3/policy/core_defs.py b/vmware_nsxlib/v3/policy/core_defs.py index ddc24a0d..d2ff2dae 100644 --- a/vmware_nsxlib/v3/policy/core_defs.py +++ b/vmware_nsxlib/v3/policy/core_defs.py @@ -56,6 +56,11 @@ EXCLUDE_LIST_PATH_PATTERN = (TENANTS_PATH_PATTERN + REALIZATION_PATH = "infra/realized-state/realized-entities?intent_path=%s" DHCP_REALY_PATTERN = TENANTS_PATH_PATTERN + "dhcp-relay-configs/" +TIER0_LOCALE_SERVICES_PATH_PATTERN = (TIER0S_PATH_PATTERN + + "%s/locale-services/") +TIER1_LOCALE_SERVICES_PATH_PATTERN = (TIER1S_PATH_PATTERN + + "%s/locale-services/") + @six.add_metaclass(abc.ABCMeta) class ResourceDef(object): @@ -416,7 +421,7 @@ class Tier0LocaleServiceDef(RouterLocaleServiceDef): @property def path_pattern(self): - return TIER0S_PATH_PATTERN + "%s/locale-services/" + return TIER0_LOCALE_SERVICES_PATH_PATTERN @property def path_ids(self): @@ -427,7 +432,7 @@ class Tier1LocaleServiceDef(RouterLocaleServiceDef): @property def path_pattern(self): - return TIER1S_PATH_PATTERN + "%s/locale-services/" + return TIER1_LOCALE_SERVICES_PATH_PATTERN @property def path_ids(self): @@ -442,7 +447,7 @@ class Tier0InterfaceDef(ResourceDef): @property def path_pattern(self): - return TIER0S_PATH_PATTERN + "%s/locale-services/%s/interfaces/" + return TIER0_LOCALE_SERVICES_PATH_PATTERN + "%s/interfaces/" @property def path_ids(self): @@ -457,7 +462,7 @@ class Tier1InterfaceDef(ResourceDef): @property def path_pattern(self): - return TIER1S_PATH_PATTERN + "%s/locale-services/%s/interfaces/" + return TIER1_LOCALE_SERVICES_PATH_PATTERN + "%s/interfaces/" def get_obj_dict(self): body = super(Tier1InterfaceDef, self).get_obj_dict() diff --git a/vmware_nsxlib/v3/policy/core_resources.py b/vmware_nsxlib/v3/policy/core_resources.py index b65682d7..7001d4b9 100644 --- a/vmware_nsxlib/v3/policy/core_resources.py +++ b/vmware_nsxlib/v3/policy/core_resources.py @@ -991,10 +991,11 @@ class NsxPolicyTier1Api(NsxPolicyResourceBase): tenant=tenant, current_body=tier1_dict) - def _locale_service_id(self, tier1_id): + @staticmethod + def _locale_service_id(tier1_id): # Supporting only a single locale-service per router for now # with the same id as the router id with a constant suffix - return tier1_id + self.LOCALE_SERVICE_SUFF + return tier1_id + NsxPolicyTier1Api.LOCALE_SERVICE_SUFF def create_locale_service(self, tier1_id, tenant=constants.POLICY_INFRA_TENANT): diff --git a/vmware_nsxlib/v3/policy/ipsec_vpn_defs.py b/vmware_nsxlib/v3/policy/ipsec_vpn_defs.py new file mode 100644 index 00000000..5a32e0b6 --- /dev/null +++ b/vmware_nsxlib/v3/policy/ipsec_vpn_defs.py @@ -0,0 +1,275 @@ +# Copyright 2019 VMware, Inc. +# All Rights Reserved +# +# 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 vmware_nsxlib.v3.policy import constants +from vmware_nsxlib.v3.policy import core_defs + +TENANTS_PATH_PATTERN = "%s/" +IPSEC_VPN_IKE_PROFILES_PATH_PATTERN = (TENANTS_PATH_PATTERN + + "ipsec-vpn-ike-profiles/") +IPSEC_VPN_TUNNEL_PROFILES_PATH_PATTERN = (TENANTS_PATH_PATTERN + + "ipsec-vpn-tunnel-profiles/") +IPSEC_VPN_DPD_PROFILES_PATH_PATTERN = (TENANTS_PATH_PATTERN + + "ipsec-vpn-dpd-profiles/") +IPSEC_VPN_SERVICE_PATH_PATTERN = ( + core_defs.TIER1_LOCALE_SERVICES_PATH_PATTERN + "%s/ipsec-vpn-services/") + +IPSEC_VPN_DPD_PROFILES_PATH_PATTERN = (TENANTS_PATH_PATTERN + + "ipsec-vpn-dpd-profiles/") + + +class IpsecVpnIkeProfileDef(core_defs.ResourceDef): + + @property + def path_pattern(self): + return IPSEC_VPN_IKE_PROFILES_PATH_PATTERN + + @property + def path_ids(self): + return ('tenant', 'profile_id') + + @staticmethod + def resource_type(): + return "IPSecVpnIkeProfile" + + def get_obj_dict(self): + body = super(IpsecVpnIkeProfileDef, self).get_obj_dict() + self._set_attrs_if_specified(body, ["ike_version", + "encryption_algorithms", + "digest_algorithms", + "dh_groups", + "sa_life_time"]) + return body + + +class IpsecVpnTunnelProfileDef(core_defs.ResourceDef): + + @property + def path_pattern(self): + return IPSEC_VPN_TUNNEL_PROFILES_PATH_PATTERN + + @property + def path_ids(self): + return ('tenant', 'profile_id') + + @staticmethod + def resource_type(): + return "IPSecVpnTunnelProfile" + + def get_obj_dict(self): + body = super(IpsecVpnTunnelProfileDef, self).get_obj_dict() + self._set_attrs_if_specified(body, ["enable_perfect_forward_secrecy", + "encryption_algorithms", + "digest_algorithms", + "dh_groups", + "sa_life_time"]) + return body + + +class IpsecVpnDpdProfileDef(core_defs.ResourceDef): + + @property + def path_pattern(self): + return IPSEC_VPN_DPD_PROFILES_PATH_PATTERN + + @property + def path_ids(self): + return ('tenant', 'profile_id') + + @staticmethod + def resource_type(): + return "IPSecVpnDpdProfile" + + def get_obj_dict(self): + body = super(IpsecVpnDpdProfileDef, self).get_obj_dict() + self._set_attrs_if_specified(body, ["dpd_probe_interval", "enabled"]) + return body + + +class Tier1IPSecVpnServiceDef(core_defs.ResourceDef): + + @staticmethod + def resource_type(): + return 'IPSecVpnService' + + @property + def path_pattern(self): + return IPSEC_VPN_SERVICE_PATH_PATTERN + + def get_obj_dict(self): + body = super(Tier1IPSecVpnServiceDef, self).get_obj_dict() + self._set_attrs_if_specified(body, ['enabled', 'ike_log_level']) + return body + + @property + def path_ids(self): + return ('tenant', 'tier1_id', 'service_id', 'vpn_service_id') + + +class IpsecVpnLocalEndpointDef(core_defs.ResourceDef): + + @property + def path_pattern(self): + return IPSEC_VPN_SERVICE_PATH_PATTERN + "%s/local-endpoints/" + + @property + def path_ids(self): + return ('tenant', 'tier1_id', 'service_id', 'vpn_service_id', + 'endpoint_id') + + @staticmethod + def resource_type(): + return "IPSecVpnLocalEndpoint" + + def get_obj_dict(self): + body = super(IpsecVpnLocalEndpointDef, self).get_obj_dict() + self._set_attrs_if_specified(body, ["local_address", "local_id", + "certificate_path", + "trust_ca_ids", "trust_crl_ids"]) + return body + + +class IPSecVpnRule(object): + + def __init__(self, name, rule_id, action=constants.IPSEC_VPN_RULE_PROTECT, + description=None, enabled=True, logged=False, + destination_cidrs=None, source_cidrs=None, sequence_number=0, + tags=None): + self.name = name + self.description = description + self.action = action + self.enabled = enabled + self.id = rule_id + self.logged = logged + self.destination_cidrs = destination_cidrs + self.source_cidrs = source_cidrs + self.sequence_number = sequence_number + self.tags = tags + + def get_obj_dict(self): + obj = {'display_name': self.name, + 'id': self.id, + 'action': self.action, + 'enabled': self.enabled, + 'logged': self.logged, + 'resource_type': 'IPSecVpnRule'} + + if self.description: + obj['description'] = self.description + + if self.destination_cidrs: + obj['destinations'] = [ + {'subnet': cidr} for cidr in self.destination_cidrs] + + if self.source_cidrs: + obj['sources'] = [ + {'subnet': cidr} for cidr in self.source_cidrs] + + if self.sequence_number: + obj['sequence_number'] = self.sequence_number + + if self.tags: + obj['tags'] = self.tags + + return obj + + +class Tier1IPSecVpnSessionDef(core_defs.ResourceDef): + + @staticmethod + def resource_type(): + return 'PolicyBasedIPSecVpnSession' + + @property + def path_pattern(self): + return IPSEC_VPN_SERVICE_PATH_PATTERN + "%s/sessions/" + + def get_obj_dict(self): + body = super(Tier1IPSecVpnSessionDef, self).get_obj_dict() + self._set_attrs_if_specified(body, ['enabled', 'peer_address', + 'peer_id', 'psk']) + + if self.has_attr('rules'): + body['rules'] = [ + a.get_obj_dict() + if isinstance(a, IPSecVpnRule) else a + for a in self.get_attr('rules')] + + if self.has_attr('dpd_profile_id'): + path = "" + if self.get_attr('dpd_profile_id'): + profile = IpsecVpnDpdProfileDef( + profile_id=self.get_attr('dpd_profile_id'), + tenant=self.get_tenant()) + path = profile.get_resource_full_path() + self._set_attr_if_specified(body, 'dpd_profile_id', + body_attr='dpd_profile_path', + value=path) + + if self.has_attr('ike_profile_id'): + path = "" + if self.get_attr('ike_profile_id'): + profile = IpsecVpnIkeProfileDef( + profile_id=self.get_attr('ike_profile_id'), + tenant=self.get_tenant()) + path = profile.get_resource_full_path() + self._set_attr_if_specified(body, 'ike_profile_id', + body_attr='ike_profile_path', + value=path) + + if self.has_attr('tunnel_profile_id'): + path = "" + if self.get_attr('tunnel_profile_id'): + profile = IpsecVpnTunnelProfileDef( + profile_id=self.get_attr('tunnel_profile_id'), + tenant=self.get_tenant()) + path = profile.get_resource_full_path() + self._set_attr_if_specified(body, 'tunnel_profile_id', + body_attr='tunnel_profile_path', + value=path) + + if self.has_attr('local_endpoint_id'): + path = "" + if self.get_attr('local_endpoint_id'): + endpoint = IpsecVpnLocalEndpointDef( + tier1_id=self.get_attr('tier1_id'), + service_id=self.get_attr('service_id'), + vpn_service_id=self.get_attr('vpn_service_id'), + endpoint_id=self.get_attr('local_endpoint_id'), + tenant=self.get_tenant()) + path = endpoint.get_resource_full_path() + self._set_attr_if_specified(body, 'local_endpoint_id', + body_attr='local_endpoint_path', + value=path) + return body + + @property + def path_ids(self): + return ('tenant', 'tier1_id', 'service_id', 'vpn_service_id', + 'session_id') + + +class Tier1IPSecVpnSessionStatusDef(core_defs.ResourceDef): + + @property + def path_pattern(self): + return (IPSEC_VPN_SERVICE_PATH_PATTERN + + "%s/sessions/%s/detailed-status/") + + @property + def path_ids(self): + return ('tenant', 'tier1_id', 'service_id', 'vpn_service_id', + 'session_id', '') diff --git a/vmware_nsxlib/v3/policy/ipsec_vpn_resources.py b/vmware_nsxlib/v3/policy/ipsec_vpn_resources.py new file mode 100644 index 00000000..16bc7551 --- /dev/null +++ b/vmware_nsxlib/v3/policy/ipsec_vpn_resources.py @@ -0,0 +1,535 @@ +# Copyright 2019 VMware, Inc. +# All Rights Reserved +# +# 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 oslo_log import log as logging + +from vmware_nsxlib.v3.policy import constants +from vmware_nsxlib.v3.policy import core_resources +from vmware_nsxlib.v3.policy import ipsec_vpn_defs + +LOG = logging.getLogger(__name__) +IGNORE = core_resources.IGNORE + + +class NsxIpsecVpnIkeProfileApi(core_resources.NsxPolicyResourceBase): + @property + def entry_def(self): + return ipsec_vpn_defs.IpsecVpnIkeProfileDef + + def create_or_overwrite(self, name, + profile_id=None, + description=IGNORE, + ike_version=IGNORE, + encryption_algorithms=IGNORE, + digest_algorithms=IGNORE, + dh_groups=IGNORE, + sa_life_time=IGNORE, + tags=IGNORE, + tenant=constants.POLICY_INFRA_TENANT): + + profile_id = self._init_obj_uuid(profile_id) + profile_def = self._init_def( + profile_id=profile_id, + name=name, + description=description, + ike_version=ike_version, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=tenant) + self._create_or_store(profile_def) + return profile_id + + def delete(self, profile_id, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(profile_id=profile_id, + tenant=tenant) + self.policy_api.delete(profile_def) + + def get(self, profile_id, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(profile_id=profile_id, + tenant=tenant) + return self.policy_api.get(profile_def) + + def list(self, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(tenant=tenant) + return self._list(profile_def) + + def get_by_name(self, name, tenant=constants.POLICY_INFRA_TENANT): + return super(NsxIpsecVpnIkeProfileApi, self).get_by_name( + name, tenant=tenant) + + def update(self, profile_id, name=IGNORE, description=IGNORE, + ike_version=IGNORE, encryption_algorithms=IGNORE, + digest_algorithms=IGNORE, dh_groups=IGNORE, sa_life_time=IGNORE, + tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT): + self._update(profile_id=profile_id, + name=name, + description=description, + ike_version=ike_version, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=tenant) + + +class NsxIpsecVpnTunnelProfileApi(core_resources.NsxPolicyResourceBase): + @property + def entry_def(self): + return ipsec_vpn_defs.IpsecVpnTunnelProfileDef + + def create_or_overwrite(self, name, + profile_id=None, + description=IGNORE, + enable_perfect_forward_secrecy=IGNORE, + encryption_algorithms=IGNORE, + digest_algorithms=IGNORE, + dh_groups=IGNORE, + sa_life_time=IGNORE, + tags=IGNORE, + tenant=constants.POLICY_INFRA_TENANT): + + profile_id = self._init_obj_uuid(profile_id) + profile_def = self._init_def( + profile_id=profile_id, + name=name, + description=description, + enable_perfect_forward_secrecy=enable_perfect_forward_secrecy, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=tenant) + self._create_or_store(profile_def) + return profile_id + + def delete(self, profile_id, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(profile_id=profile_id, + tenant=tenant) + self.policy_api.delete(profile_def) + + def get(self, profile_id, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(profile_id=profile_id, + tenant=tenant) + return self.policy_api.get(profile_def) + + def list(self, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(tenant=tenant) + return self._list(profile_def) + + def get_by_name(self, name, tenant=constants.POLICY_INFRA_TENANT): + return super(NsxIpsecVpnTunnelProfileApi, self).get_by_name( + name, tenant=tenant) + + def update(self, profile_id, name=IGNORE, description=IGNORE, + enable_perfect_forward_secrecy=IGNORE, + encryption_algorithms=IGNORE, + digest_algorithms=IGNORE, dh_groups=IGNORE, sa_life_time=IGNORE, + tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT): + self._update( + profile_id=profile_id, + name=name, + description=description, + enable_perfect_forward_secrecy=enable_perfect_forward_secrecy, + encryption_algorithms=encryption_algorithms, + digest_algorithms=digest_algorithms, + dh_groups=dh_groups, + sa_life_time=sa_life_time, + tags=tags, + tenant=tenant) + + +class NsxIpsecVpnDpdProfileApi(core_resources.NsxPolicyResourceBase): + @property + def entry_def(self): + return ipsec_vpn_defs.IpsecVpnDpdProfileDef + + def create_or_overwrite(self, name, + profile_id=None, + description=IGNORE, + dpd_probe_interval=IGNORE, + enabled=IGNORE, + tags=IGNORE, + tenant=constants.POLICY_INFRA_TENANT): + + profile_id = self._init_obj_uuid(profile_id) + profile_def = self._init_def( + profile_id=profile_id, + name=name, + description=description, + dpd_probe_interval=dpd_probe_interval, + enabled=enabled, + tags=tags, + tenant=tenant) + self._create_or_store(profile_def) + return profile_id + + def delete(self, profile_id, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(profile_id=profile_id, + tenant=tenant) + self.policy_api.delete(profile_def) + + def get(self, profile_id, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(profile_id=profile_id, + tenant=tenant) + return self.policy_api.get(profile_def) + + def list(self, tenant=constants.POLICY_INFRA_TENANT): + profile_def = self.entry_def(tenant=tenant) + return self._list(profile_def) + + def get_by_name(self, name, tenant=constants.POLICY_INFRA_TENANT): + return super(NsxIpsecVpnDpdProfileApi, self).get_by_name( + name, tenant=tenant) + + def update(self, profile_id, name=IGNORE, description=IGNORE, + dpd_probe_interval=IGNORE, enabled=IGNORE, + tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT): + self._update( + profile_id=profile_id, + name=name, + description=description, + dpd_probe_interval=dpd_probe_interval, + enabled=enabled, + tags=tags, + tenant=tenant) + + +class NsxIpsecVpnServiceApi(core_resources.NsxPolicyResourceBase): + @property + def entry_def(self): + return ipsec_vpn_defs.Tier1IPSecVpnServiceDef + + def _locale_service_id(self, tier1_id): + return core_resources.NsxPolicyTier1Api._locale_service_id(tier1_id) + + def create_or_overwrite(self, name, tier1_id, + vpn_service_id=None, + description=IGNORE, + enabled=IGNORE, + ike_log_level=IGNORE, + tags=IGNORE, + tenant=constants.POLICY_INFRA_TENANT): + + vpn_service_id = self._init_obj_uuid(vpn_service_id) + service_def = self._init_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + name=name, + description=description, + enabled=enabled, + ike_log_level=ike_log_level, + tags=tags, + tenant=tenant) + self._create_or_store(service_def) + return vpn_service_id + + def delete(self, tier1_id, vpn_service_id, + tenant=constants.POLICY_INFRA_TENANT): + service_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + tenant=tenant) + self.policy_api.delete(service_def) + + def get(self, tier1_id, vpn_service_id, + tenant=constants.POLICY_INFRA_TENANT): + service_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + tenant=tenant) + return self.policy_api.get(service_def) + + def list(self, tier1_id, tenant=constants.POLICY_INFRA_TENANT): + service_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + tenant=tenant) + return self._list(service_def) + + def get_by_name(self, tier1_id, name, + tenant=constants.POLICY_INFRA_TENANT): + return super(NsxIpsecVpnServiceApi, self).get_by_name( + name, tier1_id=tier1_id, + tenant=tenant) + + def update(self, tier1_id, vpn_service_id, name=IGNORE, description=IGNORE, + enabled=IGNORE, ike_log_level=IGNORE, + tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT): + self._update( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + name=name, + description=description, + enabled=enabled, + ike_log_level=ike_log_level, + tags=tags, + tenant=tenant) + + +class NsxIpsecVpnLocalEndpointApi(core_resources.NsxPolicyResourceBase): + @property + def entry_def(self): + return ipsec_vpn_defs.IpsecVpnLocalEndpointDef + + def _locale_service_id(self, tier1_id): + return core_resources.NsxPolicyTier1Api._locale_service_id(tier1_id) + + def create_or_overwrite(self, name, tier1_id, + vpn_service_id, + endpoint_id=None, + description=IGNORE, + local_address=IGNORE, + local_id=IGNORE, + certificate_path=IGNORE, + trust_ca_ids=IGNORE, + trust_crl_ids=IGNORE, + tags=IGNORE, + tenant=constants.POLICY_INFRA_TENANT): + + endpoint_id = self._init_obj_uuid(endpoint_id) + endpoint_def = self._init_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + endpoint_id=endpoint_id, + name=name, + description=description, + local_address=local_address, + local_id=local_id, + certificate_path=certificate_path, + trust_ca_ids=trust_ca_ids, + trust_crl_ids=trust_crl_ids, + tags=tags, + tenant=tenant) + self._create_or_store(endpoint_def) + return endpoint_id + + def delete(self, tier1_id, vpn_service_id, endpoint_id, + tenant=constants.POLICY_INFRA_TENANT): + endpoint_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + endpoint_id=endpoint_id, + tenant=tenant) + self.policy_api.delete(endpoint_def) + + def get(self, tier1_id, vpn_service_id, endpoint_id, + tenant=constants.POLICY_INFRA_TENANT): + endpoint_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + endpoint_id=endpoint_id, + tenant=tenant) + return self.policy_api.get(endpoint_def) + + def list(self, tier1_id, vpn_service_id, + tenant=constants.POLICY_INFRA_TENANT): + endpoint_def = self.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + service_id=self._locale_service_id(tier1_id), + tenant=tenant) + return self._list(endpoint_def) + + def get_by_name(self, tier1_id, vpn_service_id, name, + tenant=constants.POLICY_INFRA_TENANT): + return super(NsxIpsecVpnLocalEndpointApi, self).get_by_name( + name, tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + tenant=tenant) + + def update(self, tier1_id, vpn_service_id, endpoint_id, + name=IGNORE, + description=IGNORE, + local_address=IGNORE, + local_id=IGNORE, + certificate_path=IGNORE, + trust_ca_ids=IGNORE, + trust_crl_ids=IGNORE, + tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT): + self._update( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + endpoint_id=endpoint_id, + name=name, + description=description, + local_address=local_address, + local_id=local_id, + certificate_path=certificate_path, + trust_ca_ids=trust_ca_ids, + trust_crl_ids=trust_crl_ids, + tags=tags, + tenant=tenant) + + +class NsxIpsecVpnSessionApi(core_resources.NsxPolicyResourceBase): + @property + def entry_def(self): + return ipsec_vpn_defs.Tier1IPSecVpnSessionDef + + def _locale_service_id(self, tier1_id): + return core_resources.NsxPolicyTier1Api._locale_service_id(tier1_id) + + def create_or_overwrite(self, name, tier1_id, + vpn_service_id, + session_id=None, + description=IGNORE, + enabled=IGNORE, + peer_address=IGNORE, + peer_id=IGNORE, + psk=IGNORE, + rules=IGNORE, + dpd_profile_id=IGNORE, + ike_profile_id=IGNORE, + tunnel_profile_id=IGNORE, + local_endpoint_id=IGNORE, + tags=IGNORE, + tenant=constants.POLICY_INFRA_TENANT): + + session_id = self._init_obj_uuid(session_id) + session_def = self._init_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + session_id=session_id, + name=name, + description=description, + enabled=enabled, + peer_address=peer_address, + peer_id=peer_id, + psk=psk, + rules=rules, + dpd_profile_id=dpd_profile_id, + ike_profile_id=ike_profile_id, + tunnel_profile_id=tunnel_profile_id, + local_endpoint_id=local_endpoint_id, + tags=tags, + tenant=tenant) + self._create_or_store(session_def) + return session_id + + def delete(self, tier1_id, vpn_service_id, session_id, + tenant=constants.POLICY_INFRA_TENANT): + session_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + session_id=session_id, + tenant=tenant) + self.policy_api.delete(session_def) + + def get(self, tier1_id, vpn_service_id, session_id, + tenant=constants.POLICY_INFRA_TENANT): + session_def = self.entry_def( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + session_id=session_id, + tenant=tenant) + return self.policy_api.get(session_def) + + def get_status(self, tier1_id, vpn_service_id, session_id, + tenant=constants.POLICY_INFRA_TENANT): + status_def = ipsec_vpn_defs.Tier1IPSecVpnSessionStatusDef( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + session_id=session_id, + tenant=tenant) + return self.policy_api.get(status_def) + + def list(self, tier1_id, vpn_service_id, + tenant=constants.POLICY_INFRA_TENANT): + session_def = self.entry_def( + tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + service_id=self._locale_service_id(tier1_id), + tenant=tenant) + return self._list(session_def) + + def get_by_name(self, tier1_id, vpn_service_id, name, + tenant=constants.POLICY_INFRA_TENANT): + return super(NsxIpsecVpnSessionApi, self).get_by_name( + name, tier1_id=tier1_id, + vpn_service_id=vpn_service_id, + tenant=tenant) + + def update(self, tier1_id, vpn_service_id, session_id, + name=IGNORE, + description=IGNORE, + enabled=IGNORE, + peer_address=IGNORE, + peer_id=IGNORE, + psk=IGNORE, + rules=IGNORE, + dpd_profile_id=IGNORE, + ike_profile_id=IGNORE, + tunnel_profile_id=IGNORE, + local_endpoint_id=IGNORE, + tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT): + self._update( + tier1_id=tier1_id, + service_id=self._locale_service_id(tier1_id), + vpn_service_id=vpn_service_id, + session_id=session_id, + name=name, + description=description, + enabled=enabled, + peer_address=peer_address, + peer_id=peer_id, + psk=psk, + rules=rules, + dpd_profile_id=dpd_profile_id, + ike_profile_id=ike_profile_id, + tunnel_profile_id=tunnel_profile_id, + local_endpoint_id=local_endpoint_id, + tags=tags, + tenant=tenant) + + def build_rule(self, name, rule_id, + action=constants.IPSEC_VPN_RULE_PROTECT, + description=None, enabled=True, + logged=False, destination_cidrs=None, source_cidrs=None, + sequence_number=0, tags=None): + return ipsec_vpn_defs.IPSecVpnRule( + name=name, action=action, description=description, + enabled=enabled, rule_id=rule_id, logged=logged, + destination_cidrs=destination_cidrs, + source_cidrs=source_cidrs, sequence_number=sequence_number, + tags=tags) + + +class NsxPolicyIpsecVpnApi(object): + """This is the class that have all IPSEC VPN policy apis""" + def __init__(self, *args): + self.ike_profile = NsxIpsecVpnIkeProfileApi(*args) + self.tunnel_profile = NsxIpsecVpnTunnelProfileApi(*args) + self.dpd_profile = NsxIpsecVpnDpdProfileApi(*args) + self.service = NsxIpsecVpnServiceApi(*args) + self.local_endpoint = NsxIpsecVpnLocalEndpointApi(*args) + self.session = NsxIpsecVpnSessionApi(*args) diff --git a/vmware_nsxlib/v3/vpn_ipsec.py b/vmware_nsxlib/v3/vpn_ipsec.py index 2175d007..d84068fd 100644 --- a/vmware_nsxlib/v3/vpn_ipsec.py +++ b/vmware_nsxlib/v3/vpn_ipsec.py @@ -21,6 +21,9 @@ LOG = logging.getLogger(__name__) VPN_IPSEC_PATH = 'vpn/ipsec/' +# The following classes define IPSEC NSX constants that are alo relevant to the +# policy implementation: + class IkeVersionTypes(object): """Supported IKE versions (NSX default is V2)""" IKE_VERSION_V1 = 'IKE_V1' @@ -29,15 +32,20 @@ class IkeVersionTypes(object): class EncryptionAlgorithmTypes(object): - """Supported encryption algorithms (NSX default is GCM)""" + """Supported encryption algorithms (NSX default is AES_128)""" ENCRYPTION_ALGORITHM_128 = 'AES_128' ENCRYPTION_ALGORITHM_256 = 'AES_256' + ENCRYPTION_ALGORITHM_GCM_128 = 'AES_GCM_128' # only with IKE_V2 + ENCRYPTION_ALGORITHM_GCM_192 = 'AES_GCM_192' # only with IKE_V2 + ENCRYPTION_ALGORITHM_GCM_256 = 'AES_GCM_256' # only with IKE_V2 class DigestAlgorithmTypes(object): """Supported digest (auth) algorithms (NSX default is SHA2_256)""" DIGEST_ALGORITHM_SHA1 = 'SHA1' DIGEST_ALGORITHM_SHA256 = 'SHA2_256' + DIGEST_ALGORITHM_SHA2_384 = 'SHA2_384' + DIGEST_ALGORITHM_SHA2_512 = 'SHA2_512' DIGEST_ALGORITHM_GMAC_128 = 'GMAC_128' # only for tunnel profile DIGEST_ALGORITHM_GMAC_192 = 'GMAC_192' # only for tunnel profile DIGEST_ALGORITHM_GMAC_256 = 'GMAC_256' # only for tunnel profile @@ -45,9 +53,14 @@ class DigestAlgorithmTypes(object): class DHGroupTypes(object): """Supported DH groups for Perfect Forward Secrecy""" + DH_GROUP_2 = 'GROUP2' + DH_GROUP_5 = 'GROUP5' DH_GROUP_14 = 'GROUP14' DH_GROUP_15 = 'GROUP15' DH_GROUP_16 = 'GROUP16' + DH_GROUP_19 = 'GROUP19' + DH_GROUP_20 = 'GROUP20' + DH_GROUP_21 = 'GROUP21' class EncapsulationModeTypes(object):