From 34121473722b1e10ba9b64af9a3517dc2d6e422f Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Tue, 21 Jan 2025 12:25:42 +0100 Subject: [PATCH] Add "qinq-vlan" and "no-qinq-vlan" params to the "network create" cmd Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/939703 Related-Bug: #1915151 Change-Id: Icacf83c20c3650a9d75f665f020b8818e1b4a585 --- openstackclient/network/v2/network.py | 39 ++++++++++++++++--- .../tests/unit/network/v2/fakes.py | 1 + .../tests/unit/network/v2/test_network.py | 25 ++++++++++++ ..._qinq-to-the-network-3556c094aeedc0de.yaml | 7 ++++ 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 912e068597..7636de0c93 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -14,6 +14,7 @@ from cliff import columns as cliff_columns from osc_lib.cli import format_columns +from osc_lib import exceptions from osc_lib import utils from osc_lib.utils import tags as _tag @@ -60,11 +61,7 @@ def _get_columns_network(item): 'ipv6_address_scope_id': 'ipv6_address_scope', 'tags': 'tags', } - # TODO(slaweq): temporary, until - # https://review.opendev.org/c/openstack/openstacksdk/+/939703 will be - # merged this new column should be hidden from the output (it is just to - # make unit tests in the openstacksdk patch happy) - hidden_columns = ['location', 'tenant_id', 'is_vlan_qinq'] + hidden_columns = ['location', 'tenant_id'] return utils.get_osc_show_columns_for_sdk_resource( item, column_map, hidden_columns ) @@ -353,6 +350,25 @@ class CreateNetwork( ), ) + vlan_qinq_grp = parser.add_mutually_exclusive_group() + vlan_qinq_grp.add_argument( + '--qinq-vlan', + action='store_true', + help=self.enhance_help_neutron( + _("Enable VLAN QinQ (S-Tag ethtype 0x8a88) " "for the network") + ), + ) + vlan_qinq_grp.add_argument( + '--no-qinq-vlan', + action='store_true', + help=self.enhance_help_neutron( + _( + "Disable VLAN QinQ (S-Tag ethtype 0x8a88) " + "for the network" + ) + ), + ) + _add_additional_network_options(parser) _tag.add_tag_option_to_parser_for_create( parser, _('network'), enhance_help=self.enhance_help_neutron @@ -376,6 +392,19 @@ class CreateNetwork( attrs['vlan_transparent'] = True if parsed_args.no_transparent_vlan: attrs['vlan_transparent'] = False + + if parsed_args.qinq_vlan: + attrs['vlan_qinq'] = True + if parsed_args.no_qinq_vlan: + attrs['vlan_qinq'] = False + + if attrs.get('vlan_transparent') and attrs.get('vlan_qinq'): + msg = _( + "--transparent-vlan and --qinq-vlan can not be both enabled " + "for the network." + ) + raise exceptions.CommandError(msg) + attrs.update( self._parse_extra_properties(parsed_args.extra_properties) ) diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index 4a0f9df77a..d0b1c1ebb1 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -1419,6 +1419,7 @@ def create_one_network(attrs=None): 'availability_zone_hints': [], 'is_default': False, 'is_vlan_transparent': True, + 'is_vlan_qinq': False, 'port_security_enabled': True, 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex, 'ipv4_address_scope': 'ipv4' + uuid.uuid4().hex, diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py index 33fe5be3a5..0222be68d2 100644 --- a/openstackclient/tests/unit/network/v2/test_network.py +++ b/openstackclient/tests/unit/network/v2/test_network.py @@ -63,6 +63,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'ipv6_address_scope', 'is_default', 'is_vlan_transparent', + 'is_vlan_qinq', 'mtu', 'name', 'port_security_enabled', @@ -103,6 +104,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): network.RouterExternalColumn(_network.is_router_external), _network.is_shared, _network.is_vlan_transparent, + _network.is_vlan_qinq, _network.status, _network.segments, format_columns.ListColumn(_network.subnet_ids), @@ -190,6 +192,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): "--qos-policy", self.qos_policy.id, "--transparent-vlan", + "--no-qinq-vlan", "--enable-port-security", "--dns-domain", "example.org.", @@ -210,6 +213,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): ('segmentation_id', '400'), ('qos_policy', self.qos_policy.id), ('transparent_vlan', True), + ('qinq_vlan', False), ('enable_port_security', True), ('name', self._network.name), ('dns_domain', 'example.org.'), @@ -234,6 +238,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'provider:segmentation_id': '400', 'qos_policy_id': self.qos_policy.id, 'vlan_transparent': True, + 'vlan_qinq': False, 'port_security_enabled': True, 'dns_domain': 'example.org.', } @@ -246,6 +251,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): "--enable", "--no-share", "--disable-port-security", + "--qinq-vlan", self._network.name, ] verifylist = [ @@ -253,6 +259,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): ('no_share', True), ('name', self._network.name), ('external', False), + ('qinq_vlan', True), ('disable_port_security', True), ] @@ -264,6 +271,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'admin_state_up': True, 'name': self._network.name, 'shared': False, + 'vlan_qinq': True, 'port_security_enabled': False, } ) @@ -309,6 +317,19 @@ class TestCreateNetworkIdentityV3(TestNetwork): def test_create_with_no_tag(self): self._test_create_with_tag(add_tags=False) + def test_create_with_vlan_qinq_and_transparency_enabled(self): + arglist = [ + "--transparent-vlan", + "--qinq-vlan", + self._network.name, + ] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + class TestCreateNetworkIdentityV2( identity_fakes_v2.FakeClientMixin, @@ -332,6 +353,7 @@ class TestCreateNetworkIdentityV2( 'ipv6_address_scope', 'is_default', 'is_vlan_transparent', + 'is_vlan_qinq', 'mtu', 'name', 'port_security_enabled', @@ -372,6 +394,7 @@ class TestCreateNetworkIdentityV2( network.RouterExternalColumn(_network.is_router_external), _network.is_shared, _network.is_vlan_transparent, + _network.is_vlan_qinq, _network.status, _network.segments, format_columns.ListColumn(_network.subnet_ids), @@ -1149,6 +1172,7 @@ class TestShowNetwork(TestNetwork): 'ipv6_address_scope', 'is_default', 'is_vlan_transparent', + 'is_vlan_qinq', 'mtu', 'name', 'port_security_enabled', @@ -1189,6 +1213,7 @@ class TestShowNetwork(TestNetwork): network.RouterExternalColumn(_network.is_router_external), _network.is_shared, _network.is_vlan_transparent, + _network.is_vlan_qinq, _network.status, _network.segments, format_columns.ListColumn(_network.subnet_ids), diff --git a/releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml b/releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml new file mode 100644 index 0000000000..f89575b40c --- /dev/null +++ b/releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Add ``qinq-vlan`` and ``no-qinq-vlan`` arguments to the ``network create`` + command. It will enable/disable QinQ feature for the created network. + This new argument is mutually exclusive with the ``transparent-vlan`` - only + one of them can be set to ``True`` for the network.