summaryrefslogtreecommitdiff
path: root/openstackclient/compute
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/compute')
-rw-r--r--openstackclient/compute/v2/server.py47
-rw-r--r--openstackclient/compute/v2/server_group.py17
2 files changed, 49 insertions, 15 deletions
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 93e9f966..1d1fc741 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -24,6 +24,7 @@ import os
from novaclient import api_versions
from novaclient.v2 import servers
from openstack import exceptions as sdk_exceptions
+from osc_lib.cli import format_columns
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
@@ -38,6 +39,8 @@ from openstackclient.network import common as network_common
LOG = logging.getLogger(__name__)
+IMAGE_STRING_FOR_BFV = 'N/A (booted from volume)'
+
def _format_servers_list_networks(networks):
"""Return a formatted string of a server's networks
@@ -147,6 +150,12 @@ def _prep_server_detail(compute_client, image_client, server, refresh=True):
info['image'] = "%s (%s)" % (image.name, image_id)
except Exception:
info['image'] = image_id
+ else:
+ # NOTE(melwitt): An server booted from a volume will have no image
+ # associated with it. We fill in the image with "N/A (booted from
+ # volume)" to help users who want to be able to grep for
+ # boot-from-volume servers when using the CLI.
+ info['image'] = IMAGE_STRING_FOR_BFV
# Convert the flavor blob to a name
flavor_info = info.get('flavor', {})
@@ -166,14 +175,14 @@ def _prep_server_detail(compute_client, image_client, server, refresh=True):
if 'os-extended-volumes:volumes_attached' in info:
info.update(
{
- 'volumes_attached': utils.format_list_of_dicts(
+ 'volumes_attached': format_columns.ListDictColumn(
info.pop('os-extended-volumes:volumes_attached'))
}
)
if 'security_groups' in info:
info.update(
{
- 'security_groups': utils.format_list_of_dicts(
+ 'security_groups': format_columns.ListDictColumn(
info.pop('security_groups'))
}
)
@@ -182,9 +191,14 @@ def _prep_server_detail(compute_client, image_client, server, refresh=True):
info['addresses'] = _format_servers_list_networks(server.networks)
# Map 'metadata' field to 'properties'
- info.update(
- {'properties': utils.format_dict(info.pop('metadata'))}
- )
+ if not info['metadata']:
+ info.update(
+ {'properties': utils.format_dict(info.pop('metadata'))}
+ )
+ else:
+ info.update(
+ {'properties': format_columns.DictColumn(info.pop('metadata'))}
+ )
# Migrate tenant_id to project_id naming
if 'tenant_id' in info:
@@ -751,19 +765,27 @@ class CreateServer(command.ShowOne):
images_matched = []
for img in image_list:
img_dict = {}
+
# exclude any unhashable entries
- for key, value in img.items():
+ img_dict_items = list(img.items())
+ if img.properties:
+ img_dict_items.extend(list(img.properties.items()))
+ for key, value in img_dict_items:
try:
set([key, value])
except TypeError:
+ if key != 'properties':
+ LOG.debug('Skipped the \'%s\' attribute. '
+ 'That cannot be compared. '
+ '(image: %s, value: %s)',
+ key, img.id, value)
pass
else:
img_dict[key] = value
+
if all(k in img_dict and img_dict[k] == v
for k, v in wanted_properties.items()):
images_matched.append(img)
- else:
- return []
return images_matched
images = _match_image(image_client, parsed_args.image_property)
@@ -1520,8 +1542,12 @@ class ListServer(command.Lister):
s.image_name = image.name
s.image_id = s.image['id']
else:
- s.image_name = ''
- s.image_id = ''
+ # NOTE(melwitt): An server booted from a volume will have no
+ # image associated with it. We fill in the Image Name and ID
+ # with "N/A (booted from volume)" to help users who want to be
+ # able to grep for boot-from-volume servers when using the CLI.
+ s.image_name = IMAGE_STRING_FOR_BFV
+ s.image_id = IMAGE_STRING_FOR_BFV
if 'id' in s.flavor:
flavor = flavors.get(s.flavor['id'])
if flavor:
@@ -2530,7 +2556,6 @@ class ShowServer(command.ShowOne):
data = _prep_server_detail(compute_client,
self.app.client_manager.image, server,
refresh=False)
-
return zip(*sorted(data.items()))
diff --git a/openstackclient/compute/v2/server_group.py b/openstackclient/compute/v2/server_group.py
index c49a552f..1af6e28d 100644
--- a/openstackclient/compute/v2/server_group.py
+++ b/openstackclient/compute/v2/server_group.py
@@ -17,6 +17,7 @@
import logging
+from novaclient import api_versions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -67,9 +68,13 @@ class CreateServerGroup(command.ShowOne):
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
info = {}
+
+ policy_arg = {'policies': [parsed_args.policy]}
+ if compute_client.api_version >= api_versions.APIVersion("2.64"):
+ policy_arg = {'policy': parsed_args.policy}
server_group = compute_client.server_groups.create(
- name=parsed_args.name,
- policies=[parsed_args.policy])
+ name=parsed_args.name, **policy_arg)
+
info.update(server_group._info)
columns = _get_columns(info)
@@ -136,11 +141,15 @@ class ListServerGroup(command.Lister):
compute_client = self.app.client_manager.compute
data = compute_client.server_groups.list(parsed_args.all_projects)
+ policy_key = 'Policies'
+ if compute_client.api_version >= api_versions.APIVersion("2.64"):
+ policy_key = 'Policy'
+
if parsed_args.long:
column_headers = columns = (
'ID',
'Name',
- 'Policies',
+ policy_key,
'Members',
'Project Id',
'User Id',
@@ -149,7 +158,7 @@ class ListServerGroup(command.Lister):
column_headers = columns = (
'ID',
'Name',
- 'Policies',
+ policy_key,
)
return (column_headers,