#!/usr/bin/python
# -*- coding: utf-8 -*-

# Based on Jimmy Tang's implementation

DOCUMENTATION = '''
---
module: keystone_user
version_added: "1.2"
short_description: Manage OpenStack Identity (keystone) users, tenants and roles
description:
   - Manage users,tenants, roles from OpenStack.
options:
   login_user:
     description:
        - login username to authenticate to keystone
     required: false
     default: admin
   login_password:
     description:
        - Password of login user
     required: false
     default: 'yes'
   login_tenant_name:
     description:
        - The tenant login_user belongs to
     required: false
     default: None
     version_added: "1.3"
   token:
     description:
        - The token to be uses in case the password is not specified
     required: false
     default: None
   endpoint:
     description:
        - The keystone url for authentication
     required: false
     default: 'http://127.0.0.1:35357/v2.0/'
   user:
     description:
        - The name of the user that has to added/removed from OpenStack
     required: false
     default: None
   password:
     description:
        - The password to be assigned to the user
     required: false
     default: None
   tenant:
     description:
        - The tenant name that has be added/removed
     required: false
     default: None
   tenant_description:
     description:
        - A description for the tenant
     required: false
     default: None
   email:
     description:
        - An email address for the user
     required: false
     default: None
   role:
     description:
        - The name of the role to be assigned or created
     required: false
     default: None
   state:
     description:
        - Indicate desired state of the resource
     choices: ['present', 'absent']
     default: present
requirements: [ python-keystoneclient ]
author: Lorin Hochstein
'''

EXAMPLES = '''
# Create a tenant
- keystone_user: tenant=demo tenant_description="Default Tenant"

# Create a user
- keystone_user: user=john tenant=demo password=secrete

# Apply the admin role to the john user in the demo tenant
- keystone_user: role=admin user=john tenant=demo
'''

try:
    from keystoneclient.v2_0 import client
except ImportError:
    keystoneclient_found = False
else:
    keystoneclient_found = True


def authenticate(endpoint, token, login_user, login_password, login_tenant_name):
    """Return a keystone client object"""

    if token:
        return client.Client(endpoint=endpoint, token=token)
    else:
        return client.Client(auth_url=endpoint, username=login_user,
                             password=login_password, tenant_name=login_tenant_name)


def tenant_exists(keystone, tenant):
    """ Return True if tenant already exists"""
    return tenant in [x.name for x in keystone.tenants.list()]


def user_exists(keystone, user):
    """" Return True if user already exists"""
    return user in [x.name for x in keystone.users.list()]


def get_tenant(keystone, name):
    """ Retrieve a tenant by name"""
    tenants = [x for x in keystone.tenants.list() if x.name == name]
    count = len(tenants)
    if count == 0:
        raise KeyError("No keystone tenants with name %s" % name)
    elif count > 1:
        raise ValueError("%d tenants with name %s" % (count, name))
    else:
        return tenants[0]


def get_user(keystone, name):
    """ Retrieve a user by name"""
    users = [x for x in keystone.users.list() if x.name == name]
    count = len(users)
    if count == 0:
        raise KeyError("No keystone users with name %s" % name)
    elif count > 1:
        raise ValueError("%d users with name %s" % (count, name))
    else:
        return users[0]


def get_role(keystone, name):
    """ Retrieve a role by name"""
    roles = [x for x in keystone.roles.list() if x.name == name]
    count = len(roles)
    if count == 0:
        raise KeyError("No keystone roles with name %s" % name)
    elif count > 1:
        raise ValueError("%d roles with name %s" % (count, name))
    else:
        return roles[0]


def get_tenant_id(keystone, name):
    return get_tenant(keystone, name).id


def get_user_id(keystone, name):
    return get_user(keystone, name).id


def ensure_tenant_exists(keystone, tenant_name, tenant_description,
                         check_mode):
    """ Ensure that a tenant exists.

        Return (True, id) if a new tenant was created, (False, None) if it
        already existed.
    """

    # Check if tenant already exists
    try:
        tenant = get_tenant(keystone, tenant_name)
    except KeyError:
        # Tenant doesn't exist yet
        pass
    else:
        if tenant.description == tenant_description:
            return (False, tenant.id)
        else:
            # We need to update the tenant description
            if check_mode:
                return (True, tenant.id)
            else:
                tenant.update(description=tenant_description)
                return (True, tenant.id)

    # We now know we will have to create a new tenant
    if check_mode:
        return (True, None)

    ks_tenant = keystone.tenants.create(tenant_name=tenant_name,
                                        description=tenant_description,
                                        enabled=True)
    return (True, ks_tenant.id)
    

def ensure_tenant_absent(keystone, tenant, check_mode):
    """ Ensure that a tenant does not exist

         Return True if the tenant was removed, False if it didn't exist
         in the first place
    """
    if not tenant_exists(keystone, tenant):
        return False

    # We now know we will have to delete the tenant
    if check_mode:
        return True

def ensure_user_exists_and_is_current(keystone, endpoint, user_name, password, email, tenant_name,
                       check_mode):
    """ Check if user exists and has the same email and password

        Return (True, id) if a new user was created or one was updated, (False, id) if the user is 
        up to date
    """
    
    # Check if tenant already exists
    try:
        user = get_user(keystone, user_name)
    except KeyError:
        # Tenant doesn't exist yet
        user = None
        pass
    else:
        # User does exist, check if it's current
        try:
            authenticate(endpoint, None, user_name, password, tenant_name)
        except: 
            pass
        else:
            # It's current, we're done
            return (False, user.id)

    # We now know we will have to create a new user
    if check_mode:
        return (True, None)

    tenant = get_tenant(keystone, tenant_name)

    if (not user):
        user = keystone.users.create(name=user_name, password=password,
                                 email=email, tenant_id=tenant.id)
    else:
        user = keystone.users.update_password(user.id, password)
        
    return (True, user.id)


def ensure_role_exists(keystone, user_name, tenant_name, role_name,
                       check_mode):
    """ Check if role exists

        Return (True, id) if a new role was created or if the role was newly
        assigned to the user for the tenant. (False, id) if the role already
        exists and was already assigned to the user ofr the tenant.

    """
    # Check if the user has the role in the tenant
    user = get_user(keystone, user_name)
    tenant = get_tenant(keystone, tenant_name)
    roles = [x for x in keystone.roles.roles_for_user(user, tenant)
                     if x.name == role_name]
    count = len(roles)

    if count == 1:
        # If the role is in there, we are done
        role = roles[0]
        return (False, role.id)
    elif count > 1:
        # Too many roles with the same name, throw an error
        raise ValueError("%d roles with name %s" % (count, role_name))

    # At this point, we know we will need to make changes
    if check_mode:
        return (True, None)

    # Get the role if it exists
    try:
        role = get_role(keystone, role_name)
    except KeyError:
        # Role doesn't exist yet
        role = keystone.roles.create(role_name)

    # Associate the role with the user in the admin
    keystone.roles.add_user_role(user, role, tenant)
    return (True, role.id)


def ensure_user_absent(keystone, user, check_mode):
    raise NotImplementedError("Not yet implemented")


def ensure_role_absent(keystone, uesr, tenant, role, check_mode):
    raise NotImplementedError("Not yet implemented")


def main():

    argument_spec = openstack_argument_spec()
    argument_spec.update(dict(
            tenant_description=dict(required=False),
            email=dict(required=False),
            user=dict(required=False),
            tenant=dict(required=False),
            password=dict(required=False),
            role=dict(required=False),
            state=dict(default='present', choices=['present', 'absent']),
            endpoint=dict(required=False,
                          default="http://127.0.0.1:35357/v2.0"),
            token=dict(required=False),
            login_user=dict(required=False),
            login_password=dict(required=False),
            login_tenant_name=dict(required=False)
    ))
    # keystone operations themselves take an endpoint, not a keystone auth_url
    del(argument_spec['auth_url'])
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        mutually_exclusive=[['token', 'login_user'],
                            ['token', 'login_password'],
                            ['token', 'login_tenant_name']]
    )

    if not keystoneclient_found:
        module.fail_json(msg="the python-keystoneclient module is required")

    user = module.params['user']
    password = module.params['password']
    tenant = module.params['tenant']
    tenant_description = module.params['tenant_description']
    email = module.params['email']
    role = module.params['role']
    state = module.params['state']
    endpoint = module.params['endpoint']
    token = module.params['token']
    login_user = module.params['login_user']
    login_password = module.params['login_password']
    login_tenant_name = module.params['login_tenant_name']

    keystone = authenticate(endpoint, token, login_user, login_password, login_tenant_name)

    check_mode = module.check_mode

    try:
        d = dispatch(keystone, user, password, tenant, tenant_description,
                     email, role, state, endpoint, token, login_user,
                     login_password, check_mode)
    except Exception, e:
        if check_mode:
            # If we have a failure in check mode
            module.exit_json(changed=True,
                             msg="exception: %s" % e)
        else:
            module.fail_json(msg="exception: %s" % e)
    else:
        module.exit_json(**d)


def dispatch(keystone, user=None, password=None, tenant=None,
             tenant_description=None, email=None, role=None,
             state="present", endpoint=None, token=None, login_user=None,
             login_password=None, check_mode=False):
    """ Dispatch to the appropriate method.

        Returns a dict that will be passed to exit_json

        tenant  user  role   state
        ------  ----  ----  --------
          X                  present     ensure_tenant_exists
          X                  absent      ensure_tenant_absent
          X      X           present     ensure_user_exists
          X      X           absent      ensure_user_absent
          X      X     X     present     ensure_role_exists
          X      X     X     absent      ensure_role_absent


        """
    changed = False
    id = None
    if tenant and not user and not role and state == "present":
        changed, id = ensure_tenant_exists(keystone, tenant,
                                           tenant_description, check_mode)
    elif tenant and not user and not role and state == "absent":
        changed = ensure_tenant_absent(keystone, tenant, check_mode)
    elif tenant and user and not role and state == "present":
        changed, id = ensure_user_exists_and_is_current(keystone, endpoint, user, password,
                                         email, tenant, check_mode)
    elif tenant and user and not role and state == "absent":
        changed = ensure_user_absent(keystone, user, check_mode)
    elif tenant and user and role and state == "present":
        changed, id = ensure_role_exists(keystone, user, tenant, role,
                                         check_mode)
    elif tenant and user and role and state == "absent":
        changed = ensure_role_absent(keystone, user, tenant, role, check_mode)
    else:
        # Should never reach here
        raise ValueError("Code should never reach here")

    return dict(changed=changed, id=id)

# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.openstack import *
if __name__ == '__main__':
    main()
