summaryrefslogtreecommitdiff
path: root/openstackclient/compute/v2
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/compute/v2')
-rw-r--r--openstackclient/compute/v2/server.py189
1 files changed, 143 insertions, 46 deletions
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index c7c6add0..69bfc7e8 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -20,45 +20,55 @@ Server action implementations
"""
import logging
+import os
+
+from cliff import lister
+from cliff import show
from openstackclient.common import command
from openstackclient.common import utils
-def _find_server(cs, server):
- """Get a server by name or ID."""
- return utils.find_resource(cs.servers, server)
-
-
-def _print_server(cs, server):
- # By default when searching via name we will do a
- # findall(name=blah) and due a REST /details which is not the same
- # as a .get() and doesn't get the information about flavors and
- # images. This fix it as we redo the call with the id which does a
- # .get() to get all informations.
- if not 'flavor' in server._info:
- server = _find_server(cs, server.id)
-
- networks = server.networks
- info = server._info.copy()
- for network_label, address_list in networks.items():
- info['%s network' % network_label] = ', '.join(address_list)
-
- flavor = info.get('flavor', {})
- flavor_id = flavor.get('id', '')
- info['flavor'] = _find_flavor(cs, flavor_id).name
-
- image = info.get('image', {})
- image_id = image.get('id', '')
- info['image'] = _find_image(cs, image_id).name
-
- info.pop('links', None)
- info.pop('addresses', None)
-
- utils.print_dict(info)
-
-
-class List_Server(command.OpenStackCommand):
+def _format_servers_list_networks(server):
+ """Return a string containing the networks a server is attached to.
+
+ :param server: a single Server resource
+ """
+ output = []
+ for (network, addresses) in server.networks.items():
+ if not addresses:
+ continue
+ addresses_csv = ', '.join(addresses)
+ group = "%s=%s" % (network, addresses_csv)
+ output.append(group)
+ return '; '.join(output)
+
+
+def get_server_properties(server, fields, formatters={}):
+ """Return a tuple containing the server properties.
+
+ :param server: a single Server resource
+ :param fields: tuple of strings with the desired field names
+ :param formatters: dictionary mapping field names to callables
+ to format the values
+ """
+ row = []
+ mixed_case_fields = ['serverId']
+
+ for field in fields:
+ if field in formatters:
+ row.append(formatters[field](server))
+ else:
+ if field in mixed_case_fields:
+ field_name = field.replace(' ', '_')
+ else:
+ field_name = field.lower().replace(' ', '_')
+ data = getattr(server, field_name, '')
+ row.append(data)
+ return tuple(row)
+
+
+class List_Server(command.OpenStackCommand, lister.Lister):
"List server command."
api = 'compute'
@@ -67,17 +77,79 @@ class List_Server(command.OpenStackCommand):
def get_parser(self, prog_name):
parser = super(List_Server, self).get_parser(prog_name)
parser.add_argument(
- '--long',
+ '--reservation-id',
+ help='only return instances that match the reservation',
+ )
+ parser.add_argument(
+ '--ip',
+ help='regular expression to match IP address',
+ )
+ parser.add_argument(
+ '--ip6',
+ help='regular expression to match IPv6 address',
+ )
+ parser.add_argument(
+ '--name',
+ help='regular expression to match name',
+ )
+ parser.add_argument(
+ '--instance-name',
+ help='regular expression to match instance name',
+ )
+ parser.add_argument(
+ '--status',
+ help='search by server status',
+ # FIXME(dhellmann): Add choices?
+ )
+ parser.add_argument(
+ '--flavor',
+ help='search by flavor ID',
+ )
+ parser.add_argument(
+ '--image',
+ help='search by image ID',
+ )
+ parser.add_argument(
+ '--host',
+ metavar='HOSTNAME',
+ help='search by hostname',
+ )
+ parser.add_argument(
+ '--all-tenants',
action='store_true',
- default=False,
- help='Additional fields are listed in output')
+ default=bool(int(os.environ.get("ALL_TENANTS", 0))),
+ help='display information from all tenants (admin only)',
+ )
return parser
- def run(self, parsed_args):
- self.log.info('v2.List_Server.run(%s)' % parsed_args)
-
-
-class Show_Server(command.OpenStackCommand):
+ def get_data(self, parsed_args):
+ self.log.debug('v2.List_Server.run(%s)' % parsed_args)
+ nova_client = self.app.client_manager.compute
+ search_opts = {
+ 'all_tenants': parsed_args.all_tenants,
+ 'reservation_id': parsed_args.reservation_id,
+ 'ip': parsed_args.ip,
+ 'ip6': parsed_args.ip6,
+ 'name': parsed_args.name,
+ 'image': parsed_args.image,
+ 'flavor': parsed_args.flavor,
+ 'status': parsed_args.status,
+ 'host': parsed_args.host,
+ 'instance_name': parsed_args.instance_name,
+ }
+ self.log.debug('search options: %s', search_opts)
+ # FIXME(dhellmann): Consider adding other columns
+ columns = ('ID', 'Name', 'Status', 'Networks')
+ data = nova_client.servers.list(search_opts=search_opts)
+ return (columns,
+ (get_server_properties(
+ s, columns,
+ formatters={'Networks': _format_servers_list_networks},
+ ) for s in data),
+ )
+
+
+class Show_Server(command.OpenStackCommand, show.ShowOne):
"Show server command."
api = 'compute'
@@ -91,7 +163,32 @@ class Show_Server(command.OpenStackCommand):
help='Name or ID of server to display')
return parser
- def run(self, parsed_args):
- self.log.info('v2.Show_Server.run(%s)' % parsed_args)
- #s = _find_server(cs, args.server)
- #_print_server(cs, s)
+ def get_data(self, parsed_args):
+ self.log.debug('v2.Show_Server.run(%s)' % parsed_args)
+ nova_client = self.app.client_manager.compute
+ server = utils.find_resource(nova_client.servers, parsed_args.server)
+
+ info = {}
+ info.update(server._info)
+
+ # Convert the flavor blob to a name
+ flavor_info = info.get('flavor', {})
+ flavor_id = flavor_info.get('id', '')
+ flavor = utils.find_resource(nova_client.flavors, flavor_id)
+ info['flavor'] = flavor.name
+
+ # Convert the image blob to a name
+ image_info = info.get('image', {})
+ image_id = image_info.get('id', '')
+ image = utils.find_resource(nova_client.images, image_id)
+ info['image'] = image.name
+
+ # Format addresses in a useful way
+ info['addresses'] = _format_servers_list_networks(server)
+
+ # Remove a couple of values that are long and not too useful
+ info.pop('links', None)
+
+ columns = sorted(info.keys())
+ values = [info[c] for c in columns]
+ return (columns, values)