# Copyright 2012 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # vim: tabstop=4 shiftwidth=4 softtabstop=4 """ Common client utilities """ import os import sys import uuid from openstackclient.common import exceptions def find_resource(manager, name_or_id): """Helper for the _find_* methods.""" # first try to get entity as integer id try: if isinstance(name_or_id, int) or name_or_id.isdigit(): return manager.get(int(name_or_id)) except exceptions.NotFound: pass # now try to get entity as uuid try: uuid.UUID(str(name_or_id)) return manager.get(name_or_id) except (ValueError, exceptions.NotFound): pass # finally try to find entity by name try: return manager.find(name=name_or_id) # FIXME(dtroyer): The exception to catch here is dependent on which # client library the manager passed in belongs to. # Eventually this should be pulled from a common set # of client exceptions. except Exception as ex: if type(ex).__name__ == 'NotFound': msg = "No %s with a name or ID of '%s' exists." % \ (manager.resource_class.__name__.lower(), name_or_id) raise exceptions.CommandError(msg) else: raise def get_item_properties(item, fields, mixed_case_fields=[], formatters={}): """Return a tuple containing the item properties. :param item: a single item resource (e.g. Server, Tenant, etc) :param fields: tuple of strings with the desired field names :param mixed_case_fields: tuple of field names to preserve case :param formatters: dictionary mapping field names to callables to format the values """ row = [] for field in fields: if field in formatters: row.append(formatters[field](item)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') data = getattr(item, field_name, '') row.append(data) return tuple(row) def string_to_bool(arg): return arg.strip().lower() in ('t', 'true', 'yes', '1') def env(*vars, **kwargs): """Search for the first defined of possibly many env vars Returns the first environment variable defined in vars, or returns the default defined in kwargs. """ for v in vars: value = os.environ.get(v, None) if value: return value return kwargs.get('default', '') def import_class(import_str): """Returns a class from a string including module and class :param import_str: a string representation of the class name :rtype: the requested class """ mod_str, _sep, class_str = import_str.rpartition('.') __import__(mod_str) return getattr(sys.modules[mod_str], class_str) def get_client_class(api_name, version, version_map): """Returns the client class for the requested API version :param api_name: the name of the API, e.g. 'compute', 'image', etc :param version: the requested API version :param version_map: a dict of client classes keyed by version :rtype: a client class for the requested API version """ try: client_path = version_map[str(version)] except (KeyError, ValueError): msg = "Invalid %s client version '%s'. must be one of: %s" % ( (api_name, version, ', '.join(version_map.keys()))) raise exceptions.UnsupportedVersion(msg) return import_class(client_path)