Support "network create" command in nova network

This patch only provide network name and subnet setting for
"network create" command.

The other options, such as --project which depends on
identity v2 or v3, will make the unit tests too complicated.
So I prefer to implement them in other patches.

Change-Id: I9ec93f0af813c8fae4170c36e16bbe8f0f53cbb6
Partial-Bug: 1543672
This commit is contained in:
Tang Chen 2016-02-25 16:35:57 +08:00
parent f9add0559c
commit 359dfa1a06
4 changed files with 174 additions and 23 deletions

View File

@ -22,19 +22,23 @@ Create new network
.. option:: --project <project>
Owner's project (name or ID)
(Network v2 only)
.. option:: --project-domain <project-domain>
Domain the project belongs to (name or ID).
This can be used in case collisions between project names exist.
(Network v2 only)
.. option:: --enable
Enable network (default)
(Network v2 only)
.. option:: --disable
Disable network
(Network v2 only)
.. option:: --share
@ -46,8 +50,14 @@ Create new network
.. option:: --availability-zone-hint <availability-zone>
Availability Zone in which to create this network (requires the Network
Availability Zone extension, this option can be repeated).
Availability Zone in which to create this network (requires the Network
Availability Zone extension, this option can be repeated).
(Network v2 only)
.. option:: --subnet <subnet>
IPv4 subnet for fixed IPs (in CIDR notation)
(Compute v2 network only)
.. _network_create-name:
.. describe:: <name>

View File

@ -75,30 +75,27 @@ def _get_attrs(client_manager, parsed_args):
return attrs
class CreateNetwork(command.ShowOne):
def _get_attrs_compute(client_manager, parsed_args):
attrs = {}
if parsed_args.name is not None:
attrs['label'] = str(parsed_args.name)
if parsed_args.shared is not None:
attrs['share_address'] = parsed_args.shared
if parsed_args.subnet is not None:
attrs['cidr'] = parsed_args.subnet
return attrs
class CreateNetwork(common.NetworkAndComputeShowOne):
"""Create new network"""
def get_parser(self, prog_name):
parser = super(CreateNetwork, self).get_parser(prog_name)
def update_parser_common(self, parser):
parser.add_argument(
'name',
metavar='<name>',
help='New network name',
)
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',
dest='admin_state',
action='store_true',
default=True,
help='Enable network (default)',
)
admin_group.add_argument(
'--disable',
dest='admin_state',
action='store_false',
help='Disable network',
)
share_group = parser.add_mutually_exclusive_group()
share_group.add_argument(
'--share',
@ -113,13 +110,29 @@ class CreateNetwork(command.ShowOne):
action='store_false',
help='Do not share the network between projects',
)
return parser
def update_parser_network(self, parser):
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',
dest='admin_state',
action='store_true',
default=True,
help='Enable network (default)',
)
admin_group.add_argument(
'--disable',
dest='admin_state',
action='store_false',
help='Disable network',
)
parser.add_argument(
'--project',
metavar='<project>',
help="Owner's project (name or ID)"
)
identity_common.add_project_domain_option_to_parser(parser)
parser.add_argument(
'--availability-zone-hint',
action='append',
@ -131,16 +144,28 @@ class CreateNetwork(command.ShowOne):
)
return parser
def take_action(self, parsed_args):
client = self.app.client_manager.network
def update_parser_compute(self, parser):
parser.add_argument(
'--subnet',
metavar='<subnet>',
help="IPv4 subnet for fixed IPs (in CIDR notation)"
)
return parser
def take_action_network(self, client, parsed_args):
attrs = _get_attrs(self.app.client_manager, parsed_args)
obj = client.create_network(**attrs)
columns = _get_columns(obj)
data = utils.get_item_properties(obj, columns, formatters=_formatters)
return (columns, data)
def take_action_compute(self, client, parsed_args):
attrs = _get_attrs_compute(self.app.client_manager, parsed_args)
obj = client.networks.create(**attrs)
columns = tuple(sorted(obj._info.keys()))
data = utils.get_dict_properties(obj._info, columns)
return (columns, data)
class DeleteNetwork(common.NetworkAndComputeCommand):
"""Delete network(s)"""

View File

@ -576,6 +576,120 @@ class TestNetworkCompute(compute_fakes.TestComputev2):
self.compute = self.app.client_manager.compute
class TestCreateNetworkCompute(TestNetworkCompute):
# The network to create.
_network = compute_fakes.FakeNetwork.create_one_network()
columns = (
'bridge',
'bridge_interface',
'broadcast',
'cidr',
'cidr_v6',
'created_at',
'deleted',
'deleted_at',
'dhcp_server',
'dhcp_start',
'dns1',
'dns2',
'enable_dhcp',
'gateway',
'gateway_v6',
'host',
'id',
'injected',
'label',
'mtu',
'multi_host',
'netmask',
'netmask_v6',
'priority',
'project_id',
'rxtx_base',
'share_address',
'updated_at',
'vlan',
'vpn_private_address',
'vpn_public_address',
'vpn_public_port',
)
data = (
_network.bridge,
_network.bridge_interface,
_network.broadcast,
_network.cidr,
_network.cidr_v6,
_network.created_at,
_network.deleted,
_network.deleted_at,
_network.dhcp_server,
_network.dhcp_start,
_network.dns1,
_network.dns2,
_network.enable_dhcp,
_network.gateway,
_network.gateway_v6,
_network.host,
_network.id,
_network.injected,
_network.label,
_network.mtu,
_network.multi_host,
_network.netmask,
_network.netmask_v6,
_network.priority,
_network.project_id,
_network.rxtx_base,
_network.share_address,
_network.updated_at,
_network.vlan,
_network.vpn_private_address,
_network.vpn_public_address,
_network.vpn_public_port,
)
def setUp(self):
super(TestCreateNetworkCompute, self).setUp()
self.app.client_manager.network_endpoint_enabled = False
self.compute.networks.create.return_value = self._network
# Get the command object to test
self.cmd = network.CreateNetwork(self.app, None)
def test_create_no_options(self):
arglist = []
verifylist = []
# Missing required args should raise exception here
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
def test_create_default_options(self):
arglist = [
"--subnet", self._network.cidr,
self._network.label,
]
verifylist = [
('subnet', self._network.cidr),
('name', self._network.label),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.compute.networks.create.assert_called_with(**{
'cidr': self._network.cidr,
'label': self._network.label,
})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
class TestDeleteNetworkCompute(TestNetworkCompute):
# The network to delete.

View File

@ -6,3 +6,5 @@ features:
[Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
- Command ``network show`` is now available for nova network.
[Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
- Command ``network create`` is now available for nova network.
[Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]