diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst index d133674f9..4b72d5e06 100644 --- a/doc/source/command-objects/network.rst +++ b/doc/source/command-objects/network.rst @@ -193,53 +193,96 @@ List networks [--project [--project-domain ]] [--share | --no-share] [--status ] + [--provider-network-type ] + [--provider-physical-network ] + [--provider-segment ] .. option:: --external List external networks + *Network version 2 only* + .. option:: --internal List internal networks + *Network version 2 only* + .. option:: --long List additional fields in output + *Network version 2 only* + .. option:: --name List networks according to their name + *Network version 2 only* + .. option:: --enable List enabled networks + *Network version 2 only* + .. option:: --disable List disabled networks + *Network version 2 only* + .. option:: --project List networks according to their project (name or ID) + *Network version 2 only* + .. option:: --project-domain Domain the project belongs to (name or ID). This can be used in case collisions between project names exist. + *Network version 2 only* + .. option:: --share List networks shared between projects + *Network version 2 only* + .. option:: --no-share List networks not shared between projects + *Network version 2 only* + .. option:: --status List networks according to their status ('ACTIVE', 'BUILD', 'DOWN', 'ERROR') +.. option:: --provider-network-type + + List networks according to their physical mechanisms. + The supported options are: flat, geneve, gre, local, vlan, vxlan. + + *Network version 2 only* + +.. option:: --provider-physical-network + + List networks according to name of the physical network + + *Network version 2 only* + +.. option:: --provider-segment + + List networks according to VLAN ID for VLAN networks + or Tunnel ID for GENEVE/GRE/VXLAN networks + + *Network version 2 only* + network set ----------- diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 40183b73f..397139e20 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -304,7 +304,7 @@ class DeleteNetwork(common.NetworkAndComputeDelete): class ListNetwork(common.NetworkAndComputeLister): """List networks""" - def update_parser_common(self, parser): + def update_parser_network(self, parser): router_ext_group = parser.add_mutually_exclusive_group() router_ext_group.add_argument( '--external', @@ -361,6 +361,29 @@ class ListNetwork(common.NetworkAndComputeLister): help=_("List networks according to their status " "('ACTIVE', 'BUILD', 'DOWN', 'ERROR')") ) + parser.add_argument( + '--provider-network-type', + metavar='', + choices=['flat', 'geneve', 'gre', 'local', + 'vlan', 'vxlan'], + help=_("List networks according to their physical mechanisms. " + "The supported options are: flat, geneve, gre, local, " + "vlan, vxlan.") + ) + parser.add_argument( + '--provider-physical-network', + metavar='', + dest='physical_network', + help=_("List networks according to name of the physical network") + ) + parser.add_argument( + '--provider-segment', + metavar='', + dest='segmentation_id', + help=_("List networks according to VLAN ID for VLAN networks " + "or Tunnel ID for GENEVE/GRE/VXLAN networks") + ) + return parser def take_action_network(self, client, parsed_args): @@ -433,6 +456,13 @@ class ListNetwork(common.NetworkAndComputeLister): if parsed_args.status: args['status'] = parsed_args.status + if parsed_args.provider_network_type: + args['provider:network_type'] = parsed_args.provider_network_type + if parsed_args.physical_network: + args['provider:physical_network'] = parsed_args.physical_network + if parsed_args.segmentation_id: + args['provider:segmentation_id'] = parsed_args.segmentation_id + data = client.networks(**args) return (column_headers, diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index 94727ae3c..02ef037e0 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -291,6 +291,8 @@ class FakeNetwork(object): 'shared': False, 'subnets': ['a', 'b'], 'provider_network_type': 'vlan', + 'provider_physical_network': 'physnet1', + 'provider_segmentation_id': "400", 'router:external': True, 'availability_zones': [], 'availability_zone_hints': [], diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py index 828da4a26..c0de86404 100644 --- a/openstackclient/tests/unit/network/v2/test_network.py +++ b/openstackclient/tests/unit/network/v2/test_network.py @@ -65,6 +65,8 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'port_security_enabled', 'project_id', 'provider_network_type', + 'provider_physical_network', + 'provider_segmentation_id', 'router:external', 'shared', 'status', @@ -82,6 +84,8 @@ class TestCreateNetworkIdentityV3(TestNetwork): _network.is_port_security_enabled, _network.project_id, _network.provider_network_type, + _network.provider_physical_network, + _network.provider_segmentation_id, network._format_router_external(_network.is_router_external), _network.shared, _network.status, @@ -229,6 +233,8 @@ class TestCreateNetworkIdentityV2(TestNetwork): 'port_security_enabled', 'project_id', 'provider_network_type', + 'provider_physical_network', + 'provider_segmentation_id', 'router:external', 'shared', 'status', @@ -246,6 +252,8 @@ class TestCreateNetworkIdentityV2(TestNetwork): _network.is_port_security_enabled, _network.project_id, _network.provider_network_type, + _network.provider_physical_network, + _network.provider_segmentation_id, network._format_router_external(_network.is_router_external), _network.shared, _network.status, @@ -681,6 +689,57 @@ class TestListNetwork(TestNetwork): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) + def test_network_list_provider_network_type(self): + network_type = self._network[0].provider_network_type + arglist = [ + '--provider-network-type', network_type, + ] + verifylist = [ + ('provider_network_type', network_type), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.networks.assert_called_once_with( + **{'provider:network_type': network_type} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_network_list_provider_physical_network(self): + physical_network = self._network[0].provider_physical_network + arglist = [ + '--provider-physical-network', physical_network, + ] + verifylist = [ + ('physical_network', physical_network), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.networks.assert_called_once_with( + **{'provider:physical_network': physical_network} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_network_list_provider_segment(self): + segmentation_id = self._network[0].provider_segmentation_id + arglist = [ + '--provider-segment', segmentation_id, + ] + verifylist = [ + ('segmentation_id', segmentation_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.networks.assert_called_once_with( + **{'provider:segmentation_id': segmentation_id} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetNetwork(TestNetwork): @@ -805,6 +864,8 @@ class TestShowNetwork(TestNetwork): 'port_security_enabled', 'project_id', 'provider_network_type', + 'provider_physical_network', + 'provider_segmentation_id', 'router:external', 'shared', 'status', @@ -822,6 +883,8 @@ class TestShowNetwork(TestNetwork): _network.is_port_security_enabled, _network.project_id, _network.provider_network_type, + _network.provider_physical_network, + _network.provider_segmentation_id, network._format_router_external(_network.is_router_external), _network.shared, _network.status, @@ -1111,10 +1174,7 @@ class TestListNetworkCompute(TestNetworkCompute): def test_network_list_no_options(self): arglist = [] - verifylist = [ - ('external', False), - ('long', False), - ] + verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) # In base command class Lister in cliff, abstract method take_action() diff --git a/releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml b/releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml new file mode 100644 index 000000000..afedabcdd --- /dev/null +++ b/releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add ``--provider-network-type``, ``--provider-physical-network``, and + ``--provider-segment`` options to the ``network list`` command. + [Bug `1635580 `_]