def get_template_contents(template_file=None, template_url=None, files=None): # Transform a bare file path to a file:// URL. if template_file: # nosec template_url = utils.normalise_file_path_to_url(template_file) tpl = request.urlopen(template_url).read() else: raise exceptions.CommandErrorException(_('Need to specify exactly ' 'one of %(arg1)s, %(arg2)s ' 'or %(arg3)s') % {'arg1': '--template-file', 'arg2': '--template-url'}) if not tpl: raise exceptions.CommandErrorException(_('Could not fetch ' 'template from %s') % template_url) try: if isinstance(tpl, six.binary_type): tpl = tpl.decode('utf-8') template = template_format.parse(tpl) except ValueError as e: raise exceptions.CommandErrorException(_('Error parsing template ' '%(url)s %(error)s') % {'url': template_url, 'error': e}) return template
def matches(self, min_version, max_version): """Matches the version object. Returns whether the version object represents a version greater than or equal to the minimum version and less than or equal to the maximum version. :param min_version: Minimum acceptable version. :param max_version: Maximum acceptable version. :returns: boolean If min_version is null then there is no minimum limit. If max_version is null then there is no maximum limit. If self is null then raise ValueError """ if self.is_null(): raise ValueError(_("Null APIVersion doesn't support 'matches'.")) if max_version.is_null() and min_version.is_null(): return True elif max_version.is_null(): return min_version <= self elif min_version.is_null(): return self <= max_version else: return min_version <= self <= max_version
def __init__(self, version_str=None): """Create an API version object. :param version_str: String representation of APIVersionRequest. Correct format is 'X.Y', where 'X' and 'Y' are int values. None value should be used to create Null APIVersionRequest, which is equal to 0.0 """ self.ver_major = 0 self.ver_minor = 0 if version_str is not None: match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0|latest)$", version_str) if match: self.ver_major = int(match.group(1)) if match.group(2) == "latest": # NOTE(andreykurilin): Infinity allows to easily determine # latest version and doesn't require any additional checks # in comparison methods. self.ver_minor = float("inf") else: self.ver_minor = int(match.group(2)) else: msg = _("Invalid format of client version '%s'. " "Expected format 'X.Y', where X is a major part and Y " "is a minor part of version.") % version_str raise exceptions.UnsupportedVersion(msg)
def format_args(args, parse_comma=True): '''Reformat a list of key-value arguments into a dict. Convert arguments into format expected by the API. ''' if not args: return {} if parse_comma: # expect multiple invocations of --label (or other arguments) but fall # back to either , or ; delimited if only one --label is specified if len(args) == 1: args = args[0].replace(';', ',').split(',') fmt_args = {} for arg in args: try: (k, v) = arg.split(('='), 1) except ValueError: raise exc.CommandError(_('arguments must be a list of KEY=VALUE ' 'not %s') % arg) if k not in fmt_args: fmt_args[k] = v else: if not isinstance(fmt_args[k], list): fmt_args[k] = [fmt_args[k]] fmt_args[k].append(v) return fmt_args
def take_action(self, parsed_args): client = _get_client(self, parsed_args) try: client.quotas.delete(parsed_args.project_id) print(_('Request to delete quotas has been accepted.')) except Exception as e: print("Delete for quotas failed: %(e)s" % {'e': e})
class MethodNotAllowed(HTTPClientError): """HTTP 405 - Method Not Allowed. A request was made of a resource using a request method not supported by that resource. """ http_status = 405 message = _("Method Not Allowed")
class Forbidden(HTTPClientError): """HTTP 403 - Forbidden. The request was a valid request, but the server is refusing to respond to it. """ http_status = 403 message = _("Forbidden")
class NotFound(HTTPClientError): """HTTP 404 - Not Found. The requested resource could not be found but may be available again in the future. """ http_status = 404 message = _("Not Found")
class Unauthorized(HTTPClientError): """HTTP 401 - Unauthorized. Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. """ http_status = 401 message = _("Unauthorized")
class MultipleChoices(HTTPRedirection): """HTTP 300 - Multiple Choices. Indicates multiple options for the resource that the client may follow. """ http_status = 300 message = _("Multiple Choices")
def _find_actions(self, subparsers, actions_module, version, do_help): msg = _(" (Supported by API versions '%(start)s' - '%(end)s')") for attr in (a for a in dir(actions_module) if a.startswith('do_')): # I prefer to be hyphen-separated instead of underscores. command = attr[3:].replace('_', '-') callback = getattr(actions_module, attr) desc = callback.__doc__ or '' if hasattr(callback, "versioned"): subs = api_versions.get_substitutions(callback) if do_help: desc += msg % {'start': subs[0].start_version.get_string(), 'end': subs[-1].end_version.get_string()} else: for versioned_method in subs: if version.matches(versioned_method.start_version, versioned_method.end_version): callback = versioned_method.func break else: continue action_help = desc.strip() arguments = getattr(callback, 'arguments', []) subparser = ( subparsers.add_parser(command, help=action_help, description=desc, add_help=False, formatter_class=OpenStackHelpFormatter) ) subparser.add_argument('-h', '--help', action='help', help=argparse.SUPPRESS,) self.subcommands[command] = subparser for (args, kwargs) in arguments: start_version = kwargs.get("start_version", None) if start_version: start_version = api_versions.APIVersion(start_version) end_version = kwargs.get("end_version", None) if end_version: end_version = api_versions.APIVersion(end_version) else: end_version = api_versions.APIVersion( "%s.latest" % start_version.ver_major) if do_help: kwargs["help"] = kwargs.get("help", "") + (msg % { "start": start_version.get_string(), "end": end_version.get_string()}) else: if not version.matches(start_version, end_version): continue kw = kwargs.copy() kw.pop("start_version", None) kw.pop("end_version", None) subparser.add_argument(*args, **kwargs) subparser.set_defaults(func=callback)
def discover_version(client, requested_version): server_start_version, server_end_version = _get_server_version_range( client) if (not requested_version.is_latest() and requested_version != APIVersion('1.1')): if server_start_version.is_null() and server_end_version.is_null(): raise exceptions.UnsupportedVersion( _("Server doesn't support microversions")) if not requested_version.matches(server_start_version, server_end_version): raise exceptions.UnsupportedVersion( _("The specified version isn't supported by server. The valid " "version range is '%(min)s' to '%(max)s'") % { "min": server_start_version.get_string(), "max": server_end_version.get_string()}) return requested_version min_version = APIVersion(MIN_API_VERSION) max_version = APIVersion(MAX_API_VERSION) if server_start_version.is_null() and server_end_version.is_null(): return APIVersion("1.1") elif min_version > server_end_version: raise exceptions.UnsupportedVersion( _("Server version is too old. The client valid version range is " "'%(client_min)s' to '%(client_max)s'. The server valid version " "range is '%(server_min)s' to '%(server_max)s'.") % { 'client_min': min_version.get_string(), 'client_max': max_version.get_string(), 'server_min': server_start_version.get_string(), 'server_max': server_end_version.get_string()}) elif max_version < server_start_version: raise exceptions.UnsupportedVersion( _("Server version is too new. The client valid version range is " "'%(client_min)s' to '%(client_max)s'. The server valid version " "range is '%(server_min)s' to '%(server_max)s'.") % { 'client_min': min_version.get_string(), 'client_max': max_version.get_string(), 'server_min': server_start_version.get_string(), 'server_max': server_end_version.get_string()}) elif max_version <= server_end_version: return max_version elif server_end_version < max_version: return server_end_version
def discover_version(client, requested_version): server_start_version, server_end_version = _get_server_version_range( client) if (not requested_version.is_latest() and requested_version != APIVersion('1.1')): if server_start_version.is_null() and server_end_version.is_null(): raise exceptions.UnsupportedVersion( _("Server doesn't support microversions")) if not requested_version.matches(server_start_version, server_end_version): raise exceptions.UnsupportedVersion( _("The specified version isn't supported by server. The valid " "version range is '%(min)s' to '%(max)s'") % { "min": server_start_version.get_string(), "max": server_end_version.get_string()}) return requested_version min_version = APIVersion(MIN_API_VERSION) max_version = APIVersion(MAX_API_VERSION) if server_start_version.is_null() and server_end_version.is_null(): return APIVersion("1.1") elif min_version > server_end_version: raise exceptions.UnsupportedVersion( _("Server version is too old. The client valid version range is " "'%(client_min)s' to '%(client_max)s'. The server valid version " "range is '%(server_min)s' to '%(server_max)s'.") % { 'client_min': min_version.get_string(), 'client_max': max_version.get_string(), 'server_min': server_start_version.get_string(), 'server_max': server_end_version.get_string()}) elif max_version < server_start_version: raise exceptions.UnsupportedVersion( _("Server version is too new. The client valid version range is " "'%(client_min)s' to '%(client_max)s'. The server valid version " "range is '%(server_min)s' to '%(server_max)s'.") % { 'client_min': min_version.get_string(), 'client_max': max_version.get_string(), 'server_min': server_start_version.get_string(), 'server_max': server_end_version.get_string()}) elif max_version <= server_end_version: return max_version elif server_end_version < max_version: return server_end_version
def _get_client_class_and_version(version): if not isinstance(version, api_versions.APIVersion): version = api_versions.get_api_version(version) else: api_versions.check_major_version(version) if version.is_latest(): raise exceptions.UnsupportedVersion( _('The version should be explicit, not latest.')) return version, importutils.import_class('zunclient.v%s.client.Client' % version.ver_major)
def check_major_version(api_version): """Checks major part of ``APIVersion`` obj is supported. :raises exceptions.UnsupportedVersion: if major part is not supported """ available_versions = get_available_major_versions() if (not api_version.is_null() and str(api_version.ver_major) not in available_versions): if len(available_versions) == 1: msg = _("Invalid client version '%(version)s'. " "Major part should be '%(major)s'") % { "version": api_version.get_string(), "major": available_versions[0]} else: msg = _("Invalid client version '%(version)s'. " "Major part must be one of: '%(major)s'") % { "version": api_version.get_string(), "major": ", ".join(available_versions)} raise exceptions.UnsupportedVersion(msg)
def check_major_version(api_version): """Checks major part of ``APIVersion`` obj is supported. :raises exceptions.UnsupportedVersion: if major part is not supported """ available_versions = get_available_major_versions() if (not api_version.is_null() and str(api_version.ver_major) not in available_versions): if len(available_versions) == 1: msg = _("Invalid client version '%(version)s'. " "Major part should be '%(major)s'") % { "version": api_version.get_string(), "major": available_versions[0]} else: msg = _("Invalid client version '%(version)s'. " "Major part must be one of: '%(major)s'") % { "version": api_version.get_string(), "major": ", ".join(available_versions)} raise exceptions.UnsupportedVersion(msg)
def take_action(self, parsed_args): client = _get_client(self, parsed_args) opts = {} opts['image_id'] = parsed_args.uuid try: client.images.delete(**opts) print(_('Request to delete image %s has been accepted.') % opts['image_id']) except Exception as e: print("Delete for image %(image)s failed: %(e)s" % {'image': opts['image_id'], 'e': e})
def get_string(self): """Version string representation. Converts object to string representation which if used to create an APIVersion object results in the same version. """ if self.is_null(): raise ValueError( _("Null APIVersion cannot be converted to string.")) elif self.is_latest(): return "%s.%s" % (self.ver_major, "latest") return "%s.%s" % (self.ver_major, self.ver_minor)
def get_string(self): """Version string representation. Converts object to string representation which if used to create an APIVersion object results in the same version. """ if self.is_null(): raise ValueError( _("Null APIVersion cannot be converted to string.")) elif self.is_latest(): return "%s.%s" % (self.ver_major, "latest") return "%s.%s" % (self.ver_major, self.ver_minor)
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) 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 six.PY3: print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode()) else: print(encodeutils.safe_encode(pt.get_string(**kwargs)))
def take_action(self, parsed_args): client = _get_client(self, parsed_args) containers = parsed_args.container for container in containers: try: client.containers.unpause(container) print( _('Request to unpause container %s has been accepted') % container) except Exception as e: print("unpause for container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def take_action(self, parsed_args): client = _get_client(self, parsed_args) container = parsed_args.container name = parsed_args.name try: client.containers.rename(container, name) print( _('Request to rename container %s has been accepted') % container) except Exception as e: print("rename for container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def take_action(self, parsed_args): client = _get_client(self, parsed_args) containers = parsed_args.container for container in containers: try: client.containers.stop(container, parsed_args.timeout) print( _('Request to stop container %s has been accepted.') % container) except Exception as e: print("Stop for container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def take_action(self, parsed_args): client = _get_client(self, parsed_args) registries = parsed_args.registry for registry in registries: opts = {} opts['id'] = registry opts = zun_utils.remove_null_parms(**opts) try: client.registries.delete(**opts) print(_('Request to delete registry %s has been accepted.') % registry) except Exception as e: print("Delete for registry %(registry)s failed: %(e)s" % {'registry': registry, 'e': e})
class RequestEntityTooLarge(HTTPClientError): """HTTP 413 - Request Entity Too Large. The request is larger than the server is willing or able to process. """ http_status = 413 message = _("Request Entity Too Large") def __init__(self, *args, **kwargs): try: self.retry_after = int(kwargs.pop('retry_after')) except (KeyError, ValueError): self.retry_after = 0 super(RequestEntityTooLarge, self).__init__(*args, **kwargs)
def take_action(self, parsed_args): client = _get_client(self, parsed_args) containers = parsed_args.container force = getattr(parsed_args, 'force') for container in containers: try: client.containers.delete(container, force) print( _('Request to delete container %s has been accepted.') % container) except Exception as e: print("Delete for container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def args_array_to_patch(op, attributes): patch = [] for attr in attributes: # Sanitize if not attr.startswith('/'): attr = '/' + attr if op in ['add', 'replace']: path, value = split_and_deserialize(attr) patch.append({'op': op, 'path': path, 'value': value}) elif op == "remove": # For remove only the key is needed patch.append({'op': op, 'path': attr}) else: raise exc.CommandError(_('Unknown PATCH operation: %s') % op) return patch
def take_action(self, parsed_args): client = _get_client(self, parsed_args) capsules = parsed_args.capsule for capsule in capsules: opts = {} opts['id'] = capsule try: client.capsules.delete(**opts) print( _('Request to delete capsule %s has been accepted.') % capsule) except Exception as e: print("Delete for capsule %(capsule)s failed: %(e)s" % { 'capsule': capsule, 'e': e })
def take_action(self, parsed_args): client = _get_client(self, parsed_args) container = parsed_args.container opts = {} opts['id'] = parsed_args.container opts['signal'] = parsed_args.signal try: client.containers.kill(**opts) print( _('Request to send kill signal to container %s has ' 'been accepted') % container) except Exception as e: print("kill signal for container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def _find_actions(self, subparsers, actions_module, version, do_help): msg = _(" (Supported by API versions '%(start)s' - '%(end)s')") for attr in (a for a in dir(actions_module) if a.startswith('do_')): # I prefer to be hyphen-separated instead of underscores. command = attr[3:].replace('_', '-') callback = getattr(actions_module, attr) desc = callback.__doc__ or '' if hasattr(callback, "versioned"): subs = api_versions.get_substitutions(callback) if do_help: desc += msg % { 'start': subs[0].start_version.get_string(), 'end': subs[-1].end_version.get_string() } else: for versioned_method in subs: if version.matches(versioned_method.start_version, versioned_method.end_version): callback = versioned_method.func break else: continue action_help = desc.strip() exclusive_args = getattr(callback, 'exclusive_args', {}) arguments = getattr(callback, 'arguments', []) subparser = (subparsers.add_parser( command, help=action_help, description=desc, add_help=False, formatter_class=OpenStackHelpFormatter)) subparser.add_argument( '-h', '--help', action='help', help=argparse.SUPPRESS, ) self.subcommands[command] = subparser self._add_subparser_args(subparser, arguments, version, do_help, msg) self._add_subparser_exclusive_args(subparser, exclusive_args, version, do_help, msg) subparser.set_defaults(func=callback)
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) 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 six.PY3: print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode()) else: print(encodeutils.safe_encode(pt.get_string(**kwargs)))
def split_and_deserialize(string): """Split and try to JSON deserialize a string. Gets a string with the KEY=VALUE format, split it (using '=' as the separator) and try to JSON deserialize the VALUE. :returns: A tuple of (key, value). """ try: key, value = string.split("=", 1) except ValueError: raise exc.CommandError(_('Attributes must be a list of ' 'PATH=VALUE not "%s"') % string) try: value = jsonutils.loads(value) except ValueError: pass return (key, value)
def split_and_deserialize(string): """Split and try to JSON deserialize a string. Gets a string with the KEY=VALUE format, split it (using '=' as the separator) and try to JSON deserialize the VALUE. :returns: A tuple of (key, value). """ try: key, value = string.split("=", 1) except ValueError: raise exc.CommandError(_('Attributes must be a list of ' 'PATH=VALUE not "%s"') % string) try: value = json.loads(value) except ValueError: pass return (key, value)
def find(self, **kwargs): """Find a single item with attributes matching ``**kwargs``. This isn't very efficient: it loads the entire list then filters on the Python side. """ matches = self.findall(**kwargs) num_matches = len(matches) if num_matches == 0: msg = _("No %(name)s matching %(args)s.") % { 'name': self.resource_class.__name__, 'args': kwargs } raise exceptions.NotFound(msg) elif num_matches > 1: raise exceptions.NoUniqueMatch() else: return matches[0]
def take_action(self, parsed_args): client = _get_client(self, parsed_args) for container in parsed_args.containers: opts = {} opts['id'] = container if parsed_args.image: opts['image'] = parsed_args.image if parsed_args.image_driver: opts['image_driver'] = parsed_args.image_driver try: client.containers.rebuild(**opts) print( _('Request to rebuild container %s has ' 'been accepted') % container) except Exception as e: print("rebuild container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def take_action(self, parsed_args): client = _get_client(self, parsed_args) containers = parsed_args.container for container in containers: opts = {} opts['id'] = container opts['force'] = parsed_args.force opts['all_tenants'] = parsed_args.all_tenants opts = zun_utils.remove_null_parms(**opts) try: client.containers.delete(**opts) print( _('Request to delete container %s has been accepted.') % container) except Exception as e: print("Delete for container %(container)s failed: %(e)s" % { 'container': container, 'e': e })
def _find_actions(self, subparsers, actions_module, version, do_help): msg = _(" (Supported by API versions '%(start)s' - '%(end)s')") for attr in (a for a in dir(actions_module) if a.startswith('do_')): # I prefer to be hyphen-separated instead of underscores. command = attr[3:].replace('_', '-') callback = getattr(actions_module, attr) desc = callback.__doc__ or '' if hasattr(callback, "versioned"): subs = api_versions.get_substitutions(callback) if do_help: desc += msg % {'start': subs[0].start_version.get_string(), 'end': subs[-1].end_version.get_string()} else: for versioned_method in subs: if version.matches(versioned_method.start_version, versioned_method.end_version): callback = versioned_method.func break else: continue action_help = desc.strip() exclusive_args = getattr(callback, 'exclusive_args', {}) arguments = getattr(callback, 'arguments', []) subparser = ( subparsers.add_parser(command, help=action_help, description=desc, add_help=False, formatter_class=OpenStackHelpFormatter) ) subparser.add_argument('-h', '--help', action='help', help=argparse.SUPPRESS,) self.subcommands[command] = subparser self._add_subparser_args(subparser, arguments, version, do_help, msg) self._add_subparser_exclusive_args(subparser, exclusive_args, version, do_help, msg) subparser.set_defaults(func=callback)
def print_dict(dct, dict_property="Property", wrap=0, value_fields=None): """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 :param value_fields: attributes that correspond to columns, in order """ pt = prettytable.PrettyTable([dict_property, 'Value']) if value_fields: pt = prettytable.PrettyTable([dict_property] + list(value_fields)) pt.align = 'l' for k, v in dct.items(): # convert dict to str to check length if isinstance(v, dict) and not value_fields: v = six.text_type(keys_and_vals_to_strs(v)) if wrap > 0: v = textwrap.fill(six.text_type(v), wrap) elif wrap < 0: raise ValueError(_("Wrap argument should be a positive integer")) # 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 = '' elif isinstance(v, dict): vals = [v[field] for field in v if field in value_fields] pt.add_row([k] + vals) elif isinstance(v, list): val = str([str(i) for i in v]) pt.add_row([k, val]) else: pt.add_row([k, v]) if six.PY3: print(encodeutils.safe_encode(pt.get_string()).decode()) else: print(encodeutils.safe_encode(pt.get_string()))
def print_dict(dct, dict_property="Property", wrap=0, value_fields=None): """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 :param value_fields: attributes that correspond to columns, in order """ pt = prettytable.PrettyTable([dict_property, 'Value']) if value_fields: pt = prettytable.PrettyTable([dict_property] + list(value_fields)) pt.align = 'l' for k, v in dct.items(): # convert dict to str to check length if isinstance(v, dict) and not value_fields: v = six.text_type(keys_and_vals_to_strs(v)) if wrap > 0: v = textwrap.fill(six.text_type(v), wrap) elif wrap < 0: raise ValueError(_("Wrap argument should be a positive integer")) # 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 = '' elif isinstance(v, dict): vals = [v[field] for field in v if field in value_fields] pt.add_row([k] + vals) elif isinstance(v, list): val = str([str(i) for i in v]) pt.add_row([k, val]) else: pt.add_row([k, v]) if six.PY3: print(encodeutils.safe_encode(pt.get_string()).decode()) else: print(encodeutils.safe_encode(pt.get_string()))
class HttpError(ClientException): """The base exception class for all HTTP exceptions.""" http_status = 0 message = _("HTTP Error") def __init__(self, message=None, details=None, response=None, request_id=None, url=None, method=None, http_status=None): self.http_status = http_status or self.http_status self.message = message or self.message self.details = details self.request_id = request_id self.response = response self.url = url self.method = method formatted_string = "%s (HTTP %s)" % (self.message, self.http_status) if request_id: formatted_string += " (Request-ID: %s)" % request_id super(HttpError, self).__init__(formatted_string)
def find(self, base_url=None, **kwargs): """Find a single item with attributes matching ``**kwargs``. :param base_url: if provided, the generated URL will be appended to it """ kwargs = self._filter_kwargs(kwargs) rl = self._list( '%(base_url)s%(query)s' % { 'base_url': self.build_url(base_url=base_url, **kwargs), 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '', }, self.collection_key) num = len(rl) if num == 0: msg = _("No %(name)s matching %(args)s.") % { 'name': self.resource_class.__name__, 'args': kwargs } raise exceptions.NotFound(msg) elif num > 1: raise exceptions.NoUniqueMatch else: return rl[0]
def decode_file_data(data): # Py3 raises binascii.Error instead of TypeError as in Py27 try: return base64.b64decode(data) except (TypeError, binascii.Error): raise exc.CommandError(_('Invalid Base 64 file data.'))
def decode_file_data(data): # Py3 raises binascii.Error instead of TypeError as in Py27 try: return base64.b64decode(data) except (TypeError, binascii.Error): raise exc.CommandError(_('Invalid Base 64 file data.'))
from oslo_serialization import jsonutils from zunclient.common import cliutils as utils from zunclient.common import template_utils from zunclient.common import utils as zun_utils from zunclient.i18n import _ def _show_capsule(capsule): zun_utils.format_container_addresses(capsule) utils.print_dict(capsule._info) @utils.arg('-f', '--template-file', metavar='<file>', required=True, help=_('Path to the template.')) def do_capsule_create(cs, args): """Create a capsule.""" opts = {} if args.template_file: template = template_utils.get_template_contents( args.template_file) opts['template'] = template cs.capsules.create(**opts) print("Request to create capsule has been accepted.") @utils.arg('--all-projects', action="store_true", default=False, help='List containers in all projects')
LOG = logging.getLogger(__name__) if not LOG.handlers: LOG.addHandler(logging.StreamHandler()) HEADER_NAME = "OpenStack-API-Version" SERVICE_TYPE = "container" MIN_API_VERSION = '1.1' MAX_API_VERSION = '1.32' DEFAULT_API_VERSION = '1.latest' _SUBSTITUTIONS = {} _type_error_msg = _("'%(other)s' should be an instance of '%(cls)s'") class APIVersion(object): """This class represents an API Version Request. This class provides convenience methods for manipulation and comparison of version numbers that we need to do to implement microversions. """ def __init__(self, version_str=None): """Create an API version object. :param version_str: String representation of APIVersionRequest. Correct format is 'X.Y', where 'X' and 'Y'
def main(self, argv): # NOTE(Christoph Jansen): With Python 3.4 argv somehow becomes a Map. # This hack fixes it. argv = list(argv) # Parse args once to find version and debug settings parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) api_version = api_versions.get_api_version(options.zun_api_version) # NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse # thinking usage-list --end is ambiguous; but it # works fine with only --endpoint-type present # Go figure. if '--endpoint_type' in argv: spot = argv.index('--endpoint_type') argv[spot] = '--endpoint-type' do_help = "help" in args subcommand_parser = self.get_subcommand_parser( api_version, do_help=do_help) self.parser = subcommand_parser if options.help or not argv: subcommand_parser.print_help() return 0 args = subcommand_parser.parse_args(argv) # Short-circuit and deal with help right away. # NOTE(jamespage): args.func is not guaranteed with python >= 3.4 if not hasattr(args, 'func') or args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 (os_username, os_project_name, os_project_id, os_user_domain_id, os_user_domain_name, os_project_domain_id, os_project_domain_name, os_auth_url, os_auth_system, endpoint_type, service_type, bypass_url, insecure, os_cacert, os_cert, os_key) = ( (args.os_username, args.os_project_name, args.os_project_id, args.os_user_domain_id, args.os_user_domain_name, args.os_project_domain_id, args.os_project_domain_name, args.os_auth_url, args.os_auth_system, args.endpoint_type, args.service_type, args.bypass_url, args.insecure, args.os_cacert, args.os_cert, args.os_key) ) if os_auth_system and os_auth_system != "keystone": auth_plugin = auth.load_plugin(os_auth_system) else: auth_plugin = None # Fetched and set later as needed os_password = None if not endpoint_type: endpoint_type = DEFAULT_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_SERVICE_TYPE # NA - there is only one service this CLI accesses # service_type = utils.get_service_type(args.func) or service_type # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not cliutils.isunauthenticated(args.func): if auth_plugin: auth_plugin.parse_opts(args) if not auth_plugin or not auth_plugin.opts: if not os_username: raise exc.CommandError("You must provide a username " "via either --os-username or " "env[OS_USERNAME]") if not os_project_name and not os_project_id: raise exc.CommandError("You must provide a project name " "or project id via --os-project-name, " "--os-project-id, env[OS_PROJECT_NAME] " "or env[OS_PROJECT_ID]") if not os_auth_url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = auth_plugin.get_auth_url() if not os_auth_url: raise exc.CommandError("You must provide an auth url " "via either --os-auth-url or " "env[OS_AUTH_URL] or specify an " "auth_system which defines a " "default url with --os-auth-system " "or env[OS_AUTH_SYSTEM]") # NOTE: The Zun client authenticates when you create it. So instead of # creating here and authenticating later, which is what the # novaclient does, we just create the client later. # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if not cliutils.isunauthenticated(args.func): # NA - Client can't be used with SecretsHelper if (auth_plugin and auth_plugin.opts and "os_password" not in auth_plugin.opts): use_pw = False else: use_pw = True if use_pw: # Auth using token must have failed or not happened # at all, so now switch to password mode and save # the token when its gotten... using our keyring # saver os_password = args.os_password if not os_password: raise exc.CommandError( 'Expecting a password provided via either ' '--os-password, env[OS_PASSWORD], or ' 'prompted response') client = base_client if not do_help: if api_version.is_latest(): # This client is just used to discover api version. # Version API needn't microversion, so we just pass # version 1.1 at here. self.cs = client.Client( version=api_versions.APIVersion("1.1"), username=os_username, password=os_password, project_id=os_project_id, project_name=os_project_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, auth_url=os_auth_url, service_type=service_type, region_name=args.os_region_name, endpoint_override=bypass_url, interface=endpoint_type, insecure=insecure, cacert=os_cacert) api_version = api_versions.discover_version(self.cs, api_version) min_version = api_versions.APIVersion(api_versions.MIN_API_VERSION) max_version = api_versions.APIVersion(api_versions.MAX_API_VERSION) if not api_version.matches(min_version, max_version): raise exc.CommandError( _("The specified version isn't supported by " "client. The valid version range is '%(min)s' " "to '%(max)s'") % { "min": min_version.get_string(), "max": max_version.get_string()} ) kwargs = {} if profiler: kwargs["profile"] = args.profile self.cs = client.Client(version=api_version, username=os_username, password=os_password, project_id=os_project_id, project_name=os_project_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, auth_url=os_auth_url, service_type=service_type, region_name=args.os_region_name, endpoint_override=bypass_url, interface=endpoint_type, insecure=insecure, cacert=os_cacert, cert=os_cert, key=os_key, **kwargs) args.func(self.cs, args) if profiler and args.profile: trace_id = profiler.get().get_base_id() print("To display trace use the command:\n\n" " osprofiler trace show --html %s " % trace_id)
def __init__(self, missing): self.missing = missing msg = _("Missing arguments: %s") % ", ".join(missing) super(MissingArgs, self).__init__(msg)
def __init__(self, endpoints=None): super(AmbiguousEndpoints, self).__init__( _("AmbiguousEndpoints: %r") % endpoints) self.endpoints = endpoints
def __init__(self, opt_names): super(AuthPluginOptionsMissing, self).__init__( _("Authentication failed. Missing options: %s") % ", ".join(opt_names)) self.opt_names = opt_names
def __init__(self, auth_system): super(AuthSystemNotFound, self).__init__( _("AuthSystemNotFound: %r") % auth_system) self.auth_system = auth_system