diff --git a/heat/engine/resources/openstack/neutron/l2_gateway_connection.py b/heat/engine/resources/openstack/neutron/l2_gateway_connection.py new file mode 100644 index 0000000000..e49078c92c --- /dev/null +++ b/heat/engine/resources/openstack/neutron/l2_gateway_connection.py @@ -0,0 +1,84 @@ +# Copyright 2018 Ericsson +# +# 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 heat.common.i18n import _ +from heat.engine import constraints +from heat.engine import properties +from heat.engine.resources.openstack.neutron import neutron +from heat.engine import support + + +class L2GatewayConnection(neutron.NeutronResource): + """A resource for managing Neutron L2 Gateway Connections. + + The L2 Gateway Connection provides a mapping to connect a Neutron network + to a L2 Gateway on a particular segmentation ID. + """ + + required_service_extension = 'l2-gateway-connection' + + entity = 'l2_gateway_connection' + + support_status = support.SupportStatus(version='12.0.0') + + PROPERTIES = ( + L2_GATEWAY_ID, NETWORK_ID, SEGMENTATION_ID, + ) = ( + 'l2_gateway_id', 'network_id', 'segmentation_id', + ) + + properties_schema = { + L2_GATEWAY_ID: properties.Schema( + properties.Schema.STRING, + _('A string specifying a id of the l2gateway resource.'), + required=True + ), + NETWORK_ID: properties.Schema( + properties.Schema.STRING, + _('A string specifying a id of the network resource ' + 'to connect to the l2gateway.'), + required=True, + constraints=[ + constraints.CustomConstraint('neutron.network') + ], + ), + SEGMENTATION_ID: properties.Schema( + properties.Schema.STRING, + _('A string specifying a segmentation id for the interface ' + 'on the l2gateway.'), + ), + } + + def handle_create(self): + props = self.prepare_properties( + self.properties, + self.physical_resource_name()) + + l2gwc = self.client().create_l2_gateway_connection( + {'l2_gateway_connection': props})['l2_gateway_connection'] + + self.resource_id_set(l2gwc['id']) + + def handle_delete(self): + if self.resource_id is None: + return + with self.client_plugin().ignore_not_found: + self.client().delete_l2_gateway_connection(self.resource_id) + + +def resource_mapping(): + return { + 'OS::Neutron::L2GatewayConnection': L2GatewayConnection, + } diff --git a/heat/tests/openstack/neutron/test_neutron_l2_gateway_connection.py b/heat/tests/openstack/neutron/test_neutron_l2_gateway_connection.py new file mode 100644 index 0000000000..b040281d32 --- /dev/null +++ b/heat/tests/openstack/neutron/test_neutron_l2_gateway_connection.py @@ -0,0 +1,87 @@ +# Copyright 2018 Ericsson +# +# 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 neutronclient.v2_0 import client as neutronclient + +from heat.common import template_format +from heat.engine.clients.os import neutron +from heat.engine import scheduler +from heat.tests import common +from heat.tests import utils + + +class NeutronL2GatewayConnectionTest(common.HeatTestCase): + test_template = ''' + heat_template_version: queens + description: Template to test L2GatewayConnection Neutron resource + resources: + l2gw_conn: + type: OS::Neutron::L2GatewayConnection + properties: + network_id: j29n3678-c012-p008-3975-93584a65a18a + segmentation_id: 501 + l2_gateway_id: d3590f37-b072-4358-9719-71964d84a31c + ''' + + mock_create_req = { + "l2_gateway_connection": { + "network_id": "j29n3678-c012-p008-3975-93584a65a18a", + "segmentation_id": "501", + "l2_gateway_id": "d3590f37-b072-4358-9719-71964d84a31c" + }} + mock_create_reply = { + "l2_gateway_connection": { + "id": "e491171c-3458-4d85-b3a3-68a7c4a1cacd", + "tenant_id": "7ea656c7c9b8447494f33b0bc741d9e6", + "network_id": "j29n3678-c012-p008-3975-93584a65a18a", + "segmentation_id": "501", + "l2_gateway_id": "d3590f37-b072-4358-9719-71964d84a31c" + }} + + def setUp(self): + super(NeutronL2GatewayConnectionTest, self).setUp() + self.mockclient = mock.MagicMock() + self.patchobject(neutronclient, 'Client', return_value=self.mockclient) + + self.patchobject(neutron.NeutronClientPlugin, 'has_extension', + return_value=True) + + def _create_l2_gateway_connection(self): + # stack create + self.mockclient.create_l2_gateway_connection.return_value = ( + self.mock_create_reply) + self.mockclient.show_l2_gateway_connection.return_value = ( + self.mock_create_reply) + orig_template = template_format.parse(self.test_template) + self.stack = utils.parse_stack(orig_template) + scheduler.TaskRunner(self.stack.create)() + self.l2gwconn_resource = self.stack['l2gw_conn'] + + def test_l2_gateway_connection_create(self): + self._create_l2_gateway_connection() + self.assertIsNone(self.l2gwconn_resource.validate()) + self.assertEqual((self.l2gwconn_resource.CREATE, + self.l2gwconn_resource.COMPLETE), + self.l2gwconn_resource.state) + self.assertEqual('e491171c-3458-4d85-b3a3-68a7c4a1cacd', + self.l2gwconn_resource.FnGetRefId()) + self.mockclient.create_l2_gateway_connection.assert_called_once_with( + self.mock_create_req) + + def test_l2_gateway_connection_delete(self): + self._create_l2_gateway_connection() + self.stack.delete() + self.mockclient.delete_l2_gateway_connection.assert_called_with( + 'e491171c-3458-4d85-b3a3-68a7c4a1cacd') diff --git a/releasenotes/notes/neutron-l2gw-connection-support-56fc2db6e448100a.yaml b/releasenotes/notes/neutron-l2gw-connection-support-56fc2db6e448100a.yaml new file mode 100644 index 0000000000..812a1e725b --- /dev/null +++ b/releasenotes/notes/neutron-l2gw-connection-support-56fc2db6e448100a.yaml @@ -0,0 +1,6 @@ +--- +features: + - New resource ``OS::Neutron::L2GatewayConnection`` to allow management of + Neutron Layer2 Gateway Connection. This resource provides capability to + connect a Neutron network to a Layer2 Gateway. + The resource depends on the Neutron ``l2-gateway`` extension.