def print_list(objs, fields, formatters={}, sortby_index=None): if sortby_index is None: sortby = None else: sortby = fields[sortby_index] mixed_case_fields = ['serverId'] pt = prettytable.PrettyTable([f for f in fields], caching=False) pt.align = 'l' for o in objs: row = [] for field in fields: if field in formatters: row.append(formatters[field](o)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') data = getattr(o, field_name, '') if data is None: data = '-' row.append(data) pt.add_row(row) if sortby is not None: result = strutils.safe_encode(pt.get_string(sortby=sortby)) else: result = strutils.safe_encode(pt.get_string()) print(result)
def print_list(objs, fields, formatters={}, sortby_index=None): if sortby_index is None: sortby = None else: sortby = fields[sortby_index] mixed_case_fields = ['serverId'] pt = prettytable.PrettyTable([f for f in fields], caching=False) pt.align = 'l' for o in objs: row = [] for field in fields: if field in formatters: row.append(formatters[field](o)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') data = getattr(o, field_name, '') row.append(data) pt.add_row(row) if sortby is not None: result = strutils.safe_encode(pt.get_string(sortby=sortby)) else: result = strutils.safe_encode(pt.get_string()) print(result)
def print_dict(dct, dict_property="Property", wrap=0): """Print a `dict` as a table of two columns. :param dct: `dict` to print :param dict_property: name of the first column :param wrap: wrapping for the second column """ pt = prettytable.PrettyTable([dict_property, 'Value'], caching=False) pt.align = 'l' for k, v in six.iteritems(dct): # convert dict to str to check length if isinstance(v, dict): v = six.text_type(v) if wrap > 0: v = textwrap.fill(six.text_type(v), wrap) # if value has a newline, add in multiple rows # e.g. fault with stacktrace if v and isinstance(v, six.string_types) and r'\n' in v: lines = v.strip().split(r'\n') col1 = k for line in lines: pt.add_row([col1, line]) col1 = '' else: pt.add_row([k, v]) print(strutils.safe_encode(pt.get_string()))
def print_list(objs, fields, formatters=None, sortby_index=0, mixed_case_fields=None): """Print a list or objects as a table, one row per object. :param objs: iterable of :class:`Resource` :param fields: attributes that correspond to columns, in order :param formatters: `dict` of callables for field formatting :param sortby_index: index of the field for sorting table rows :param mixed_case_fields: fields corresponding to object attributes that have mixed case names (e.g., 'serverId') """ formatters = formatters or {} mixed_case_fields = mixed_case_fields or [] if sortby_index is None: kwargs = {} else: kwargs = {'sortby': fields[sortby_index]} pt = prettytable.PrettyTable(fields, caching=False) pt.align = 'l' for o in objs: row = [] for field in fields: if field in formatters: row.append(formatters[field](o)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') data = getattr(o, field_name, '') row.append(data) pt.add_row(row) print(strutils.safe_encode(pt.get_string(**kwargs)))
def main(): try: OpenStackSaharaShell().main(map(strutils.safe_decode, sys.argv[1:])) except Exception as e: logger.debug(e, exc_info=1) print("ERROR: %s" % strutils.safe_encode(six.text_type(e)), file=sys.stderr) sys.exit(1)
def find_resource(manager, name_or_id, **find_args): """Helper for the _find_* methods.""" # first try to get entity as integer id try: return manager.get(int(name_or_id)) except (TypeError, ValueError, exceptions.NotFound): pass # now try to get entity as uuid try: tmp_id = strutils.safe_encode(name_or_id) if six.PY3: tmp_id = tmp_id.decode() uuid.UUID(tmp_id) return manager.get(tmp_id) except (TypeError, ValueError, exceptions.NotFound): pass # for str id which is not uuid (for Flavor search currently) if getattr(manager, 'is_alphanum_id_allowed', False): try: return manager.get(name_or_id) except exceptions.NotFound: pass try: try: return manager.find(human_id=name_or_id, **find_args) except exceptions.NotFound: pass # finally try to find entity by name try: resource = getattr(manager, 'resource_class', None) name_attr = resource.NAME_ATTR if resource else 'name' kwargs = {name_attr: name_or_id} kwargs.update(find_args) return manager.find(**kwargs) except exceptions.NotFound: msg = "No %s with a name or ID of '%s' exists." % \ (manager.resource_class.__name__.lower(), name_or_id) raise exceptions.CommandError(msg) except exceptions.NoUniqueMatch: msg = ("Multiple %s matches found for '%s', use an ID to be more" " specific." % (manager.resource_class.__name__.lower(), name_or_id)) raise exceptions.CommandError(msg)
def print_list(objs, fields, formatters=None, sortby_index=0, mixed_case_fields=None, field_labels=None): """Print a list or objects as a table, one row per object. :param objs: iterable of :class:`Resource` :param fields: attributes that correspond to columns, in order :param formatters: `dict` of callables for field formatting :param sortby_index: index of the field for sorting table rows :param mixed_case_fields: fields corresponding to object attributes that have mixed case names (e.g., 'serverId') :param field_labels: Labels to use in the heading of the table, default to fields. """ formatters = formatters or {} mixed_case_fields = mixed_case_fields or [] field_labels = field_labels or fields if len(field_labels) != len(fields): raise ValueError(_("Field labels list %(labels)s has different number " "of elements than fields list %(fields)s"), {'labels': field_labels, 'fields': fields}) if sortby_index is None: kwargs = {} else: kwargs = {'sortby': field_labels[sortby_index]} pt = prettytable.PrettyTable(field_labels, caching=False) pt.align = 'l' for o in objs: row = [] for field in fields: if field in formatters: row.append(formatters[field](o)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') data = getattr(o, field_name, '') row.append(data) pt.add_row(row) print(strutils.safe_encode(pt.get_string(**kwargs)))
def print_dict(d, dict_property="Property", dict_value="Value", wrap=0): pt = prettytable.PrettyTable([dict_property, dict_value], caching=False) pt.align = "l" for k, v in sorted(d.items()): # convert dict to str to check length if isinstance(v, dict): v = str(v) if wrap > 0: v = textwrap.fill(str(v), wrap) # if value has a newline, add in multiple rows # e.g. fault with stacktrace if v and isinstance(v, six.string_types) and r"\n" in v: lines = v.strip().split(r"\n") col1 = k for line in lines: pt.add_row([col1, line]) col1 = "" else: pt.add_row([k, v]) print(strutils.safe_encode(pt.get_string()))
def print_dict(d, dict_property="Property", dict_value="Value", wrap=0): pt = prettytable.PrettyTable([dict_property, dict_value], caching=False) pt.align = 'l' for k, v in sorted(d.items()): # convert dict to str to check length if isinstance(v, dict): v = str(v) if wrap > 0: v = textwrap.fill(str(v), wrap) # if value has a newline, add in multiple rows # e.g. fault with stacktrace if v and isinstance(v, six.string_types) and r'\n' in v: lines = v.strip().split(r'\n') col1 = k for line in lines: pt.add_row([col1, line]) col1 = '' else: pt.add_row([k, v]) print(strutils.safe_encode(pt.get_string()))
def _boot(self, resource_url, response_key, name, image, flavor, meta=None, files=None, userdata=None, reservation_id=None, return_raw=False, min_count=None, max_count=None, security_groups=None, key_name=None, availability_zone=None, block_device_mapping=None, block_device_mapping_v2=None, nics=None, scheduler_hints=None, config_drive=None, admin_pass=None, disk_config=None, **kwargs): """Create (boot) a new server. :param name: Something to name the server. :param image: The :class:`Image` to boot with. :param flavor: The :class:`Flavor` to boot onto. :param meta: A dict of arbitrary key/value metadata to store for this server. A maximum of five entries is allowed, and both keys and values must be 255 characters or less. :param files: A dict of files to overwrite on the server upon boot. Keys are file names (i.e. ``/etc/passwd``) and values are the file contents (either as a string or as a file-like object). A maximum of five entries is allowed, and each file must be 10k or less. :param reservation_id: a UUID for the set of servers being requested. :param return_raw: If True, don't try to coearse the result into a Resource object. :param security_groups: list of security group names :param key_name: (optional extension) name of keypair to inject into the instance :param availability_zone: Name of the availability zone for instance placement. :param block_device_mapping: A dict of block device mappings for this server. :param block_device_mapping_v2: A dict of block device mappings V2 for this server. :param nics: (optional extension) an ordered list of nics to be added to this server, with information about connected networks, fixed ips, etc. :param scheduler_hints: (optional extension) arbitrary key-value pairs specified by the client to help boot an instance. :param config_drive: (optional extension) value for config drive either boolean, or volume-id :param admin_pass: admin password for the server. :param disk_config: (optional extension) control how the disk is partitioned when the server is created. """ body = {"server": { "name": name, "imageRef": str(getid(image)) if image else '', "flavorRef": str(getid(flavor)), }} if userdata: if hasattr(userdata, 'read'): userdata = userdata.read() userdata = strutils.safe_encode(userdata) body["server"]["user_data"] = base64.b64encode(userdata) if meta: body["server"]["metadata"] = meta if reservation_id: body["server"]["reservation_id"] = reservation_id if key_name: body["server"]["key_name"] = key_name if scheduler_hints: body['os:scheduler_hints'] = scheduler_hints if config_drive: body["server"]["config_drive"] = config_drive if admin_pass: body["server"]["adminPass"] = admin_pass if not min_count: min_count = 1 if not max_count: max_count = min_count body["server"]["min_count"] = min_count body["server"]["max_count"] = max_count if security_groups: body["server"]["security_groups"] = ( [{'name': sg} for sg in security_groups] ) # Files are a slight bit tricky. They're passed in a "personality" # list to the POST. Each item is a dict giving a file name and the # base64-encoded contents of the file. We want to allow passing # either an open file *or* some contents as files here. if files: personality = body['server']['personality'] = [] for filepath, file_or_string in sorted(files.items(), key=lambda x: x[0]): if hasattr(file_or_string, 'read'): data = file_or_string.read() else: data = file_or_string personality.append({ 'path': filepath, 'contents': base64.b64encode(data.encode('utf-8')), }) if availability_zone: body["server"]["availability_zone"] = availability_zone # Block device mappings are passed as a list of dictionaries if block_device_mapping: body['server']['block_device_mapping'] = ( self._parse_block_device_mapping(block_device_mapping) ) elif block_device_mapping_v2: # Append the image to the list only if we have new style BDMs if image: bdm_dict = {'uuid': image.id, 'source_type': 'image', 'destination_type': 'local', 'boot_index': 0, 'delete_on_termination': True} block_device_mapping_v2.insert(0, bdm_dict) body['server']['block_device_mapping_v2'] = block_device_mapping_v2 if nics is not None: # NOTE(tr3buchet): nics can be an empty list all_net_data = [] for nic_info in nics: net_data = {} # if value is empty string, do not send value in body if nic_info.get('net-id'): net_data['uuid'] = nic_info['net-id'] if nic_info.get('v4-fixed-ip'): net_data['fixed_ip'] = nic_info['v4-fixed-ip'] if nic_info.get('port-id'): net_data['port'] = nic_info['port-id'] all_net_data.append(net_data) body['server']['networks'] = all_net_data if disk_config is not None: body['server']['OS-DCF:diskConfig'] = disk_config return self._create(resource_url, body, response_key, return_raw=return_raw, **kwargs)
def _boot(self, resource_url, response_key, name, image, flavor, meta=None, files=None, userdata=None, reservation_id=None, return_raw=False, min_count=None, max_count=None, security_groups=None, key_name=None, availability_zone=None, block_device_mapping=None, block_device_mapping_v2=None, nics=None, scheduler_hints=None, config_drive=None, admin_pass=None, disk_config=None, **kwargs): """Create (boot) a new server. :param name: Something to name the server. :param image: The :class:`Image` to boot with. :param flavor: The :class:`Flavor` to boot onto. :param meta: A dict of arbitrary key/value metadata to store for this server. A maximum of five entries is allowed, and both keys and values must be 255 characters or less. :param files: A dict of files to overwrite on the server upon boot. Keys are file names (i.e. ``/etc/passwd``) and values are the file contents (either as a string or as a file-like object). A maximum of five entries is allowed, and each file must be 10k or less. :param reservation_id: a UUID for the set of servers being requested. :param return_raw: If True, don't try to coearse the result into a Resource object. :param security_groups: list of security group names :param key_name: (optional extension) name of keypair to inject into the instance :param availability_zone: Name of the availability zone for instance placement. :param block_device_mapping: A dict of block device mappings for this server. :param block_device_mapping_v2: A dict of block device mappings V2 for this server. :param nics: (optional extension) an ordered list of nics to be added to this server, with information about connected networks, fixed ips, etc. :param scheduler_hints: (optional extension) arbitrary key-value pairs specified by the client to help boot an instance. :param config_drive: (optional extension) value for config drive either boolean, or volume-id :param admin_pass: admin password for the server. :param disk_config: (optional extension) control how the disk is partitioned when the server is created. """ body = { "server": { "name": name, "imageRef": str(getid(image)) if image else '', "flavorRef": str(getid(flavor)), } } if userdata: if hasattr(userdata, 'read'): userdata = userdata.read() userdata = strutils.safe_encode(userdata) body["server"]["user_data"] = base64.b64encode(userdata) if meta: body["server"]["metadata"] = meta if reservation_id: body["server"]["reservation_id"] = reservation_id if key_name: body["server"]["key_name"] = key_name if scheduler_hints: body['os:scheduler_hints'] = scheduler_hints if config_drive: body["server"]["config_drive"] = config_drive if admin_pass: body["server"]["adminPass"] = admin_pass if not min_count: min_count = 1 if not max_count: max_count = min_count body["server"]["min_count"] = min_count body["server"]["max_count"] = max_count if security_groups: body["server"]["security_groups"] =\ [{'name': sg} for sg in security_groups] # Files are a slight bit tricky. They're passed in a "personality" # list to the POST. Each item is a dict giving a file name and the # base64-encoded contents of the file. We want to allow passing # either an open file *or* some contents as files here. if files: personality = body['server']['personality'] = [] for filepath, file_or_string in sorted(files.items(), key=lambda x: x[0]): if hasattr(file_or_string, 'read'): data = file_or_string.read() else: data = file_or_string personality.append({ 'path': filepath, 'contents': base64.b64encode(data.encode('utf-8')), }) if availability_zone: body["server"]["availability_zone"] = availability_zone # Block device mappings are passed as a list of dictionaries if block_device_mapping: body['server']['block_device_mapping'] = \ self._parse_block_device_mapping(block_device_mapping) elif block_device_mapping_v2: # Append the image to the list only if we have new style BDMs if image: bdm_dict = { 'uuid': image.id, 'source_type': 'image', 'destination_type': 'local', 'boot_index': 0, 'delete_on_termination': True } block_device_mapping_v2.insert(0, bdm_dict) body['server']['block_device_mapping_v2'] = block_device_mapping_v2 if nics is not None: # NOTE(tr3buchet): nics can be an empty list all_net_data = [] for nic_info in nics: net_data = {} # if value is empty string, do not send value in body if nic_info.get('net-id'): net_data['uuid'] = nic_info['net-id'] if nic_info.get('v4-fixed-ip'): net_data['fixed_ip'] = nic_info['v4-fixed-ip'] if nic_info.get('port-id'): net_data['port'] = nic_info['port-id'] all_net_data.append(net_data) body['server']['networks'] = all_net_data if disk_config is not None: body['server']['OS-DCF:diskConfig'] = disk_config return self._create(resource_url, body, response_key, return_raw=return_raw, **kwargs)
def find_resource(manager, name_or_id, **find_args): """Look for resource in a given manager. Used as a helper for the _find_* methods. Example: .. code-block:: python def _find_hypervisor(cs, hypervisor): #Get a hypervisor by name or ID. return cliutils.find_resource(cs.hypervisors, hypervisor) """ # first try to get entity as integer id try: return manager.get(int(name_or_id)) except (TypeError, ValueError, exceptions.NotFound): pass # now try to get entity as uuid try: if six.PY2: tmp_id = strutils.safe_encode(name_or_id) else: tmp_id = strutils.safe_decode(name_or_id) if uuidutils.is_uuid_like(tmp_id): return manager.get(tmp_id) except (TypeError, ValueError, exceptions.NotFound): pass # for str id which is not uuid if getattr(manager, 'is_alphanum_id_allowed', False): try: return manager.get(name_or_id) except exceptions.NotFound: pass try: try: return manager.find(human_id=name_or_id, **find_args) except exceptions.NotFound: pass # finally try to find entity by name try: resource = getattr(manager, 'resource_class', None) name_attr = resource.NAME_ATTR if resource else 'name' kwargs = {name_attr: name_or_id} kwargs.update(find_args) return manager.find(**kwargs) except exceptions.NotFound: msg = _("No %(name)s with a name or " "ID of '%(name_or_id)s' exists.") % \ { "name": manager.resource_class.__name__.lower(), "name_or_id": name_or_id } raise exceptions.CommandError(msg) except exceptions.NoUniqueMatch: msg = _("Multiple %(name)s matches found for " "'%(name_or_id)s', use an ID to be more specific.") % \ { "name": manager.resource_class.__name__.lower(), "name_or_id": name_or_id } raise exceptions.CommandError(msg)
def find_resource(manager, name_or_id, **find_args): """Look for resource in a given manager. Used as a helper for the _find_* methods. Example: def _find_hypervisor(cs, hypervisor): #Get a hypervisor by name or ID. return cliutils.find_resource(cs.hypervisors, hypervisor) """ # first try to get entity as integer id try: return manager.get(int(name_or_id)) except (TypeError, ValueError, exceptions.NotFound): pass # now try to get entity as uuid try: if six.PY2: tmp_id = strutils.safe_encode(name_or_id) else: tmp_id = strutils.safe_decode(name_or_id) if uuidutils.is_uuid_like(tmp_id): return manager.get(tmp_id) except (TypeError, ValueError, exceptions.NotFound): pass # for str id which is not uuid if getattr(manager, 'is_alphanum_id_allowed', False): try: return manager.get(name_or_id) except exceptions.NotFound: pass try: try: return manager.find(human_id=name_or_id, **find_args) except exceptions.NotFound: pass # finally try to find entity by name try: resource = getattr(manager, 'resource_class', None) name_attr = resource.NAME_ATTR if resource else 'name' kwargs = {name_attr: name_or_id} kwargs.update(find_args) return manager.find(**kwargs) except exceptions.NotFound: msg = _("No %(name)s with a name or " "ID of '%(name_or_id)s' exists.") % \ { "name": manager.resource_class.__name__.lower(), "name_or_id": name_or_id } raise exceptions.CommandError(msg) except exceptions.NoUniqueMatch: msg = _("Multiple %(name)s matches found for " "'%(name_or_id)s', use an ID to be more specific.") % \ { "name": manager.resource_class.__name__.lower(), "name_or_id": name_or_id } raise exceptions.CommandError(msg)