 59ec2bb433
			
		
	
	59ec2bb433
	
	
	
		
			
			No need to set tabstop tons of times, this can be set in your vimrc file instead. More disucssion: http://openstack.10931.n7.nabble.com/Remove-vim-modelines-td21780.html Change-Id: I45766d91f0c0b3622bbdc7dc5517497c87ebee8c Closes-Bug: #1229324
		
			
				
	
	
		
			285 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Copyright 2011 OpenStack Foundation
 | |
| # Copyright 2013 Rackspace Hosting
 | |
| # 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.
 | |
| 
 | |
| from __future__ import print_function
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import uuid
 | |
| import simplejson as json
 | |
| 
 | |
| import six
 | |
| import prettytable
 | |
| 
 | |
| from troveclient.openstack.common.apiclient import exceptions
 | |
| from troveclient.openstack.common import strutils
 | |
| 
 | |
| 
 | |
| def arg(*args, **kwargs):
 | |
|     """Decorator for CLI args."""
 | |
|     def _decorator(func):
 | |
|         add_arg(func, *args, **kwargs)
 | |
|         return func
 | |
|     return _decorator
 | |
| 
 | |
| 
 | |
| def env(*vars, **kwargs):
 | |
|     """
 | |
|     returns the first environment variable set
 | |
|     if none are non-empty, defaults to '' or keyword arg default
 | |
|     """
 | |
|     for v in vars:
 | |
|         value = os.environ.get(v, None)
 | |
|         if value:
 | |
|             return value
 | |
|     return kwargs.get('default', '')
 | |
| 
 | |
| 
 | |
| def add_arg(f, *args, **kwargs):
 | |
|     """Bind CLI arguments to a shell.py `do_foo` function."""
 | |
| 
 | |
|     if not hasattr(f, 'arguments'):
 | |
|         f.arguments = []
 | |
| 
 | |
|     # NOTE(sirp): avoid dups that can occur when the module is shared across
 | |
|     # tests.
 | |
|     if (args, kwargs) not in f.arguments:
 | |
|         # Because of the semantics of decorator composition if we just append
 | |
|         # to the options list positional options will appear to be backwards.
 | |
|         f.arguments.insert(0, (args, kwargs))
 | |
| 
 | |
| 
 | |
| def unauthenticated(f):
 | |
|     """
 | |
|     Adds 'unauthenticated' attribute to decorated function.
 | |
|     Usage:
 | |
|         @unauthenticated
 | |
|         def mymethod(f):
 | |
|             ...
 | |
|     """
 | |
|     f.unauthenticated = True
 | |
|     return f
 | |
| 
 | |
| 
 | |
| def isunauthenticated(f):
 | |
|     """
 | |
|     Checks to see if the function is marked as not requiring authentication
 | |
|     with the @unauthenticated decorator. Returns True if decorator is
 | |
|     set to True, False otherwise.
 | |
|     """
 | |
|     return getattr(f, 'unauthenticated', False)
 | |
| 
 | |
| 
 | |
| def service_type(stype):
 | |
|     """
 | |
|     Adds 'service_type' attribute to decorated function.
 | |
|     Usage:
 | |
|         @service_type('database')
 | |
|         def mymethod(f):
 | |
|             ...
 | |
|     """
 | |
|     def inner(f):
 | |
|         f.service_type = stype
 | |
|         return f
 | |
|     return inner
 | |
| 
 | |
| 
 | |
| def get_service_type(f):
 | |
|     """
 | |
|     Retrieves service type from function
 | |
|     """
 | |
|     return getattr(f, 'service_type', None)
 | |
| 
 | |
| 
 | |
| def translate_keys(collection, convert):
 | |
|     for item in collection:
 | |
|         keys = list(item.__dict__.keys())
 | |
|         for from_key, to_key in convert:
 | |
|             if from_key in keys and to_key not in keys:
 | |
|                 setattr(item, to_key, item._info[from_key])
 | |
| 
 | |
| 
 | |
| def _output_override(objs, print_as):
 | |
|     """
 | |
|     If an output override global flag is set, print with override
 | |
|     raise BaseException if no printing was overridden.
 | |
|     """
 | |
|     if 'json_output' in globals() and json_output:
 | |
|         if print_as == 'list':
 | |
|             new_objs = []
 | |
|             for o in objs:
 | |
|                 new_objs.append(o._info)
 | |
|         elif print_as == 'dict':
 | |
|             new_objs = objs
 | |
|         # pretty print the json
 | |
|         print(json.dumps(new_objs, indent='  '))
 | |
|     elif 'xml_output' in globals():
 | |
|         print('not implemented')
 | |
|     else:
 | |
|         raise BaseException('No valid output override')
 | |
| 
 | |
| 
 | |
| def _print(pt, order):
 | |
| 
 | |
|     if sys.version_info >= (3, 0):
 | |
|         print(pt.get_string(sortby=order))
 | |
|     else:
 | |
|         print(strutils.safe_encode(pt.get_string(sortby=order)))
 | |
| 
 | |
| 
 | |
| def print_list(objs, fields, formatters={}, order_by=None):
 | |
|     try:
 | |
|         _output_override(objs, 'list')
 | |
|         return
 | |
|     except BaseException:
 | |
|         pass
 | |
|     mixed_case_fields = []
 | |
|     pt = prettytable.PrettyTable([f for f in fields], caching=False)
 | |
|     pt.aligns = ['l' for f in fields]
 | |
| 
 | |
|     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 order_by is None:
 | |
|         order_by = fields[0]
 | |
|     _print(pt, order_by)
 | |
| 
 | |
| 
 | |
| def print_dict(d, property="Property"):
 | |
|     try:
 | |
|         _output_override(d, 'dict')
 | |
|         return
 | |
|     except BaseException:
 | |
|         pass
 | |
|     pt = prettytable.PrettyTable([property, 'Value'], caching=False)
 | |
|     pt.aligns = ['l', 'l']
 | |
|     [pt.add_row(list(r)) for r in six.iteritems(d)]
 | |
|     _print(pt, property)
 | |
| 
 | |
| 
 | |
| 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
 | |
| 
 | |
|     if sys.version_info <= (3, 0):
 | |
|         name_or_id = strutils.safe_decode(name_or_id)
 | |
| 
 | |
|     # now try to get entity as uuid
 | |
|     try:
 | |
|         uuid.UUID(name_or_id)
 | |
|         return manager.get(name_or_id)
 | |
|     except (ValueError, exceptions.NotFound):
 | |
|         pass
 | |
| 
 | |
|     try:
 | |
|         try:
 | |
|             return manager.find(human_id=name_or_id)
 | |
|         except exceptions.NotFound:
 | |
|             pass
 | |
| 
 | |
|         # finally try to find entity by name
 | |
|         try:
 | |
|             return manager.find(name=name_or_id)
 | |
|         except exceptions.NotFound:
 | |
|             try:
 | |
|                 return manager.find(display_name=name_or_id)
 | |
|             except (UnicodeDecodeError, exceptions.NotFound):
 | |
|                 try:
 | |
|                     # Instances does not have name, but display_name
 | |
|                     return manager.find(display_name=name_or_id)
 | |
|                 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)
 | |
| 
 | |
| 
 | |
| class HookableMixin(object):
 | |
|     """Mixin so classes can register and run hooks."""
 | |
|     _hooks_map = {}
 | |
| 
 | |
|     @classmethod
 | |
|     def add_hook(cls, hook_type, hook_func):
 | |
|         if hook_type not in cls._hooks_map:
 | |
|             cls._hooks_map[hook_type] = []
 | |
| 
 | |
|         cls._hooks_map[hook_type].append(hook_func)
 | |
| 
 | |
|     @classmethod
 | |
|     def run_hooks(cls, hook_type, *args, **kwargs):
 | |
|         hook_funcs = cls._hooks_map.get(hook_type) or []
 | |
|         for hook_func in hook_funcs:
 | |
|             hook_func(*args, **kwargs)
 | |
| 
 | |
| 
 | |
| def safe_issubclass(*args):
 | |
|     """Like issubclass, but will just return False if not a class."""
 | |
| 
 | |
|     try:
 | |
|         if issubclass(*args):
 | |
|             return True
 | |
|     except TypeError:
 | |
|         pass
 | |
| 
 | |
|     return False
 | |
| 
 | |
| 
 | |
| # http://code.activestate.com/recipes/
 | |
| #   577257-slugify-make-a-string-usable-in-a-url-or-filename/
 | |
| def slugify(value):
 | |
|     """
 | |
|     Normalizes string, converts to lowercase, removes non-alpha characters,
 | |
|     and converts spaces to hyphens.
 | |
| 
 | |
|     From Django's "django/template/defaultfilters.py".
 | |
| 
 | |
|     Make use strutils.to_slug from openstack common
 | |
|     """
 | |
|     return strutils.to_slug(value, incoming=None, errors="strict")
 | |
| 
 | |
| 
 | |
| def is_uuid_like(val):
 | |
|     """Returns validation of a value as a UUID.
 | |
| 
 | |
|     For our purposes, a UUID is a canonical form string:
 | |
|     aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
 | |
| 
 | |
|     """
 | |
|     try:
 | |
|         return str(uuid.UUID(val)) == val
 | |
|     except (TypeError, ValueError, AttributeError):
 | |
|         return False
 |