diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst index 0c472e7f1..5d9a5ca86 100644 --- a/doc/source/command-objects/network.rst +++ b/doc/source/command-objects/network.rst @@ -24,6 +24,7 @@ Create new network [--enable | --disable] [--share | --no-share] [--availability-zone-hint ] + [--enable-port-security | --disable-port-security] [--external [--default | --no-default] | --internal] [--provider-network-type ] [--provider-physical-network ] @@ -72,6 +73,20 @@ Create new network *Network version 2 only* +.. option:: --enable-port-security + + Enable port security by default for ports created on + this network (default) + + *Network version 2 only* + +.. option:: --disable-port-security + + Disable port security by default for ports created on + this network + + *Network version 2 only* + .. option:: --subnet IPv4 subnet for fixed IPs (in CIDR notation) @@ -191,6 +206,7 @@ Set network properties [--name ] [--enable | --disable] [--share | --no-share] + [--enable-port-security | --disable-port-security] [--external [--default | --no-default] | --internal] [--provider-network-type ] [--provider-physical-network ] @@ -218,6 +234,16 @@ Set network properties Do not share the network between projects +.. option:: --enable-port-security + + Enable port security by default for ports created on + this network + +.. option:: --disable-port-security + + Disable port security by default for ports created on + this network + .. option:: --external Set this network as an external network. diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 31dfc7983..ccc02fd8e 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -58,6 +58,10 @@ def _get_attrs(client_manager, parsed_args): attrs['shared'] = True if parsed_args.no_share: attrs['shared'] = False + if parsed_args.enable_port_security: + attrs['port_security_enabled'] = True + if parsed_args.disable_port_security: + attrs['port_security_enabled'] = False # "network set" command doesn't support setting project. if 'project' in parsed_args and parsed_args.project is not None: @@ -197,6 +201,19 @@ class CreateNetwork(common.NetworkAndComputeShowOne): "(Network Availability Zone extension required, " "repeat option to set multiple availability zones)") ) + port_security_group = parser.add_mutually_exclusive_group() + port_security_group.add_argument( + '--enable-port-security', + action='store_true', + help=_("Enable port security by default for ports created on " + "this network (default)") + ) + port_security_group.add_argument( + '--disable-port-security', + action='store_true', + help=_("Disable port security by default for ports created on " + "this network") + ) external_router_grp = parser.add_mutually_exclusive_group() external_router_grp.add_argument( '--external', @@ -403,6 +420,19 @@ class SetNetwork(command.Command): action='store_true', help=_("Do not share the network between projects") ) + port_security_group = parser.add_mutually_exclusive_group() + port_security_group.add_argument( + '--enable-port-security', + action='store_true', + help=_("Enable port security by default for ports created on " + "this network") + ) + port_security_group.add_argument( + '--disable-port-security', + action='store_true', + help=_("Disable port security by default for ports created on " + "this network") + ) external_router_grp = parser.add_mutually_exclusive_group() external_router_grp.add_argument( '--external', diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py index 50d9899cb..8d5efe145 100644 --- a/openstackclient/tests/network/v2/fakes.py +++ b/openstackclient/tests/network/v2/fakes.py @@ -285,6 +285,7 @@ class FakeNetwork(object): 'availability_zones': [], 'availability_zone_hints': [], 'is_default': False, + 'port_security_enabled': True, } # Overwrite default attributes. @@ -296,6 +297,8 @@ class FakeNetwork(object): # Set attributes with special mapping in OpenStack SDK. network.project_id = network_attrs['tenant_id'] network.is_router_external = network_attrs['router:external'] + network.is_port_security_enabled = \ + network_attrs['port_security_enabled'] return network diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py index 4322bf9a5..aa0164033 100644 --- a/openstackclient/tests/network/v2/test_network.py +++ b/openstackclient/tests/network/v2/test_network.py @@ -56,6 +56,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'id', 'is_default', 'name', + 'port_security_enabled', 'project_id', 'provider_network_type', 'router:external', @@ -71,6 +72,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): _network.id, _network.is_default, _network.name, + _network.is_port_security_enabled, _network.project_id, _network.provider_network_type, network._format_router_external(_network.is_router_external), @@ -144,6 +146,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): "--provider-physical-network", "physnet1", "--provider-segment", "400", "--transparent-vlan", + "--enable-port-security", self._network.name, ] verifylist = [ @@ -158,6 +161,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): ('physical_network', 'physnet1'), ('segmentation_id', '400'), ('transparent_vlan', True), + ('enable_port_security', True), ('name', self._network.name), ] @@ -176,6 +180,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'provider:physical_network': 'physnet1', 'provider:segmentation_id': '400', 'vlan_transparent': True, + 'port_security_enabled': True, }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -184,6 +189,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): arglist = [ "--enable", "--no-share", + "--disable-port-security", self._network.name, ] verifylist = [ @@ -191,6 +197,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): ('no_share', True), ('name', self._network.name), ('external', False), + ('disable_port_security', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -200,6 +207,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'admin_state_up': True, 'name': self._network.name, 'shared': False, + 'port_security_enabled': False, }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -220,6 +228,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): 'id', 'is_default', 'name', + 'port_security_enabled', 'project_id', 'provider_network_type', 'router:external', @@ -235,6 +244,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): _network.id, _network.is_default, _network.name, + _network.is_port_security_enabled, _network.project_id, _network.provider_network_type, network._format_router_external(_network.is_router_external), @@ -537,6 +547,7 @@ class TestSetNetwork(TestNetwork): '--provider-physical-network', 'physnet1', '--provider-segment', '400', '--no-transparent-vlan', + '--enable-port-security', ] verifylist = [ ('network', self._network.name), @@ -549,6 +560,7 @@ class TestSetNetwork(TestNetwork): ('physical_network', 'physnet1'), ('segmentation_id', '400'), ('no_transparent_vlan', True), + ('enable_port_security', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -564,6 +576,7 @@ class TestSetNetwork(TestNetwork): 'provider:physical_network': 'physnet1', 'provider:segmentation_id': '400', 'vlan_transparent': False, + 'port_security_enabled': True, } self.network.update_network.assert_called_once_with( self._network, **attrs) @@ -575,12 +588,14 @@ class TestSetNetwork(TestNetwork): '--disable', '--no-share', '--internal', + '--disable-port-security', ] verifylist = [ ('network', self._network.name), ('disable', True), ('no_share', True), ('internal', True), + ('disable_port_security', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -590,6 +605,7 @@ class TestSetNetwork(TestNetwork): 'admin_state_up': False, 'shared': False, 'router:external': False, + 'port_security_enabled': False, } self.network.update_network.assert_called_once_with( self._network, **attrs) @@ -620,6 +636,7 @@ class TestShowNetwork(TestNetwork): 'id', 'is_default', 'name', + 'port_security_enabled', 'project_id', 'provider_network_type', 'router:external', @@ -635,6 +652,7 @@ class TestShowNetwork(TestNetwork): _network.id, _network.is_default, _network.name, + _network.is_port_security_enabled, _network.project_id, _network.provider_network_type, network._format_router_external(_network.is_router_external), diff --git a/releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml b/releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml index d3d3d336a..74ace6c8f 100644 --- a/releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml +++ b/releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml @@ -4,6 +4,11 @@ features: ``port set`` commands to support JSON input for more advanced binding profile data. [Blueprint :oscbp:`neutron-client`] + - Add ``--enable-port-security`` and ``--disable-port-security`` + options on the ``network create`` and ``network set`` commands. + This supports setting the default port security for ports created + on a network. + [Blueprint :oscbp:`neutron-client`] - Add ``geneve`` choice to the ``network create`` command ``--provider-network-type`` option. [Blueprint :oscbp:`neutron-client`]