Fix and enable Gating on H404
Enable gating on the Hacking H404 check - docstring should start with a summary. Change-Id: I80612a15bd11f689e9e9f4dc2ff812138630ddbd
This commit is contained in:
		
				
					committed by
					
						
						Morgan Fainberg
					
				
			
			
				
	
			
			
			
						parent
						
							0e11cf03cf
						
					
				
				
					commit
					dc5c33a9e5
				
			@@ -34,9 +34,8 @@ except NameError:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getid(obj):
 | 
			
		||||
    """
 | 
			
		||||
    Abstracts the common pattern of allowing both an object or an object's ID
 | 
			
		||||
    (UUID) as a parameter when dealing with relationships.
 | 
			
		||||
    """Abstracts the common pattern of allowing both an object or an object's
 | 
			
		||||
    ID (UUID) as a parameter when dealing with relationships.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    # Try to return the object's UUID first, if we have a UUID.
 | 
			
		||||
@@ -75,9 +74,8 @@ def filter_kwargs(f):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Manager(object):
 | 
			
		||||
    """
 | 
			
		||||
    Managers interact with a particular type of API (servers, flavors, images,
 | 
			
		||||
    etc.) and provide CRUD operations for them.
 | 
			
		||||
    """Managers interact with a particular type of API (servers, flavors,
 | 
			
		||||
    images, etc.) and provide CRUD operations for them.
 | 
			
		||||
    """
 | 
			
		||||
    resource_class = None
 | 
			
		||||
 | 
			
		||||
@@ -138,8 +136,7 @@ class Manager(object):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ManagerWithFind(Manager):
 | 
			
		||||
    """
 | 
			
		||||
    Like a `Manager`, but with additional `find()`/`findall()` methods.
 | 
			
		||||
    """Like a `Manager`, but with additional `find()`/`findall()` methods.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __metaclass__ = abc.ABCMeta
 | 
			
		||||
@@ -149,8 +146,7 @@ class ManagerWithFind(Manager):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def find(self, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Find a single item with attributes matching ``**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.
 | 
			
		||||
@@ -167,8 +163,7 @@ class ManagerWithFind(Manager):
 | 
			
		||||
            return rl[0]
 | 
			
		||||
 | 
			
		||||
    def findall(self, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Find all items with attributes matching ``**kwargs``.
 | 
			
		||||
        """Find all items with attributes matching ``**kwargs``.
 | 
			
		||||
 | 
			
		||||
        This isn't very efficient: it loads the entire list then filters on
 | 
			
		||||
        the Python side.
 | 
			
		||||
@@ -287,9 +282,7 @@ class CrudManager(Manager):
 | 
			
		||||
 | 
			
		||||
    @filter_kwargs
 | 
			
		||||
    def find(self, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Find a single item with attributes matching ``**kwargs``.
 | 
			
		||||
        """
 | 
			
		||||
        """Find a single item with attributes matching ``**kwargs``."""
 | 
			
		||||
        url = self.build_url(dict_args_in_out=kwargs)
 | 
			
		||||
 | 
			
		||||
        rl = self._list(
 | 
			
		||||
@@ -310,8 +303,7 @@ class CrudManager(Manager):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Resource(object):
 | 
			
		||||
    """
 | 
			
		||||
    A resource represents a particular instance of an object (tenant, user,
 | 
			
		||||
    """A resource represents a particular instance of an object (tenant, user,
 | 
			
		||||
    etc). This is pretty much just a bag for attributes.
 | 
			
		||||
 | 
			
		||||
    :param manager: Manager object
 | 
			
		||||
 
 | 
			
		||||
@@ -28,10 +28,9 @@ import six
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Ec2Signer(object):
 | 
			
		||||
    """
 | 
			
		||||
    Utility class which adds allows a request to be signed with an AWS style
 | 
			
		||||
    """Utility class which adds allows a request to be signed with an AWS style
 | 
			
		||||
    signature, which can then be used for authentication via the keystone ec2
 | 
			
		||||
    authentication extension
 | 
			
		||||
    authentication extension.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, secret_key):
 | 
			
		||||
@@ -41,9 +40,9 @@ class Ec2Signer(object):
 | 
			
		||||
            self.hmac_256 = hmac.new(self.secret_key, digestmod=hashlib.sha256)
 | 
			
		||||
 | 
			
		||||
    def _v4_creds(self, credentials):
 | 
			
		||||
        """
 | 
			
		||||
        Detect if the credentials are for a v4 signed request, since AWS
 | 
			
		||||
        """Detect if the credentials are for a v4 signed request, since AWS
 | 
			
		||||
        removed the SignatureVersion field from the v4 request spec...
 | 
			
		||||
 | 
			
		||||
        This expects a dict of the request headers to be passed in the
 | 
			
		||||
        credentials dict, since the recommended way to pass v4 creds is
 | 
			
		||||
        via the 'Authorization' header
 | 
			
		||||
@@ -127,9 +126,8 @@ class Ec2Signer(object):
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def _canonical_qs(params):
 | 
			
		||||
        """
 | 
			
		||||
        Construct a sorted, correctly encoded query string as required for
 | 
			
		||||
        _calc_signature_2 and _calc_signature_4
 | 
			
		||||
        """Construct a sorted, correctly encoded query string as required for
 | 
			
		||||
        _calc_signature_2 and _calc_signature_4.
 | 
			
		||||
        """
 | 
			
		||||
        keys = params.keys()
 | 
			
		||||
        keys.sort()
 | 
			
		||||
@@ -164,8 +162,7 @@ class Ec2Signer(object):
 | 
			
		||||
                            hashlib.sha256).digest()
 | 
			
		||||
 | 
			
		||||
        def signature_key(datestamp, region_name, service_name):
 | 
			
		||||
            """
 | 
			
		||||
            Signature key derivation, see
 | 
			
		||||
            """Signature key derivation, see
 | 
			
		||||
            http://docs.aws.amazon.com/general/latest/gr/
 | 
			
		||||
            signature-v4-examples.html#signature-v4-examples-python
 | 
			
		||||
            """
 | 
			
		||||
@@ -177,8 +174,9 @@ class Ec2Signer(object):
 | 
			
		||||
            return k_signing
 | 
			
		||||
 | 
			
		||||
        def auth_param(param_name):
 | 
			
		||||
            """
 | 
			
		||||
            Get specified auth parameter, provided via one of:
 | 
			
		||||
            """Get specified auth parameter.
 | 
			
		||||
 | 
			
		||||
            Provided via one of:
 | 
			
		||||
            - the Authorization header
 | 
			
		||||
            - the X-Amz-* query parameters
 | 
			
		||||
            """
 | 
			
		||||
@@ -191,8 +189,8 @@ class Ec2Signer(object):
 | 
			
		||||
            return param_str
 | 
			
		||||
 | 
			
		||||
        def date_param():
 | 
			
		||||
            """
 | 
			
		||||
            Get the X-Amz-Date' value, which can be either a header or paramter
 | 
			
		||||
            """Get the X-Amz-Date' value, which can be either a header
 | 
			
		||||
            or parameter.
 | 
			
		||||
 | 
			
		||||
            Note AWS supports parsing the Date header also, but this is not
 | 
			
		||||
            currently supported here as it will require some format mangling
 | 
			
		||||
 
 | 
			
		||||
@@ -42,9 +42,8 @@ class NoUniqueMatch(Exception):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClientException(Exception):
 | 
			
		||||
    """
 | 
			
		||||
    The base exception class for all exceptions this library raises.
 | 
			
		||||
    """
 | 
			
		||||
    """The base exception class for all exceptions this library raises."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, code, message=None, details=None):
 | 
			
		||||
        self.code = code
 | 
			
		||||
        self.message = message or self.__class__.message
 | 
			
		||||
@@ -55,24 +54,21 @@ class ClientException(Exception):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BadRequest(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 400 - Bad request: you sent some malformed data.
 | 
			
		||||
    """
 | 
			
		||||
    """HTTP 400 - Bad request: you sent some malformed data."""
 | 
			
		||||
 | 
			
		||||
    http_status = 400
 | 
			
		||||
    message = "Bad request"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Unauthorized(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 401 - Unauthorized: bad credentials.
 | 
			
		||||
    """
 | 
			
		||||
    """HTTP 401 - Unauthorized: bad credentials."""
 | 
			
		||||
 | 
			
		||||
    http_status = 401
 | 
			
		||||
    message = "Unauthorized"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Forbidden(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 403 - Forbidden: your credentials don't give you access to this
 | 
			
		||||
    """HTTP 403 - Forbidden: your credentials do not allow access to this
 | 
			
		||||
    resource.
 | 
			
		||||
    """
 | 
			
		||||
    http_status = 403
 | 
			
		||||
@@ -80,32 +76,26 @@ class Forbidden(ClientException):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NotFound(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 404 - Not found
 | 
			
		||||
    """
 | 
			
		||||
    """HTTP 404 - Not found."""
 | 
			
		||||
    http_status = 404
 | 
			
		||||
    message = "Not found"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MethodNotAllowed(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 405 - Method not allowed
 | 
			
		||||
    """
 | 
			
		||||
    """HTTP 405 - Method not allowed."""
 | 
			
		||||
    http_status = 405
 | 
			
		||||
    message = "Method not allowed"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Conflict(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 409 - Conflict
 | 
			
		||||
    """
 | 
			
		||||
    """HTTP 409 - Conflict."""
 | 
			
		||||
    http_status = 409
 | 
			
		||||
    message = "Conflict"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OverLimit(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 413 - Over limit: you're over the API limits for this time period.
 | 
			
		||||
    """HTTP 413 - Over limit: you're over the API limits for this time
 | 
			
		||||
    period.
 | 
			
		||||
    """
 | 
			
		||||
    http_status = 413
 | 
			
		||||
    message = "Over limit"
 | 
			
		||||
@@ -113,17 +103,15 @@ class OverLimit(ClientException):
 | 
			
		||||
 | 
			
		||||
# NotImplemented is a python keyword.
 | 
			
		||||
class HTTPNotImplemented(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 501 - Not Implemented: the server does not support this operation.
 | 
			
		||||
    """HTTP 501 - Not Implemented: the server does not support this
 | 
			
		||||
    operation.
 | 
			
		||||
    """
 | 
			
		||||
    http_status = 501
 | 
			
		||||
    message = "Not Implemented"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ServiceUnavailable(ClientException):
 | 
			
		||||
    """
 | 
			
		||||
    HTTP 503 - Service Unavailable: The server is currently unavailable.
 | 
			
		||||
    """
 | 
			
		||||
    """HTTP 503 - Service Unavailable: The server is currently unavailable."""
 | 
			
		||||
    http_status = 503
 | 
			
		||||
    message = "Service Unavailable"
 | 
			
		||||
 | 
			
		||||
@@ -146,9 +134,8 @@ _code_map = dict((c.http_status, c) for c in [BadRequest,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def from_response(response, body=None):
 | 
			
		||||
    """
 | 
			
		||||
    Return an instance of an ClientException or subclass
 | 
			
		||||
    based on an requests response.
 | 
			
		||||
    """Return an instance of a ClientException or subclass
 | 
			
		||||
    based on a requests response.
 | 
			
		||||
 | 
			
		||||
    Usage::
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -442,8 +442,8 @@ class OpenStackIdentityShell(object):
 | 
			
		||||
            return shell_v2_0.CLIENT_CLASS
 | 
			
		||||
 | 
			
		||||
    def do_bash_completion(self, args):
 | 
			
		||||
        """
 | 
			
		||||
        Prints all of the commands and options to stdout.
 | 
			
		||||
        """Prints all of the commands and options to stdout.
 | 
			
		||||
 | 
			
		||||
        The keystone.bash_completion script doesn't have to hard code them.
 | 
			
		||||
        """
 | 
			
		||||
        commands = set()
 | 
			
		||||
@@ -460,9 +460,7 @@ class OpenStackIdentityShell(object):
 | 
			
		||||
    @utils.arg('command', metavar='<subcommand>', nargs='?',
 | 
			
		||||
               help='Display help for <subcommand>')
 | 
			
		||||
    def do_help(self, args):
 | 
			
		||||
        """
 | 
			
		||||
        Display help about this program or one of its subcommands.
 | 
			
		||||
        """
 | 
			
		||||
        """Display help about this program or one of its subcommands."""
 | 
			
		||||
        if getattr(args, 'command', None):
 | 
			
		||||
            if args.command in self.subcommands:
 | 
			
		||||
                self.subcommands[args.command].print_help()
 | 
			
		||||
 
 | 
			
		||||
@@ -113,10 +113,10 @@ def unauthenticated(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.
 | 
			
		||||
    """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)
 | 
			
		||||
 | 
			
		||||
@@ -135,8 +135,7 @@ def hash_signed_token(signed_text):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def prompt_for_password():
 | 
			
		||||
    """
 | 
			
		||||
     Prompt user for password if not provided so the password
 | 
			
		||||
    """Prompt user for password if not provided so the password
 | 
			
		||||
    doesn't show up in the bash history.
 | 
			
		||||
    """
 | 
			
		||||
    if not (hasattr(sys.stdin, 'isatty') and sys.stdin.isatty()):
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,8 @@ class CredentialsManager(base.ManagerWithFind):
 | 
			
		||||
    resource_class = EC2
 | 
			
		||||
 | 
			
		||||
    def create(self, user_id, tenant_id):
 | 
			
		||||
        """
 | 
			
		||||
        Create a new access/secret pair for the user/tenant pair
 | 
			
		||||
        """Create a new access/secret pair for the user/tenant pair.
 | 
			
		||||
 | 
			
		||||
        :rtype: object of type :class:`EC2`
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
@@ -39,24 +39,22 @@ class CredentialsManager(base.ManagerWithFind):
 | 
			
		||||
                            params, "credential")
 | 
			
		||||
 | 
			
		||||
    def list(self, user_id):
 | 
			
		||||
        """
 | 
			
		||||
        Get a list of access/secret pairs for a user_id
 | 
			
		||||
        """Get a list of access/secret pairs for a user_id.
 | 
			
		||||
 | 
			
		||||
        :rtype: list of :class:`EC2`
 | 
			
		||||
        """
 | 
			
		||||
        return self._list("/users/%s/credentials/OS-EC2" % user_id,
 | 
			
		||||
                          "credentials")
 | 
			
		||||
 | 
			
		||||
    def get(self, user_id, access):
 | 
			
		||||
        """
 | 
			
		||||
        Get the access/secret pair for a given access key
 | 
			
		||||
        """Get the access/secret pair for a given access key.
 | 
			
		||||
 | 
			
		||||
        :rtype: object of type :class:`EC2`
 | 
			
		||||
        """
 | 
			
		||||
        return self._get("/users/%s/credentials/OS-EC2/%s" %
 | 
			
		||||
                         (user_id, base.getid(access)), "credential")
 | 
			
		||||
 | 
			
		||||
    def delete(self, user_id, access):
 | 
			
		||||
        """
 | 
			
		||||
        Delete an access/secret pair for a user
 | 
			
		||||
        """
 | 
			
		||||
        """Delete an access/secret pair for a user."""
 | 
			
		||||
        return self._delete("/users/%s/credentials/OS-EC2/%s" %
 | 
			
		||||
                            (user_id, base.getid(access)))
 | 
			
		||||
 
 | 
			
		||||
@@ -34,22 +34,16 @@ class RoleManager(base.ManagerWithFind):
 | 
			
		||||
        return self._get("/OS-KSADM/roles/%s" % base.getid(role), "role")
 | 
			
		||||
 | 
			
		||||
    def create(self, name):
 | 
			
		||||
        """
 | 
			
		||||
        Create a role.
 | 
			
		||||
        """
 | 
			
		||||
        """Create a role."""
 | 
			
		||||
        params = {"role": {"name": name}}
 | 
			
		||||
        return self._create('/OS-KSADM/roles', params, "role")
 | 
			
		||||
 | 
			
		||||
    def delete(self, role):
 | 
			
		||||
        """
 | 
			
		||||
        Delete a role.
 | 
			
		||||
        """
 | 
			
		||||
        """Delete a role."""
 | 
			
		||||
        return self._delete("/OS-KSADM/roles/%s" % base.getid(role))
 | 
			
		||||
 | 
			
		||||
    def list(self):
 | 
			
		||||
        """
 | 
			
		||||
        List all available roles.
 | 
			
		||||
        """
 | 
			
		||||
        """List all available roles."""
 | 
			
		||||
        return self._list("/OS-KSADM/roles", "roles")
 | 
			
		||||
 | 
			
		||||
    def roles_for_user(self, user, tenant=None):
 | 
			
		||||
 
 | 
			
		||||
@@ -75,10 +75,7 @@ class TenantManager(base.ManagerWithFind):
 | 
			
		||||
        return self._get("/tenants/%s" % tenant_id, "tenant")
 | 
			
		||||
 | 
			
		||||
    def create(self, tenant_name, description=None, enabled=True, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Create a new tenant.
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        """Create a new tenant."""
 | 
			
		||||
        params = {"tenant": {"name": tenant_name,
 | 
			
		||||
                             "description": description,
 | 
			
		||||
                             "enabled": enabled}}
 | 
			
		||||
@@ -91,8 +88,7 @@ class TenantManager(base.ManagerWithFind):
 | 
			
		||||
        return self._create('/tenants', params, "tenant")
 | 
			
		||||
 | 
			
		||||
    def list(self, limit=None, marker=None):
 | 
			
		||||
        """
 | 
			
		||||
        Get a list of tenants.
 | 
			
		||||
        """Get a list of tenants.
 | 
			
		||||
 | 
			
		||||
        :param integer limit: maximum number to return. (optional)
 | 
			
		||||
        :param string marker: use when specifying a limit and making
 | 
			
		||||
@@ -125,9 +121,7 @@ class TenantManager(base.ManagerWithFind):
 | 
			
		||||
 | 
			
		||||
    def update(self, tenant_id, tenant_name=None, description=None,
 | 
			
		||||
               enabled=None, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Update a tenant with a new name and description.
 | 
			
		||||
        """
 | 
			
		||||
        """Update a tenant with a new name and description."""
 | 
			
		||||
        body = {"tenant": {'id': tenant_id}}
 | 
			
		||||
        if tenant_name is not None:
 | 
			
		||||
            body['tenant']['name'] = tenant_name
 | 
			
		||||
@@ -145,9 +139,7 @@ class TenantManager(base.ManagerWithFind):
 | 
			
		||||
        return self._create("/tenants/%s" % tenant_id, body, "tenant")
 | 
			
		||||
 | 
			
		||||
    def delete(self, tenant):
 | 
			
		||||
        """
 | 
			
		||||
        Delete a tenant.
 | 
			
		||||
        """
 | 
			
		||||
        """Delete a tenant."""
 | 
			
		||||
        return self._delete("/tenants/%s" % (base.getid(tenant)))
 | 
			
		||||
 | 
			
		||||
    def list_users(self, tenant):
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,7 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
        return self._get("/users/%s" % base.getid(user), "user")
 | 
			
		||||
 | 
			
		||||
    def update(self, user, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Update user data.
 | 
			
		||||
        """Update user data.
 | 
			
		||||
 | 
			
		||||
        Supported arguments include ``name``, ``email``, and ``enabled``.
 | 
			
		||||
        """
 | 
			
		||||
@@ -52,9 +51,7 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
        return self._update(url, params, "user")
 | 
			
		||||
 | 
			
		||||
    def update_enabled(self, user, enabled):
 | 
			
		||||
        """
 | 
			
		||||
        Update enabled-ness
 | 
			
		||||
        """
 | 
			
		||||
        """Update enabled-ness."""
 | 
			
		||||
        params = {"user": {"id": base.getid(user),
 | 
			
		||||
                           "enabled": enabled}}
 | 
			
		||||
 | 
			
		||||
@@ -62,9 +59,7 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
                     "user")
 | 
			
		||||
 | 
			
		||||
    def update_password(self, user, password):
 | 
			
		||||
        """
 | 
			
		||||
        Update password
 | 
			
		||||
        """
 | 
			
		||||
        """Update password."""
 | 
			
		||||
        params = {"user": {"id": base.getid(user),
 | 
			
		||||
                           "password": password}}
 | 
			
		||||
 | 
			
		||||
@@ -72,9 +67,7 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
                            params, "user")
 | 
			
		||||
 | 
			
		||||
    def update_own_password(self, origpasswd, passwd):
 | 
			
		||||
        """
 | 
			
		||||
        Update password
 | 
			
		||||
        """
 | 
			
		||||
        """Update password."""
 | 
			
		||||
        params = {"user": {"password": passwd,
 | 
			
		||||
                           "original_password": origpasswd}}
 | 
			
		||||
 | 
			
		||||
@@ -84,9 +77,7 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
                            management=False)
 | 
			
		||||
 | 
			
		||||
    def update_tenant(self, user, tenant):
 | 
			
		||||
        """
 | 
			
		||||
        Update default tenant.
 | 
			
		||||
        """
 | 
			
		||||
        """Update default tenant."""
 | 
			
		||||
        params = {"user": {"id": base.getid(user),
 | 
			
		||||
                           "tenantId": base.getid(tenant)}}
 | 
			
		||||
 | 
			
		||||
@@ -96,9 +87,7 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
                            params, "user")
 | 
			
		||||
 | 
			
		||||
    def create(self, name, password, email, tenant_id=None, enabled=True):
 | 
			
		||||
        """
 | 
			
		||||
        Create a user.
 | 
			
		||||
        """
 | 
			
		||||
        """Create a user."""
 | 
			
		||||
        # FIXME(ja): email should be optional, keystone currently requires it
 | 
			
		||||
        params = {"user": {"name": name,
 | 
			
		||||
                           "password": password,
 | 
			
		||||
@@ -108,14 +97,11 @@ class UserManager(base.ManagerWithFind):
 | 
			
		||||
        return self._create('/users', params, "user")
 | 
			
		||||
 | 
			
		||||
    def delete(self, user):
 | 
			
		||||
        """
 | 
			
		||||
        Delete a user.
 | 
			
		||||
        """
 | 
			
		||||
        """Delete a user."""
 | 
			
		||||
        return self._delete("/users/%s" % base.getid(user))
 | 
			
		||||
 | 
			
		||||
    def list(self, tenant_id=None, limit=None, marker=None):
 | 
			
		||||
        """
 | 
			
		||||
        Get a list of users (optionally limited to a tenant)
 | 
			
		||||
        """Get a list of users (optionally limited to a tenant).
 | 
			
		||||
 | 
			
		||||
        :rtype: list of :class:`User`
 | 
			
		||||
        """
 | 
			
		||||
 
 | 
			
		||||
@@ -23,9 +23,7 @@ def assert_has_keys(dict, required=[], optional=[]):
 | 
			
		||||
class FakeClient(object):
 | 
			
		||||
 | 
			
		||||
    def assert_called(self, method, url, body=None, pos=-1):
 | 
			
		||||
        """
 | 
			
		||||
        Assert than an API method was just called.
 | 
			
		||||
        """
 | 
			
		||||
        """Assert than an API method was just called."""
 | 
			
		||||
        expected = (method, url)
 | 
			
		||||
        called = self.callstack[pos][0:2]
 | 
			
		||||
 | 
			
		||||
@@ -38,9 +36,7 @@ class FakeClient(object):
 | 
			
		||||
            assert self.callstack[pos][2] == body
 | 
			
		||||
 | 
			
		||||
    def assert_called_anytime(self, method, url, body=None):
 | 
			
		||||
        """
 | 
			
		||||
        Assert than an API method was called anytime in the test.
 | 
			
		||||
        """
 | 
			
		||||
        """Assert than an API method was called anytime in the test."""
 | 
			
		||||
        expected = (method, url)
 | 
			
		||||
 | 
			
		||||
        assert self.callstack, ("Expected %s %s but no calls were made." %
 | 
			
		||||
 
 | 
			
		||||
@@ -105,8 +105,9 @@ class Ec2SignerTest(testtools.TestCase):
 | 
			
		||||
        self.assertEqual(signature, expected)
 | 
			
		||||
 | 
			
		||||
    def test_generate_v4(self):
 | 
			
		||||
        """
 | 
			
		||||
        Test v4 generator with data from AWS docs example, see:
 | 
			
		||||
        """Test v4 generator with data from AWS docs example.
 | 
			
		||||
 | 
			
		||||
        see:
 | 
			
		||||
        http://docs.aws.amazon.com/general/latest/gr/
 | 
			
		||||
        sigv4-create-canonical-request.html
 | 
			
		||||
        and
 | 
			
		||||
@@ -145,9 +146,7 @@ class Ec2SignerTest(testtools.TestCase):
 | 
			
		||||
        self.assertEqual(signature, expected)
 | 
			
		||||
 | 
			
		||||
    def test_generate_v4_port(self):
 | 
			
		||||
        """
 | 
			
		||||
        Test v4 generator with host:port format
 | 
			
		||||
        """
 | 
			
		||||
        """Test v4 generator with host:port format."""
 | 
			
		||||
        # Create a new signer object with the AWS example key
 | 
			
		||||
        secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
 | 
			
		||||
        signer = Ec2Signer(secret)
 | 
			
		||||
@@ -181,10 +180,9 @@ class Ec2SignerTest(testtools.TestCase):
 | 
			
		||||
        self.assertEqual(signature, expected)
 | 
			
		||||
 | 
			
		||||
    def test_generate_v4_port_strip(self):
 | 
			
		||||
        """
 | 
			
		||||
        Test v4 generator with host:port format, but for an old
 | 
			
		||||
        """Test v4 generator with host:port format, but for an old
 | 
			
		||||
        (<2.9.3) version of boto, where the port should be stripped
 | 
			
		||||
        to match boto behavior
 | 
			
		||||
        to match boto behavior.
 | 
			
		||||
        """
 | 
			
		||||
        # Create a new signer object with the AWS example key
 | 
			
		||||
        secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
 | 
			
		||||
@@ -220,9 +218,8 @@ class Ec2SignerTest(testtools.TestCase):
 | 
			
		||||
        self.assertEqual(expected, signature)
 | 
			
		||||
 | 
			
		||||
    def test_generate_v4_port_nostrip(self):
 | 
			
		||||
        """
 | 
			
		||||
        Test v4 generator with host:port format, but for an new
 | 
			
		||||
        (>=2.9.3) version of boto, where the port should not be stripped
 | 
			
		||||
        """Test v4 generator with host:port format, but for an new
 | 
			
		||||
        (>=2.9.3) version of boto, where the port should not be stripped.
 | 
			
		||||
        """
 | 
			
		||||
        # Create a new signer object with the AWS example key
 | 
			
		||||
        secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
 | 
			
		||||
 
 | 
			
		||||
@@ -54,8 +54,7 @@ class KeyringTest(utils.TestCase):
 | 
			
		||||
        keyring.set_keyring(MemoryKeyring())
 | 
			
		||||
 | 
			
		||||
    def test_no_keyring_key(self):
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that we get no value back if we don't have use_keyring
 | 
			
		||||
        """Ensure that we get no value back if we don't have use_keyring
 | 
			
		||||
        set in the client.
 | 
			
		||||
        """
 | 
			
		||||
        cl = httpclient.HTTPClient(username=USERNAME, password=PASSWORD,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tox.ini
									
									
									
									
									
								
							@@ -34,6 +34,6 @@ downloadcache = ~/cache/pip
 | 
			
		||||
# H302: import only modules
 | 
			
		||||
# H304: no relative imports
 | 
			
		||||
# H404: multi line docstring should start with a summary
 | 
			
		||||
ignore = F811,F821,F841,H102,H302,H304,H404
 | 
			
		||||
ignore = F811,F821,F841,H102,H302,H304
 | 
			
		||||
show-source = True
 | 
			
		||||
exclude = .venv,.tox,dist,doc,*egg,build
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user