Network CRUD
bp/neutron https://wiki.openstack.org/wiki/OpenStackClient/Commands#Network_2 Change-Id: I89ee083154afa544b03587e84becace36d9d522a
This commit is contained in:
parent
adf9349c40
commit
8f59524c3e
@ -84,6 +84,16 @@ def format_dict(data):
|
||||
return output[:-2]
|
||||
|
||||
|
||||
def format_list(data):
|
||||
"""Return a formatted strings
|
||||
|
||||
:param data: a list of strings
|
||||
:rtype: a string formatted to a,b,c
|
||||
"""
|
||||
|
||||
return ', '.join(data)
|
||||
|
||||
|
||||
def get_item_properties(item, fields, mixed_case_fields=[], formatters={}):
|
||||
"""Return a tuple containing the item properties.
|
||||
|
||||
|
0
openstackclient/network/__init__.py
Normal file
0
openstackclient/network/__init__.py
Normal file
61
openstackclient/network/client.py
Normal file
61
openstackclient/network/client.py
Normal file
@ -0,0 +1,61 @@
|
||||
# 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 logging
|
||||
|
||||
from openstackclient.common import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NETWORK_API_VERSION = '2.0'
|
||||
API_VERSION_OPTION = 'os_network_api_version'
|
||||
API_NAME = "network"
|
||||
API_VERSIONS = {
|
||||
"2.0": "neutronclient.v2_0.client.Client",
|
||||
}
|
||||
|
||||
|
||||
def make_client(instance):
|
||||
"""Returns an network service client."""
|
||||
network_client = utils.get_client_class(
|
||||
API_NAME,
|
||||
instance._api_version[API_NAME],
|
||||
API_VERSIONS)
|
||||
if not instance._url:
|
||||
instance._url = instance.get_endpoint_for_service_type("network")
|
||||
return network_client(
|
||||
username=instance._username,
|
||||
tenant_name=instance._project_name,
|
||||
password=instance._password,
|
||||
region_name=instance._region_name,
|
||||
auth_url=instance._auth_url,
|
||||
endpoint_url=instance._url,
|
||||
token=instance._token,
|
||||
insecure=instance._insecure,
|
||||
ca_cert=instance._cacert,
|
||||
)
|
||||
|
||||
|
||||
def build_option_parser(parser):
|
||||
"""Hook to add global options"""
|
||||
parser.add_argument(
|
||||
'--os-network-api-version',
|
||||
metavar='<network-api-version>',
|
||||
default=utils.env(
|
||||
'OS_NETWORK_API_VERSION',
|
||||
default=DEFAULT_NETWORK_API_VERSION),
|
||||
help='Network API version, default=' +
|
||||
DEFAULT_NETWORK_API_VERSION +
|
||||
' (Env: OS_NETWORK_API_VERSION)')
|
||||
return parser
|
43
openstackclient/network/common.py
Normal file
43
openstackclient/network/common.py
Normal file
@ -0,0 +1,43 @@
|
||||
# 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 openstackclient.common import exceptions
|
||||
|
||||
|
||||
def find(client, resource, resources, name_or_id):
|
||||
"""Find a network resource
|
||||
|
||||
:param client: network client
|
||||
:param resource: name of the resource
|
||||
:param resources: plural name of resource
|
||||
:param name_or_id: name or id of resource user is looking for
|
||||
|
||||
For example:
|
||||
n = find(netclient, 'network', 'networks', 'matrix')
|
||||
"""
|
||||
list_method = getattr(client, "list_%s" % resources)
|
||||
# Search for by name
|
||||
data = list_method(name=name_or_id, fields='id')
|
||||
info = data[resources]
|
||||
if len(info) == 1:
|
||||
return info[0]['id']
|
||||
if len(info) > 1:
|
||||
msg = "More than one %s exists with the name '%s'."
|
||||
raise exceptions.CommandError(msg % (resource, name_or_id))
|
||||
# Search for by id
|
||||
data = list_method(id=name_or_id, fields='id')
|
||||
info = data[resources]
|
||||
if len(info) == 1:
|
||||
return info[0]['id']
|
||||
msg = "No %s with a name or ID of '%s' exists." % (resource, name_or_id)
|
||||
raise exceptions.CommandError(msg)
|
0
openstackclient/network/v2_0/__init__.py
Normal file
0
openstackclient/network/v2_0/__init__.py
Normal file
236
openstackclient/network/v2_0/network.py
Normal file
236
openstackclient/network/v2_0/network.py
Normal file
@ -0,0 +1,236 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""Network action implementations"""
|
||||
|
||||
import logging
|
||||
import six
|
||||
|
||||
from cliff import command
|
||||
from cliff import lister
|
||||
from cliff import show
|
||||
|
||||
from openstackclient.common import exceptions
|
||||
from openstackclient.common import utils
|
||||
from openstackclient.network import common
|
||||
|
||||
|
||||
def filters(data):
|
||||
if 'subnets' in data:
|
||||
data['subnets'] = utils.format_list(data['subnets'])
|
||||
return data
|
||||
|
||||
|
||||
class CreateNetwork(show.ShowOne):
|
||||
"""Create a network"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.CreateNetwork')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateNetwork, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'name', metavar='<network_name>',
|
||||
help='Name of network to create')
|
||||
admin_group = parser.add_mutually_exclusive_group()
|
||||
admin_group.add_argument(
|
||||
'--admin-state-up',
|
||||
dest='admin_state', action='store_true',
|
||||
default=True, help='Set Admin State Up')
|
||||
admin_group.add_argument(
|
||||
'--admin-state-down',
|
||||
dest='admin_state', action='store_false',
|
||||
help='Set Admin State Down')
|
||||
share_group = parser.add_mutually_exclusive_group()
|
||||
share_group.add_argument(
|
||||
'--share',
|
||||
dest='shared', action='store_true',
|
||||
default=None,
|
||||
help='Share the network across tenants')
|
||||
share_group.add_argument(
|
||||
'--no-share',
|
||||
dest='shared', action='store_false',
|
||||
help='Do not share the network across tenants')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)' % parsed_args)
|
||||
client = self.app.client_manager.network
|
||||
body = self.get_body(parsed_args)
|
||||
create_method = getattr(client, "create_network")
|
||||
data = create_method(body)['network']
|
||||
if data:
|
||||
data = filters(data)
|
||||
else:
|
||||
data = {'': ''}
|
||||
return zip(*sorted(six.iteritems(data)))
|
||||
|
||||
def get_body(self, parsed_args):
|
||||
body = {'name': str(parsed_args.name),
|
||||
'admin_state_up': parsed_args.admin_state}
|
||||
if parsed_args.shared is not None:
|
||||
body['shared'] = parsed_args.shared
|
||||
return {'network': body}
|
||||
|
||||
|
||||
class DeleteNetwork(command.Command):
|
||||
|
||||
log = logging.getLogger(__name__ + '.DeleteNetwork')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteNetwork, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'identifier',
|
||||
metavar="<network>",
|
||||
help=("Name or identifier of network to delete")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)' % parsed_args)
|
||||
client = self.app.client_manager.network
|
||||
_id = common.find(client, 'network', 'networks',
|
||||
parsed_args.identifier)
|
||||
delete_method = getattr(client, "delete_network")
|
||||
delete_method(_id)
|
||||
return
|
||||
|
||||
|
||||
class ListNetwork(lister.Lister):
|
||||
"""List networks"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.ListNetwork')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListNetwork, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--external',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='List external networks',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dhcp',
|
||||
help='ID of the DHCP agent')
|
||||
parser.add_argument(
|
||||
'--long',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Long listing',
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)' % parsed_args)
|
||||
client = self.app.client_manager.network
|
||||
if parsed_args.dhcp:
|
||||
list_method = getattr(client, 'list_networks_on_dhcp_agent')
|
||||
resources = 'networks_on_dhcp_agent'
|
||||
report_filter = {'dhcp_agent': parsed_args.dhcp}
|
||||
data = list_method(**report_filter)[resources]
|
||||
else:
|
||||
list_method = getattr(client, "list_networks")
|
||||
report_filter = {}
|
||||
if parsed_args.external:
|
||||
report_filter = {'router:external': True}
|
||||
data = list_method(**report_filter)['networks']
|
||||
columns = len(data) > 0 and sorted(data[0].keys()) or []
|
||||
if parsed_args.columns:
|
||||
list_columns = parsed_args.columns
|
||||
else:
|
||||
list_columns = ['id', 'name', 'subnets']
|
||||
if not parsed_args.long and not parsed_args.dhcp:
|
||||
columns = [x for x in list_columns if x in columns]
|
||||
formatters = {'subnets': utils.format_list}
|
||||
return (columns,
|
||||
(utils.get_dict_properties(s, columns, formatters=formatters)
|
||||
for s in data))
|
||||
|
||||
|
||||
class SetNetwork(command.Command):
|
||||
|
||||
log = logging.getLogger(__name__ + '.SetNetwork')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetNetwork, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'identifier',
|
||||
metavar="<network>",
|
||||
help=("Name or identifier of network to set")
|
||||
)
|
||||
admin_group = parser.add_mutually_exclusive_group()
|
||||
admin_group.add_argument(
|
||||
'--admin-state-up',
|
||||
dest='admin_state', action='store_true',
|
||||
default=None,
|
||||
help='Set Admin State Up')
|
||||
admin_group.add_argument(
|
||||
'--admin-state-down',
|
||||
dest='admin_state', action='store_false',
|
||||
help='Set Admin State Down')
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar='<network_name>',
|
||||
help='New name for the network')
|
||||
share_group = parser.add_mutually_exclusive_group()
|
||||
share_group.add_argument(
|
||||
'--share',
|
||||
dest='shared', action='store_true',
|
||||
default=None,
|
||||
help='Share the network across tenants')
|
||||
share_group.add_argument(
|
||||
'--no-share',
|
||||
dest='shared', action='store_false',
|
||||
help='Do not share the network across tenants')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)' % parsed_args)
|
||||
client = self.app.client_manager.network
|
||||
_id = common.find(client, 'network', 'networks',
|
||||
parsed_args.identifier)
|
||||
body = {}
|
||||
if parsed_args.name is not None:
|
||||
body['name'] = str(parsed_args.name)
|
||||
if parsed_args.admin_state is not None:
|
||||
body['admin_state_up'] = parsed_args.admin_state
|
||||
if parsed_args.shared is not None:
|
||||
body['shared'] = parsed_args.shared
|
||||
if body == {}:
|
||||
raise exceptions.CommandError("Nothing specified to be set")
|
||||
update_method = getattr(client, "update_network")
|
||||
update_method(_id, {'network': body})
|
||||
return
|
||||
|
||||
|
||||
class ShowNetwork(show.ShowOne):
|
||||
|
||||
log = logging.getLogger(__name__ + '.ShowNetwork')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowNetwork, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'identifier',
|
||||
metavar="<network>",
|
||||
help=("Name or identifier of network to show")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)' % parsed_args)
|
||||
client = self.app.client_manager.network
|
||||
_id = common.find(client, 'network', 'networks',
|
||||
parsed_args.identifier)
|
||||
show_method = getattr(client, "show_network")
|
||||
data = show_method(_id)['network']
|
||||
data = filters(data)
|
||||
return zip(*sorted(six.iteritems(data)))
|
@ -52,6 +52,7 @@ class FakeClientManager(object):
|
||||
self.image = None
|
||||
self.object = None
|
||||
self.volume = None
|
||||
self.network = None
|
||||
self.auth_ref = None
|
||||
|
||||
|
||||
|
0
openstackclient/tests/network/__init__.py
Normal file
0
openstackclient/tests/network/__init__.py
Normal file
52
openstackclient/tests/network/common.py
Normal file
52
openstackclient/tests/network/common.py
Normal file
@ -0,0 +1,52 @@
|
||||
# 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 argparse
|
||||
import mock
|
||||
|
||||
from openstackclient.tests import utils
|
||||
|
||||
|
||||
class TestNetworkBase(utils.TestCommand):
|
||||
def setUp(self):
|
||||
super(TestNetworkBase, self).setUp()
|
||||
self.app = mock.Mock(name='app')
|
||||
self.app.client_manager = mock.Mock(name='client_manager')
|
||||
self.namespace = argparse.Namespace()
|
||||
|
||||
given_show_options = [
|
||||
'-f',
|
||||
'shell',
|
||||
'-c',
|
||||
'id',
|
||||
'--prefix',
|
||||
'TST',
|
||||
]
|
||||
then_show_options = [
|
||||
('formatter', 'shell'),
|
||||
('columns', ['id']),
|
||||
('prefix', 'TST'),
|
||||
]
|
||||
given_list_options = [
|
||||
'-f',
|
||||
'csv',
|
||||
'-c',
|
||||
'id',
|
||||
'--quote',
|
||||
'all',
|
||||
]
|
||||
then_list_options = [
|
||||
('formatter', 'csv'),
|
||||
('columns', ['id']),
|
||||
('quote_mode', 'all'),
|
||||
]
|
0
openstackclient/tests/network/v2_0/__init__.py
Normal file
0
openstackclient/tests/network/v2_0/__init__.py
Normal file
319
openstackclient/tests/network/v2_0/test_network.py
Normal file
319
openstackclient/tests/network/v2_0/test_network.py
Normal file
@ -0,0 +1,319 @@
|
||||
# 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 copy
|
||||
import mock
|
||||
|
||||
from openstackclient.common import exceptions
|
||||
from openstackclient.network.v2_0 import network
|
||||
from openstackclient.tests.network import common
|
||||
|
||||
RESOURCE = 'network'
|
||||
RESOURCES = 'networks'
|
||||
FAKE_ID = 'iditty'
|
||||
FAKE_NAME = 'noo'
|
||||
RECORD = {
|
||||
'id': FAKE_ID,
|
||||
'name': FAKE_NAME,
|
||||
'router:external': True,
|
||||
'subnets': ['a', 'b'],
|
||||
}
|
||||
COLUMNS = ['id', 'name', 'subnets']
|
||||
RESPONSE = {RESOURCE: RECORD}
|
||||
FILTERED = [('id', 'name', 'router:external', 'subnets'),
|
||||
(FAKE_ID, FAKE_NAME, True, 'a, b')]
|
||||
|
||||
|
||||
class TestCreateNetwork(common.TestNetworkBase):
|
||||
def test_create_no_options(self):
|
||||
arglist = [
|
||||
FAKE_NAME,
|
||||
]
|
||||
verifylist = [
|
||||
('name', FAKE_NAME),
|
||||
('admin_state', True),
|
||||
('shared', None),
|
||||
]
|
||||
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
|
||||
self.app.client_manager.network.create_network = mocker
|
||||
cmd = network.CreateNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
mocker.assert_called_with({
|
||||
RESOURCE: {
|
||||
'admin_state_up': True,
|
||||
'name': FAKE_NAME,
|
||||
}
|
||||
})
|
||||
self.assertEqual(FILTERED, result)
|
||||
|
||||
def test_create_all_options(self):
|
||||
arglist = [
|
||||
"--admin-state-down",
|
||||
"--share",
|
||||
FAKE_NAME,
|
||||
] + self.given_show_options
|
||||
verifylist = [
|
||||
('admin_state', False),
|
||||
('shared', True),
|
||||
('name', FAKE_NAME),
|
||||
] + self.then_show_options
|
||||
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
|
||||
self.app.client_manager.network.create_network = mocker
|
||||
cmd = network.CreateNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
mocker.assert_called_with({
|
||||
RESOURCE: {
|
||||
'admin_state_up': False,
|
||||
'name': FAKE_NAME,
|
||||
'shared': True,
|
||||
}
|
||||
})
|
||||
self.assertEqual(FILTERED, result)
|
||||
|
||||
def test_create_other_options(self):
|
||||
arglist = [
|
||||
"--admin-state-up",
|
||||
"--no-share",
|
||||
FAKE_NAME,
|
||||
]
|
||||
verifylist = [
|
||||
('admin_state', True),
|
||||
('shared', False),
|
||||
('name', FAKE_NAME),
|
||||
]
|
||||
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
|
||||
self.app.client_manager.network.create_network = mocker
|
||||
cmd = network.CreateNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
mocker.assert_called_with({
|
||||
RESOURCE: {
|
||||
'admin_state_up': True,
|
||||
'name': FAKE_NAME,
|
||||
'shared': False,
|
||||
}
|
||||
})
|
||||
self.assertEqual(FILTERED, result)
|
||||
|
||||
|
||||
class TestDeleteNetwork(common.TestNetworkBase):
|
||||
def test_delete(self):
|
||||
arglist = [
|
||||
FAKE_NAME,
|
||||
]
|
||||
verifylist = [
|
||||
('identifier', FAKE_NAME),
|
||||
]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
mocker = mock.Mock(return_value=None)
|
||||
self.app.client_manager.network.delete_network = mocker
|
||||
cmd = network.DeleteNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
mocker.assert_called_with(FAKE_ID)
|
||||
self.assertEqual(None, result)
|
||||
|
||||
|
||||
class TestListNetwork(common.TestNetworkBase):
|
||||
def test_list_no_options(self):
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('long', False),
|
||||
('dhcp', None),
|
||||
('external', False),
|
||||
]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
cmd = network.ListNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
lister.assert_called_with()
|
||||
self.assertEqual(COLUMNS, result[0])
|
||||
self.assertEqual((FAKE_ID, FAKE_NAME, 'a, b'), next(result[1]))
|
||||
self.assertRaises(StopIteration, next, result[1])
|
||||
|
||||
def test_list_long(self):
|
||||
arglist = ['--long']
|
||||
verifylist = [
|
||||
('long', True),
|
||||
('dhcp', None),
|
||||
('external', False),
|
||||
]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
cmd = network.ListNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
lister.assert_called_with()
|
||||
headings = ['id', 'name', 'router:external', 'subnets']
|
||||
self.assertEqual(headings, result[0])
|
||||
data = (FAKE_ID, FAKE_NAME, True, 'a, b')
|
||||
self.assertEqual(data, next(result[1]))
|
||||
self.assertRaises(StopIteration, next, result[1])
|
||||
|
||||
def test_list_dhcp(self):
|
||||
arglist = [
|
||||
'--dhcp',
|
||||
'dhcpid',
|
||||
] + self.given_list_options
|
||||
verifylist = [
|
||||
('dhcp', 'dhcpid'),
|
||||
] + self.then_list_options
|
||||
fake_dhcp_data = [{'id': '1'}, {'id': '2'}]
|
||||
fake_dhcp_response = {'networks_on_dhcp_agent': fake_dhcp_data}
|
||||
lister = mock.Mock(return_value=fake_dhcp_response)
|
||||
netty = self.app.client_manager.network
|
||||
netty.list_networks_on_dhcp_agent = lister
|
||||
cmd = network.ListNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
lister.assert_called_with(dhcp_agent='dhcpid')
|
||||
self.assertEqual(['id'], result[0])
|
||||
self.assertEqual(('1',), next(result[1]))
|
||||
self.assertEqual(('2',), next(result[1]))
|
||||
self.assertRaises(StopIteration, next, result[1])
|
||||
|
||||
def test_list_external(self):
|
||||
arglist = ['--external', '-c', 'id']
|
||||
verifylist = [('external', True)]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
cmd = network.ListNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
lister.assert_called_with(**{'router:external': True})
|
||||
self.assertEqual(['id'], result[0])
|
||||
self.assertEqual((FAKE_ID,), next(result[1]))
|
||||
self.assertRaises(StopIteration, next, result[1])
|
||||
|
||||
|
||||
class TestSetNetwork(common.TestNetworkBase):
|
||||
def test_set_this(self):
|
||||
arglist = [
|
||||
FAKE_NAME,
|
||||
'--admin-state-up',
|
||||
'--name', 'noob',
|
||||
'--share',
|
||||
]
|
||||
verifylist = [
|
||||
('identifier', FAKE_NAME),
|
||||
('admin_state', True),
|
||||
('name', 'noob'),
|
||||
('shared', True),
|
||||
]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
mocker = mock.Mock(return_value=None)
|
||||
self.app.client_manager.network.update_network = mocker
|
||||
cmd = network.SetNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
exp = {'admin_state_up': True, 'name': 'noob', 'shared': True}
|
||||
exp_record = {RESOURCE: exp}
|
||||
mocker.assert_called_with(FAKE_ID, exp_record)
|
||||
self.assertEqual(None, result)
|
||||
|
||||
def test_set_that(self):
|
||||
arglist = [
|
||||
FAKE_NAME,
|
||||
'--admin-state-down',
|
||||
'--no-share',
|
||||
]
|
||||
verifylist = [
|
||||
('identifier', FAKE_NAME),
|
||||
('admin_state', False),
|
||||
('shared', False),
|
||||
]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
mocker = mock.Mock(return_value=None)
|
||||
self.app.client_manager.network.update_network = mocker
|
||||
cmd = network.SetNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
exp = {'admin_state_up': False, 'shared': False}
|
||||
exp_record = {RESOURCE: exp}
|
||||
mocker.assert_called_with(FAKE_ID, exp_record)
|
||||
self.assertEqual(None, result)
|
||||
|
||||
def test_set_nothing(self):
|
||||
arglist = [FAKE_NAME, ]
|
||||
verifylist = [('identifier', FAKE_NAME), ]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
mocker = mock.Mock(return_value=None)
|
||||
self.app.client_manager.network.update_network = mocker
|
||||
cmd = network.SetNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
self.assertRaises(exceptions.CommandError, cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestShowNetwork(common.TestNetworkBase):
|
||||
def test_show_no_options(self):
|
||||
arglist = [
|
||||
FAKE_NAME,
|
||||
]
|
||||
verifylist = [
|
||||
('identifier', FAKE_NAME),
|
||||
]
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
|
||||
self.app.client_manager.network.show_network = mocker
|
||||
cmd = network.ShowNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
mocker.assert_called_with(FAKE_ID)
|
||||
self.assertEqual(FILTERED, result)
|
||||
|
||||
def test_show_all_options(self):
|
||||
arglist = [FAKE_NAME] + self.given_show_options
|
||||
verifylist = [('identifier', FAKE_NAME)] + self.then_show_options
|
||||
lister = mock.Mock(return_value={RESOURCES: [RECORD]})
|
||||
self.app.client_manager.network.list_networks = lister
|
||||
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
|
||||
self.app.client_manager.network.show_network = mocker
|
||||
cmd = network.ShowNetwork(self.app, self.namespace)
|
||||
|
||||
parsed_args = self.check_parser(cmd, arglist, verifylist)
|
||||
result = cmd.take_action(parsed_args)
|
||||
|
||||
mocker.assert_called_with(FAKE_ID)
|
||||
self.assertEqual(FILTERED, result)
|
@ -39,11 +39,13 @@ DEFAULT_COMPUTE_API_VERSION = "2"
|
||||
DEFAULT_IDENTITY_API_VERSION = "2.0"
|
||||
DEFAULT_IMAGE_API_VERSION = "v2"
|
||||
DEFAULT_VOLUME_API_VERSION = "1"
|
||||
DEFAULT_NETWORK_API_VERSION = "2.0"
|
||||
|
||||
LIB_COMPUTE_API_VERSION = "2"
|
||||
LIB_IDENTITY_API_VERSION = "2.0"
|
||||
LIB_IMAGE_API_VERSION = "1"
|
||||
LIB_VOLUME_API_VERSION = "1"
|
||||
LIB_NETWORK_API_VERSION = "2.0"
|
||||
|
||||
|
||||
def make_shell():
|
||||
@ -128,6 +130,8 @@ class TestShell(utils.TestCase):
|
||||
default_args["image_api_version"])
|
||||
self.assertEqual(_shell.options.os_volume_api_version,
|
||||
default_args["volume_api_version"])
|
||||
self.assertEqual(_shell.options.os_network_api_version,
|
||||
default_args["network_api_version"])
|
||||
|
||||
|
||||
class TestShellHelp(TestShell):
|
||||
@ -455,6 +459,7 @@ class TestShellCli(TestShell):
|
||||
"OS_IDENTITY_API_VERSION": DEFAULT_IDENTITY_API_VERSION,
|
||||
"OS_IMAGE_API_VERSION": DEFAULT_IMAGE_API_VERSION,
|
||||
"OS_VOLUME_API_VERSION": DEFAULT_VOLUME_API_VERSION,
|
||||
"OS_NETWORK_API_VERSION": DEFAULT_NETWORK_API_VERSION,
|
||||
}
|
||||
self.orig_env, os.environ = os.environ, env.copy()
|
||||
|
||||
@ -475,7 +480,8 @@ class TestShellCli(TestShell):
|
||||
"compute_api_version": DEFAULT_COMPUTE_API_VERSION,
|
||||
"identity_api_version": DEFAULT_IDENTITY_API_VERSION,
|
||||
"image_api_version": DEFAULT_IMAGE_API_VERSION,
|
||||
"volume_api_version": DEFAULT_VOLUME_API_VERSION
|
||||
"volume_api_version": DEFAULT_VOLUME_API_VERSION,
|
||||
"network_api_version": DEFAULT_NETWORK_API_VERSION,
|
||||
}
|
||||
self._assert_cli(flag, kwargs)
|
||||
|
||||
@ -486,6 +492,7 @@ class TestShellCli(TestShell):
|
||||
"compute_api_version": LIB_COMPUTE_API_VERSION,
|
||||
"identity_api_version": LIB_IDENTITY_API_VERSION,
|
||||
"image_api_version": LIB_IMAGE_API_VERSION,
|
||||
"volume_api_version": LIB_VOLUME_API_VERSION
|
||||
"volume_api_version": LIB_VOLUME_API_VERSION,
|
||||
"network_api_version": LIB_NETWORK_API_VERSION
|
||||
}
|
||||
self._assert_cli(flag, kwargs)
|
||||
|
@ -6,5 +6,6 @@ python-glanceclient>=0.9.0
|
||||
python-keystoneclient>=0.9.0
|
||||
python-novaclient>=2.17.0
|
||||
python-cinderclient>=1.0.6
|
||||
python-neutronclient>=2.3.4,<3
|
||||
requests>=1.1
|
||||
six>=1.7.0
|
||||
|
@ -33,6 +33,7 @@ openstack.cli.extension =
|
||||
image = openstackclient.image.client
|
||||
object_store = openstackclient.object.client
|
||||
volume = openstackclient.volume.client
|
||||
network = openstackclient.network.client
|
||||
|
||||
openstack.common =
|
||||
limits_show = openstackclient.common.limits:ShowLimits
|
||||
@ -289,6 +290,13 @@ openstack.volume.v1 =
|
||||
volume_type_set = openstackclient.volume.v1.type:SetVolumeType
|
||||
volume_type_unset = openstackclient.volume.v1.type:UnsetVolumeType
|
||||
|
||||
openstack.network.v2_0 =
|
||||
network_create = openstackclient.network.v2_0.network:CreateNetwork
|
||||
network_delete = openstackclient.network.v2_0.network:DeleteNetwork
|
||||
network_list = openstackclient.network.v2_0.network:ListNetwork
|
||||
network_set = openstackclient.network.v2_0.network:SetNetwork
|
||||
network_show = openstackclient.network.v2_0.network:ShowNetwork
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
|
Loading…
Reference in New Issue
Block a user