summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/clientmanager.py10
-rw-r--r--openstackclient/common/utils.py8
-rw-r--r--openstackclient/compute/client.py5
-rw-r--r--openstackclient/compute/v2/hypervisor.py23
-rw-r--r--openstackclient/compute/v2/server.py52
-rw-r--r--openstackclient/identity/client.py7
-rw-r--r--openstackclient/identity/v2_0/catalog.py2
-rw-r--r--openstackclient/image/client.py2
-rw-r--r--openstackclient/image/v1/image.py142
-rw-r--r--openstackclient/network/client.py6
-rw-r--r--openstackclient/object/client.py1
-rw-r--r--openstackclient/shell.py14
-rw-r--r--openstackclient/tests/common/test_clientmanager.py11
-rw-r--r--openstackclient/tests/common/test_utils.py10
-rw-r--r--openstackclient/tests/compute/v2/test_server.py56
-rw-r--r--openstackclient/tests/fakes.py2
-rw-r--r--openstackclient/tests/identity/v2_0/test_catalog.py18
-rw-r--r--openstackclient/tests/image/v1/test_image.py132
-rw-r--r--openstackclient/tests/network/common.py27
-rw-r--r--openstackclient/tests/network/v2/test_network.py8
-rw-r--r--openstackclient/tests/test_shell.py8
-rw-r--r--openstackclient/tests/volume/v1/test_qos_specs.py2
-rw-r--r--openstackclient/tests/volume/v2/test_qos_specs.py2
-rw-r--r--openstackclient/volume/client.py5
24 files changed, 386 insertions, 167 deletions
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index 0159ad7d..fae95630 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -86,6 +86,7 @@ class ClientManager(object):
self._pw_callback = pw_func
self._url = self._cli_options.auth.get('url', None)
self._region_name = self._cli_options.region_name
+ self._endpoint_type = self._cli_options.endpoint_type
self.timing = self._cli_options.timing
@@ -183,18 +184,23 @@ class ClientManager(object):
self._auth_ref = self.auth.get_auth_ref(self.session)
return self._auth_ref
- def get_endpoint_for_service_type(self, service_type, region_name=None):
+ def get_endpoint_for_service_type(self, service_type, region_name=None,
+ endpoint_type='public'):
"""Return the endpoint URL for the service type."""
+ if not endpoint_type:
+ endpoint_type = 'public'
# See if we are using password flow auth, i.e. we have a
# service catalog to select endpoints from
if self.auth_ref:
endpoint = self.auth_ref.service_catalog.url_for(
service_type=service_type,
region_name=region_name,
+ endpoint_type=endpoint_type,
)
else:
# Get the passed endpoint directly from the auth plugin
- endpoint = self.auth.get_endpoint(self.session)
+ endpoint = self.auth.get_endpoint(self.session,
+ interface=endpoint_type)
return endpoint
diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py
index c824678e..6cd35c05 100644
--- a/openstackclient/common/utils.py
+++ b/openstackclient/common/utils.py
@@ -368,3 +368,11 @@ def read_blob_file_contents(blob_file):
except IOError:
msg = "Error occurred trying to read from file %s"
raise exceptions.CommandError(msg % blob_file)
+
+
+def build_kwargs_dict(arg_name, value):
+ """Return a dictionary containing `arg_name` if `value` is set."""
+ kwargs = {}
+ if value:
+ kwargs[arg_name] = value
+ return kwargs
diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py
index 93a7b715..27d63a95 100644
--- a/openstackclient/compute/client.py
+++ b/openstackclient/compute/client.py
@@ -48,12 +48,17 @@ def make_client(instance):
extensions = [extension.Extension('list_extensions', list_extensions)]
+ # Remember endpoint_type only if it is set
+ kwargs = utils.build_kwargs_dict('endpoint_type',
+ instance._endpoint_type)
+
client = compute_client(
session=instance.session,
extensions=extensions,
http_log_debug=http_log_debug,
timings=instance.timing,
region_name=instance._region_name,
+ **kwargs
)
return client
diff --git a/openstackclient/compute/v2/hypervisor.py b/openstackclient/compute/v2/hypervisor.py
index 65035d04..f33beb08 100644
--- a/openstackclient/compute/v2/hypervisor.py
+++ b/openstackclient/compute/v2/hypervisor.py
@@ -77,6 +77,29 @@ class ShowHypervisor(show.ShowOne):
hypervisor = utils.find_resource(compute_client.hypervisors,
parsed_args.hypervisor)._info.copy()
+ aggregates = compute_client.aggregates.list()
+ hypervisor["aggregates"] = list()
+ if aggregates:
+ # Hypervisors in nova cells are prefixed by "<cell>@"
+ if "@" in hypervisor['service']['host']:
+ cell, service_host = hypervisor['service']['host'].split('@',
+ 1)
+ else:
+ cell = None
+ service_host = hypervisor['service']['host']
+
+ if cell:
+ # The host aggregates are also prefixed by "<cell>@"
+ member_of = [aggregate.name
+ for aggregate in aggregates
+ if cell in aggregate.name and
+ service_host in aggregate.hosts]
+ else:
+ member_of = [aggregate.name
+ for aggregate in aggregates
+ if service_host in aggregate.hosts]
+ hypervisor["aggregates"] = member_of
+
uptime = compute_client.hypervisors.uptime(hypervisor['id'])._info
# Extract data from uptime value
# format: 0 up 0, 0 users, load average: 0, 0, 0
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 5007b072..4efef975 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -55,6 +55,39 @@ def _format_servers_list_networks(networks):
return '; '.join(output)
+def _get_ip_address(addresses, address_type, ip_address_family):
+ # Old style addresses
+ if address_type in addresses:
+ for addy in addresses[address_type]:
+ if int(addy['version']) in ip_address_family:
+ return addy['addr']
+
+ # New style addresses
+ new_address_type = address_type
+ if address_type == 'public':
+ new_address_type = 'floating'
+ if address_type == 'private':
+ new_address_type = 'fixed'
+ for network in addresses:
+ for addy in addresses[network]:
+ # Case where it is list of strings
+ if isinstance(addy, six.string_types):
+ if new_address_type == 'fixed':
+ return addresses[network][0]
+ else:
+ return addresses[network][-1]
+ # Case where it is a dict
+ if 'OS-EXT-IPS:type' not in addy:
+ continue
+ if addy['OS-EXT-IPS:type'] == new_address_type:
+ if int(addy['version']) in ip_address_family:
+ return addy['addr']
+ raise exceptions.CommandError(
+ "ERROR: No %s IP version %s address found" %
+ (address_type, ip_address_family)
+ )
+
+
def _prep_server_detail(compute_client, server):
"""Prepare the detailed server dict for printing
@@ -1283,6 +1316,7 @@ class SshServer(command.Command):
)
parser.add_argument(
'-l',
+ dest='login',
metavar='<login-name>',
help=argparse.SUPPRESS,
)
@@ -1381,13 +1415,6 @@ class SshServer(command.Command):
# Build the command
cmd = "ssh"
- # Look for address type
- if parsed_args.address_type:
- address_type = parsed_args.address_type
- if address_type not in server.addresses:
- raise SystemExit("ERROR: No %s IP address found" % address_type)
-
- # Set up desired address family
ip_address_family = [4, 6]
if parsed_args.ipv4:
ip_address_family = [4]
@@ -1396,14 +1423,6 @@ class SshServer(command.Command):
ip_address_family = [6]
cmd += " -6"
- # Grab the first matching IP address
- ip_address = None
- for addr in server.addresses[address_type]:
- if int(addr['version']) in ip_address_family:
- ip_address = addr['addr']
- if not ip_address:
- raise SystemExit("ERROR: No IP address found")
-
if parsed_args.port:
cmd += " -p %d" % parsed_args.port
if parsed_args.identity:
@@ -1418,6 +1437,9 @@ class SshServer(command.Command):
cmd += " -v"
cmd += " %s@%s"
+ ip_address = _get_ip_address(server.addresses,
+ parsed_args.address_type,
+ ip_address_family)
self.log.debug("ssh command: %s", (cmd % (login, ip_address)))
os.system(cmd % (login, ip_address))
diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py
index 4127a451..cc803511 100644
--- a/openstackclient/identity/client.py
+++ b/openstackclient/identity/client.py
@@ -46,10 +46,15 @@ def make_client(instance):
API_VERSIONS)
LOG.debug('Instantiating identity client: %s', identity_client)
+ # Remember interface only if endpoint_type is set
+ kwargs = utils.build_kwargs_dict('interface',
+ instance._endpoint_type)
+
client = identity_client(
session=instance.session,
region_name=instance._region_name,
- )
+ **kwargs
+ )
return client
diff --git a/openstackclient/identity/v2_0/catalog.py b/openstackclient/identity/v2_0/catalog.py
index 7d17fbf5..c10001d0 100644
--- a/openstackclient/identity/v2_0/catalog.py
+++ b/openstackclient/identity/v2_0/catalog.py
@@ -31,7 +31,7 @@ def _format_endpoints(eps=None):
region = eps[index].get('region', '<none>')
ret += region + '\n'
for url in ['publicURL', 'internalURL', 'adminURL']:
- ret += " %s: %s\n" % (url, eps[index]['publicURL'])
+ ret += " %s: %s\n" % (url, eps[index][url])
return ret
diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py
index c78f4425..8e2d6cd9 100644
--- a/openstackclient/image/client.py
+++ b/openstackclient/image/client.py
@@ -46,6 +46,7 @@ def make_client(instance):
endpoint = instance.get_endpoint_for_service_type(
API_NAME,
region_name=instance._region_name,
+ endpoint_type=instance._endpoint_type,
)
client = image_client(
@@ -68,6 +69,7 @@ def make_client(instance):
endpoint=instance.get_endpoint_for_service_type(
IMAGE_API_TYPE,
region_name=instance._region_name,
+ endpoint_type=instance._endpoint_type,
)
)
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index 85a9e076..68c81cd5 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -33,7 +33,6 @@ from cliff import show
from glanceclient.common import utils as gc_utils
from openstackclient.api import utils as api_utils
-from openstackclient.common import exceptions
from openstackclient.common import parseractions
from openstackclient.common import utils
@@ -244,29 +243,7 @@ class CreateImage(show.ShowOne):
# Wrap the call to catch exceptions in order to close files
try:
- try:
- image = utils.find_resource(
- image_client.images,
- parsed_args.name,
- )
-
- # Preserve previous properties if any are being set now
- if image.properties:
- if parsed_args.properties:
- image.properties.update(kwargs['properties'])
- kwargs['properties'] = image.properties
-
- except exceptions.CommandError:
- if not parsed_args.volume:
- # This is normal for a create or reserve (create w/o
- # an image), but skip for create from volume
- image = image_client.images.create(**kwargs)
- else:
- # Update an existing reservation
-
- # If an image is specified via --file, --location or
- # --copy-from let the API handle it
- image = image_client.images.update(image.id, **kwargs)
+ image = image_client.images.create(**kwargs)
finally:
# Clean up open files - make sure data isn't a string
if ('data' in kwargs and hasattr(kwargs['data'], 'close') and
@@ -561,6 +538,51 @@ class SetImage(show.ShowOne):
help="Set a property on this image "
"(repeat option to set multiple properties)",
)
+ parser.add_argument(
+ "--store",
+ metavar="<store>",
+ help="Upload image to this store",
+ )
+ parser.add_argument(
+ "--location",
+ metavar="<image-url>",
+ help="Download image from an existing URL",
+ )
+ parser.add_argument(
+ "--copy-from",
+ metavar="<image-url>",
+ help="Copy image from the data store (similar to --location)",
+ )
+ parser.add_argument(
+ "--file",
+ metavar="<file>",
+ help="Upload image from local file",
+ )
+ parser.add_argument(
+ "--volume",
+ metavar="<volume>",
+ help="Create image from a volume",
+ )
+ parser.add_argument(
+ "--force",
+ dest='force',
+ action='store_true',
+ default=False,
+ help="Force image change if volume is in use "
+ "(only meaningful with --volume)",
+ )
+ parser.add_argument(
+ "--stdin",
+ dest='stdin',
+ action='store_true',
+ default=False,
+ help="Read image data from standard input",
+ )
+ parser.add_argument(
+ "--checksum",
+ metavar="<checksum>",
+ help="Image hash used for verification",
+ )
return parser
def take_action(self, parsed_args):
@@ -569,7 +591,8 @@ class SetImage(show.ShowOne):
kwargs = {}
copy_attrs = ('name', 'owner', 'min_disk', 'min_ram', 'properties',
- 'container_format', 'disk_format', 'size')
+ 'container_format', 'disk_format', 'size', 'store',
+ 'location', 'copy_from', 'volume', 'force', 'checksum')
for attr in copy_attrs:
if attr in parsed_args:
val = getattr(parsed_args, attr, None)
@@ -592,20 +615,63 @@ class SetImage(show.ShowOne):
if parsed_args.private:
kwargs['is_public'] = False
- if not kwargs:
- self.log.warning('no arguments specified')
- return {}, {}
-
- image = utils.find_resource(
- image_client.images,
- parsed_args.image,
- )
-
- if image.properties and parsed_args.properties:
- image.properties.update(kwargs['properties'])
- kwargs['properties'] = image.properties
+ # Wrap the call to catch exceptions in order to close files
+ try:
+ image = utils.find_resource(
+ image_client.images,
+ parsed_args.image,
+ )
- image = image_client.images.update(image.id, **kwargs)
+ if not parsed_args.location and not parsed_args.copy_from:
+ if parsed_args.volume:
+ volume_client = self.app.client_manager.volume
+ source_volume = utils.find_resource(
+ volume_client.volumes,
+ parsed_args.volume,
+ )
+ response, body = volume_client.volumes.upload_to_image(
+ source_volume.id,
+ parsed_args.force,
+ parsed_args.image,
+ (parsed_args.container_format
+ if parsed_args.container_format
+ else image.container_format),
+ (parsed_args.disk_format
+ if parsed_args.disk_format
+ else image.disk_format),
+ )
+ info = body['os-volume_upload_image']
+ elif parsed_args.file:
+ # Send an open file handle to glanceclient so it will
+ # do a chunked transfer
+ kwargs["data"] = io.open(parsed_args.file, "rb")
+ else:
+ # Read file from stdin
+ if sys.stdin.isatty() is not True:
+ if parsed_args.stdin:
+ if msvcrt:
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+ # Send an open file handle to glanceclient so it
+ # will do a chunked transfer
+ kwargs["data"] = sys.stdin
+ else:
+ self.log.warning('Use --stdin to enable read image'
+ ' data from standard input')
+
+ if image.properties and parsed_args.properties:
+ image.properties.update(kwargs['properties'])
+ kwargs['properties'] = image.properties
+
+ if not kwargs:
+ self.log.warning('no arguments specified')
+ return {}, {}
+
+ image = image_client.images.update(image.id, **kwargs)
+ finally:
+ # Clean up open files - make sure data isn't a string
+ if ('data' in kwargs and hasattr(kwargs['data'], 'close') and
+ kwargs['data'] != sys.stdin):
+ kwargs['data'].close()
info = {}
info.update(image._info)
diff --git a/openstackclient/network/client.py b/openstackclient/network/client.py
index 870566aa..de08e5e2 100644
--- a/openstackclient/network/client.py
+++ b/openstackclient/network/client.py
@@ -47,11 +47,17 @@ def make_client(instance):
endpoint = instance.get_endpoint_for_service_type(
API_NAME,
region_name=instance._region_name,
+ endpoint_type=instance._endpoint_type,
)
+ # Remember endpoint_type only if it is set
+ kwargs = utils.build_kwargs_dict('endpoint_type',
+ instance._endpoint_type)
+
client = network_client(
session=instance.session,
region_name=instance._region_name,
+ **kwargs
)
network_api = utils.get_client_class(
diff --git a/openstackclient/object/client.py b/openstackclient/object/client.py
index beb7c04f..676f6642 100644
--- a/openstackclient/object/client.py
+++ b/openstackclient/object/client.py
@@ -36,6 +36,7 @@ def make_client(instance):
endpoint = instance.get_endpoint_for_service_type(
'object-store',
region_name=instance._region_name,
+ endpoint_type=instance._endpoint_type,
)
client = object_store_v1.APIv1(
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index 4109b8bc..b4e5904c 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -209,6 +209,15 @@ class OpenStackShell(app.App):
DEFAULT_DOMAIN +
' (Env: OS_DEFAULT_DOMAIN)')
parser.add_argument(
+ '--os-endpoint-type',
+ metavar='<endpoint-type>',
+ dest='endpoint_type',
+ choices=['admin', 'public', 'internal'],
+ default=utils.env('OS_ENDPOINT_TYPE'),
+ help='Select an endpoint type.'
+ ' Valid endpoint types: [admin, public, internal].'
+ ' (Env: OS_ENDPOINT_TYPE)')
+ parser.add_argument(
'--timing',
default=False,
action='store_true',
@@ -254,7 +263,10 @@ class OpenStackShell(app.App):
self.options.project_name = tenant_name
# Do configuration file handling
- cc = cloud_config.OpenStackConfig()
+ # Ignore the default value of endpoint_type. Only if it is set later
+ # will it be used.
+ cc = cloud_config.OpenStackConfig(
+ override_defaults={'endpoint_type': None, })
self.log.debug("defaults: %s", cc.defaults)
self.cloud = cc.get_one_cloud(
diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py
index 4e2f46b4..e86ef509 100644
--- a/openstackclient/tests/common/test_clientmanager.py
+++ b/openstackclient/tests/common/test_clientmanager.py
@@ -54,6 +54,7 @@ class FakeOptions(object):
self.identity_api_version = '2.0'
self.timing = None
self.region_name = None
+ self.endpoint_type = None
self.url = None
self.auth = {}
self.default_domain = 'default'
@@ -123,6 +124,8 @@ class TestClientManager(utils.TestCase):
auth_url=fakes.AUTH_URL,
),
auth_type='v2token',
+ endpoint_type=fakes.ENDPOINT_TYPE,
+ region_name=fakes.REGION_NAME,
),
api_version=API_VERSION,
verify=True
@@ -137,6 +140,14 @@ class TestClientManager(utils.TestCase):
client_manager.auth,
auth_v2.Token,
)
+ self.assertEqual(
+ fakes.ENDPOINT_TYPE,
+ client_manager._endpoint_type,
+ )
+ self.assertEqual(
+ fakes.REGION_NAME,
+ client_manager._region_name,
+ )
self.assertFalse(client_manager._insecure)
self.assertTrue(client_manager._verify)
diff --git a/openstackclient/tests/common/test_utils.py b/openstackclient/tests/common/test_utils.py
index d9f5b7a5..a25a5ba5 100644
--- a/openstackclient/tests/common/test_utils.py
+++ b/openstackclient/tests/common/test_utils.py
@@ -159,6 +159,16 @@ class TestUtils(test_utils.TestCase):
self.assertFalse(utils.wait_for_delete(manager, res_id))
self.assertFalse(mock_sleep.called)
+ def test_build_kwargs_dict_value_set(self):
+ self.assertEqual({'arg_bla': 'bla'},
+ utils.build_kwargs_dict('arg_bla', 'bla'))
+
+ def test_build_kwargs_dict_value_None(self):
+ self.assertEqual({}, utils.build_kwargs_dict('arg_bla', None))
+
+ def test_build_kwargs_dict_value_empty_str(self):
+ self.assertEqual({}, utils.build_kwargs_dict('arg_bla', ''))
+
class NoUniqueMatch(Exception):
pass
diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py
index a8a1936d..4df18f05 100644
--- a/openstackclient/tests/compute/v2/test_server.py
+++ b/openstackclient/tests/compute/v2/test_server.py
@@ -15,7 +15,9 @@
import copy
import mock
+import testtools
+from openstackclient.common import exceptions
from openstackclient.common import utils as common_utils
from openstackclient.compute.v2 import server
from openstackclient.tests.compute.v2 import fakes as compute_fakes
@@ -250,7 +252,7 @@ class TestServerCreate(TestServer):
mock_open.assert_called_with('userdata.sh')
# Ensure the userdata file is closed
- mock_file.close.assert_called()
+ mock_file.close.assert_called_with()
# Set expected values
kwargs = dict(
@@ -580,3 +582,55 @@ class TestServerResize(TestServer):
self.servers_mock.revert_resize.assert_called_with(
self.servers_get_return_value,
)
+
+
+class TestServerGeneral(testtools.TestCase):
+ OLD = {
+ 'private': [
+ {
+ 'addr': '192.168.0.3',
+ 'version': 4,
+ },
+ ]
+ }
+ NEW = {
+ 'foo': [
+ {
+ 'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:93:b3:01',
+ 'version': 4,
+ 'addr': '10.10.1.2',
+ 'OS-EXT-IPS:type': 'fixed',
+ },
+ {
+ 'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:93:b3:02',
+ 'version': 6,
+ 'addr': '0:0:0:0:0:ffff:a0a:103',
+ 'OS-EXT-IPS:type': 'floating',
+ },
+ ]
+ }
+ ODD = {'jenkins': ['10.3.3.18', '124.12.125.4']}
+
+ def test_get_ip_address(self):
+ self.assertEqual("192.168.0.3",
+ server._get_ip_address(self.OLD, 'private', [4, 6]))
+ self.assertEqual("10.10.1.2",
+ server._get_ip_address(self.NEW, 'fixed', [4, 6]))
+ self.assertEqual("10.10.1.2",
+ server._get_ip_address(self.NEW, 'private', [4, 6]))
+ self.assertEqual("0:0:0:0:0:ffff:a0a:103",
+ server._get_ip_address(self.NEW, 'public', [6]))
+ self.assertEqual("0:0:0:0:0:ffff:a0a:103",
+ server._get_ip_address(self.NEW, 'floating', [6]))
+ self.assertEqual("124.12.125.4",
+ server._get_ip_address(self.ODD, 'public', [4, 6]))
+ self.assertEqual("10.3.3.18",
+ server._get_ip_address(self.ODD, 'private', [4, 6]))
+ self.assertRaises(exceptions.CommandError,
+ server._get_ip_address, self.NEW, 'public', [4])
+ self.assertRaises(exceptions.CommandError,
+ server._get_ip_address, self.NEW, 'admin', [4])
+ self.assertRaises(exceptions.CommandError,
+ server._get_ip_address, self.OLD, 'public', [4, 6])
+ self.assertRaises(exceptions.CommandError,
+ server._get_ip_address, self.OLD, 'private', [6])
diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py
index 323f9543..a9322ec3 100644
--- a/openstackclient/tests/fakes.py
+++ b/openstackclient/tests/fakes.py
@@ -26,6 +26,8 @@ AUTH_URL = "http://0.0.0.0"
USERNAME = "itchy"
PASSWORD = "scratchy"
PROJECT_NAME = "poochie"
+REGION_NAME = "richie"
+ENDPOINT_TYPE = "catchy"
TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN,
user_name=USERNAME)
diff --git a/openstackclient/tests/identity/v2_0/test_catalog.py b/openstackclient/tests/identity/v2_0/test_catalog.py
index 50445954..fe13d78d 100644
--- a/openstackclient/tests/identity/v2_0/test_catalog.py
+++ b/openstackclient/tests/identity/v2_0/test_catalog.py
@@ -27,11 +27,13 @@ class TestCatalog(utils.TestCommand):
{
'region': 'one',
'publicURL': 'https://public.one.example.com',
+ 'internalURL': 'https://internal.one.example.com',
'adminURL': 'https://admin.one.example.com',
},
{
'region': 'two',
'publicURL': 'https://public.two.example.com',
+ 'internalURL': 'https://internal.two.example.com',
'adminURL': 'https://admin.two.example.com',
},
],
@@ -74,11 +76,11 @@ class TestCatalogList(TestCatalog):
'supernova',
'compute',
'one\n publicURL: https://public.one.example.com\n '
- 'internalURL: https://public.one.example.com\n '
- 'adminURL: https://public.one.example.com\n'
+ 'internalURL: https://internal.one.example.com\n '
+ 'adminURL: https://admin.one.example.com\n'
'two\n publicURL: https://public.two.example.com\n '
- 'internalURL: https://public.two.example.com\n '
- 'adminURL: https://public.two.example.com\n',
+ 'internalURL: https://internal.two.example.com\n '
+ 'adminURL: https://admin.two.example.com\n',
), )
self.assertEqual(datalist, tuple(data))
@@ -108,11 +110,11 @@ class TestCatalogShow(TestCatalog):
self.assertEqual(collist, columns)
datalist = (
'one\n publicURL: https://public.one.example.com\n '
- 'internalURL: https://public.one.example.com\n '
- 'adminURL: https://public.one.example.com\n'
+ 'internalURL: https://internal.one.example.com\n '
+ 'adminURL: https://admin.one.example.com\n'
'two\n publicURL: https://public.two.example.com\n '
- 'internalURL: https://public.two.example.com\n '
- 'adminURL: https://public.two.example.com\n',
+ 'internalURL: https://internal.two.example.com\n '
+ 'adminURL: https://admin.two.example.com\n',
'qwertyuiop',
'supernova',
'compute',
diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py
index eec8cfa5..a79df8b4 100644
--- a/openstackclient/tests/image/v1/test_image.py
+++ b/openstackclient/tests/image/v1/test_image.py
@@ -178,8 +178,8 @@ class TestImageCreate(TestImage):
# Ensure the input file is closed
mock_file.close.assert_called_with()
- # ImageManager.get(name)
- self.images_mock.get.assert_called_with(image_fakes.image_name)
+ # ImageManager.get(name) not to be called since update action exists
+ self.images_mock.get.assert_not_called()
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
@@ -201,71 +201,6 @@ class TestImageCreate(TestImage):
self.assertEqual(image_fakes.IMAGE_columns, columns)
self.assertEqual(image_fakes.IMAGE_data, data)
- def test_image_create_volume(self):
- # Set up VolumeManager Mock
- volumes_mock = self.app.client_manager.volume.volumes
- volumes_mock.reset_mock()
- volumes_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy({'id': 'vol1', 'name': 'volly'}),
- loaded=True,
- )
- response = {
- "id": 'volume_id',
- "updated_at": 'updated_at',
- "status": 'uploading',
- "display_description": 'desc',
- "size": 'size',
- "volume_type": 'volume_type',
- "image_id": 'image1',
- "container_format": image.DEFAULT_CONTAINER_FORMAT,
- "disk_format": image.DEFAULT_DISK_FORMAT,
- "image_name": image_fakes.image_name,
- }
- full_response = {"os-volume_upload_image": response}
- volumes_mock.upload_to_image.return_value = (201, full_response)
-
- arglist = [
- '--volume', 'volly',
- image_fakes.image_name,
- ]
- verifylist = [
- ('private', False),
- ('protected', False),
- ('public', False),
- ('unprotected', False),
- ('volume', 'volly'),
- ('force', False),
- ('name', image_fakes.image_name),
- ]
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
- # DisplayCommandBase.take_action() returns two tuples
- columns, data = self.cmd.take_action(parsed_args)
-
- # VolumeManager.upload_to_image(volume, force, image_name,
- # container_format, disk_format)
- volumes_mock.upload_to_image.assert_called_with(
- 'vol1',
- False,
- image_fakes.image_name,
- 'bare',
- 'raw',
- )
-
- # ImageManager.update(image_id, remove_props=, **)
- self.images_mock.update.assert_called_with(
- image_fakes.image_id,
- name=image_fakes.image_name,
- container_format=image.DEFAULT_CONTAINER_FORMAT,
- disk_format=image.DEFAULT_DISK_FORMAT,
- properties=image_fakes.image_properties,
- volume='volly',
- )
-
- self.assertEqual(image_fakes.IMAGE_columns, columns)
- self.assertEqual(image_fakes.IMAGE_data, data)
-
class TestImageDelete(TestImage):
@@ -669,6 +604,69 @@ class TestImageSet(TestImage):
**kwargs
)
+ def test_image_update_volume(self):
+ # Set up VolumeManager Mock
+ volumes_mock = self.app.client_manager.volume.volumes
+ volumes_mock.reset_mock()
+ volumes_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy({'id': 'vol1', 'name': 'volly'}),
+ loaded=True,
+ )
+ response = {
+ "id": 'volume_id',
+ "updated_at": 'updated_at',
+ "status": 'uploading',
+ "display_description": 'desc',
+ "size": 'size',
+ "volume_type": 'volume_type',
+ "container_format": image.DEFAULT_CONTAINER_FORMAT,
+ "disk_format": image.DEFAULT_DISK_FORMAT,
+ "image": image_fakes.image_name,
+ }
+ full_response = {"os-volume_upload_image": response}
+ volumes_mock.upload_to_image.return_value = (201, full_response)
+
+ arglist = [
+ '--volume', 'volly',
+ '--name', 'updated_image',
+ image_fakes.image_name,
+ ]
+ verifylist = [
+ ('private', False),
+ ('protected', False),
+ ('public', False),
+ ('unprotected', False),
+ ('volume', 'volly'),
+ ('force', False),
+ ('name', 'updated_image'),
+ ('image', image_fakes.image_name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ # VolumeManager.upload_to_image(volume, force, image_name,
+ # container_format, disk_format)
+ volumes_mock.upload_to_image.assert_called_with(
+ 'vol1',
+ False,
+ image_fakes.image_name,
+ '',
+ '',
+ )
+
+ # ImageManager.update(image_id, remove_props=, **)
+ self.images_mock.update.assert_called_with(
+ image_fakes.image_id,
+ name='updated_image',
+ volume='volly',
+ )
+
+ self.assertEqual(image_fakes.IMAGE_columns, columns)
+ self.assertEqual(image_fakes.IMAGE_data, data)
+
class TestImageShow(TestImage):
diff --git a/openstackclient/tests/network/common.py b/openstackclient/tests/network/common.py
index 7162f97b..31fde257 100644
--- a/openstackclient/tests/network/common.py
+++ b/openstackclient/tests/network/common.py
@@ -33,30 +33,3 @@ class TestNetworkBase(utils.TestCommand):
service_type="network",
)
self.api = self.app.client_manager.network.api
-
- 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'),
- ]
diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py
index 36133a3b..87a44066 100644
--- a/openstackclient/tests/network/v2/test_network.py
+++ b/openstackclient/tests/network/v2/test_network.py
@@ -92,14 +92,14 @@ class TestCreateNetwork(common.TestNetworkBase):
"--project", identity_fakes_v3.project_name,
"--project-domain", identity_fakes_v3.domain_name,
FAKE_NAME,
- ] + self.given_show_options
+ ]
verifylist = [
('admin_state', False),
('shared', True),
('project', identity_fakes_v3.project_name),
('project_domain', identity_fakes_v3.domain_name),
('name', FAKE_NAME),
- ] + self.then_show_options
+ ]
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
self.app.client_manager.network.create_network = mocker
identity_client = identity_fakes_v3.FakeIdentityv3Client(
@@ -519,8 +519,8 @@ class TestShowNetwork(common.TestNetworkBase):
self.assertEqual(FILTERED, result)
def test_show_all_options(self, n_mock):
- arglist = [FAKE_NAME] + self.given_show_options
- verifylist = [('identifier', FAKE_NAME)] + self.then_show_options
+ arglist = [FAKE_NAME]
+ verifylist = [('identifier', FAKE_NAME)]
n_mock.return_value = copy.deepcopy(RECORD)
self.cmd = network.ShowNetwork(self.app, self.namespace)
diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py
index b080ae91..674d8345 100644
--- a/openstackclient/tests/test_shell.py
+++ b/openstackclient/tests/test_shell.py
@@ -38,6 +38,7 @@ DEFAULT_REGION_NAME = "ZZ9_Plural_Z_Alpha"
DEFAULT_TOKEN = "token"
DEFAULT_SERVICE_URL = "http://127.0.0.1:8771/v3.0/"
DEFAULT_AUTH_PLUGIN = "v2password"
+DEFAULT_ENDPOINT_TYPE = "internal"
DEFAULT_COMPUTE_API_VERSION = "2"
DEFAULT_IDENTITY_API_VERSION = "2"
@@ -61,6 +62,7 @@ CLOUD_1 = {
},
'region_name': 'occ-cloud',
'donut': 'glazed',
+ 'endpoint_type': 'public',
}
}
}
@@ -104,6 +106,7 @@ global_options = {
'--os-default-domain': (DEFAULT_DOMAIN_NAME, True, True),
'--os-cacert': ('/dev/null', True, True),
'--timing': (True, True, False),
+ '--os-endpoint-type': (DEFAULT_ENDPOINT_TYPE, True, True)
}
auth_options = {
@@ -123,6 +126,7 @@ auth_options = {
'--os-auth-type': ("v2password", True, True),
'--os-token': (DEFAULT_TOKEN, True, True),
'--os-url': (DEFAULT_SERVICE_URL, True, True),
+ '--os-endpoint-type': (DEFAULT_ENDPOINT_TYPE, True, True),
}
@@ -608,6 +612,10 @@ class TestShellCli(TestShell):
'glazed',
_shell.cloud.config['donut'],
)
+ self.assertEqual(
+ 'public',
+ _shell.cloud.config['endpoint_type'],
+ )
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
diff --git a/openstackclient/tests/volume/v1/test_qos_specs.py b/openstackclient/tests/volume/v1/test_qos_specs.py
index 0a5d14e6..226fe673 100644
--- a/openstackclient/tests/volume/v1/test_qos_specs.py
+++ b/openstackclient/tests/volume/v1/test_qos_specs.py
@@ -312,7 +312,7 @@ class TestQosList(TestQos):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.qos_mock.list.assert_called()
+ self.qos_mock.list.assert_called_with()
collist = (
'ID',
diff --git a/openstackclient/tests/volume/v2/test_qos_specs.py b/openstackclient/tests/volume/v2/test_qos_specs.py
index 92b3f179..6a550988 100644
--- a/openstackclient/tests/volume/v2/test_qos_specs.py
+++ b/openstackclient/tests/volume/v2/test_qos_specs.py
@@ -312,7 +312,7 @@ class TestQosList(TestQos):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.qos_mock.list.assert_called()
+ self.qos_mock.list.assert_called_with()
collist = (
'ID',
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
index 1038c407..965c42ec 100644
--- a/openstackclient/volume/client.py
+++ b/openstackclient/volume/client.py
@@ -53,11 +53,16 @@ def make_client(instance):
extensions = [extension.Extension('list_extensions', list_extensions)]
+ # Remember endpoint_type only if it is set
+ kwargs = utils.build_kwargs_dict('endpoint_type',
+ instance._endpoint_type)
+
client = volume_client(
session=instance.session,
extensions=extensions,
http_log_debug=http_log_debug,
region_name=instance._region_name,
+ **kwargs
)
return client