#!/bin/bash
#
# Copyright 2013 Hewlett-Packard Development Company, L.P.
# 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.

set -eu

SCRIPT_NAME=$(basename $0)
SCRIPT_HOME=$(dirname $0)

GROUP=""
PASSWORD=""

function show_options {
    echo "Usage: $SCRIPT_NAME [options] <username> <useremail>"
    echo
    echo "Create a well formed user in a cloud."
    echo "A tenant with the same name as the user is automatically created unless"
    echo "it already exists."
    echo
    echo "The admin user is added to the tenant in the admin role."
    echo
    echo "Options:"
    echo "    -p, --password -- the password for the user."
    echo
    echo "For instance: $SCRIPT_NAME joe joe@example.com"
    echo "would create a tenant 'joe', a user 'joe' with email joe@example.com"
    echo "and a random password."
    exit $1
}

TEMP=`getopt -o p: -l password: -n $SCRIPT_NAME -- "$@"`
if [ $? != 0 ]; then
    echo "Terminating..." >&2
    exit 1
fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
    case "$1" in
        -p | --password) export PASSWORD="$2"; shift 2 ;;
        -h) show_options 0;;
        --) shift ; break ;;
        *) echo "Error: unsupported option $1." ; exit 1 ;;
    esac
done

NAME=${1:-""}
EMAIL=${2:-""}

if [ -z "$NAME" -o -z "$EMAIL" ]; then
    show_options 1
fi

PASSWORD=${PASSWORD:-$(os-make-password)}

ADMIN_ROLE=$(openstack role show admin| awk '$2=="id" {print $4}')
if [ -z "$ADMIN_ROLE" ]; then
    echo "Could not find admin role" >&2
    exit 1
fi
MEMBER_ROLE=$(openstack role show _member_| awk '$2=="id" {print $4}')
# Role _member_ is implicitly created by Keystone only while creating a new user
# If no users were created, need to create a role explicitly
if [ -z "$MEMBER_ROLE" ]; then
    MEMBER_ROLE=$(openstack role create _member_ | awk '$2=="id" {print $4}')
    echo "Created role _member_ with id ${MEMBER_ROLE}" >&2
fi
ADMIN_USER_ID=$(openstack user show admin | awk '$2=="id" {print $4}')
if [ -z "$ADMIN_USER_ID" ]; then
    echo "Could not find admin user" >&2
    exit 1
fi

if ! openstack project show $NAME 1>/dev/null 2>&1 ; then
    USER_TENANT_ID=$(openstack project create $NAME | awk '$2=="id" {print $4}')
    if [ -z "$USER_TENANT_ID" ]; then
        echo "Failed to create tenant $NAME" >&2
        exit 1
    fi
else
    USER_TENANT_ID=$(openstack project show $NAME 2>/dev/null| awk '$2=="id" {print $4}')
    if [ -z "$USER_TENANT_ID" ]; then
        echo "Failed to retrieve existing tenant $NAME" >&2
        exit 1
    fi
fi

USER_ID=$(openstack user show $NAME | awk '$2=="id" {print $4}')
if [ -z "$USER_ID" ]; then
    USER_ID=$(openstack user create \
            --password "$PASSWORD" \
            --email $EMAIL $NAME | awk '$2=="id" {print $4}')
    if [ -z "$USER_ID" ]; then
        echo "Failed to create user $NAME" >&2
        exit 1
    else
        echo "Created user $NAME with password '$PASSWORD'"
    fi
else
    echo "User $NAME with id $USER_ID already exists"
fi

if openstack role list --user $USER_ID --project $USER_TENANT_ID | grep -q "\s$MEMBER_ROLE\s"; then
    echo "Role $MEMBER_ROLE is already granted for user $USER_ID with tenant $USER_TENANT_ID"
else
    openstack role add --user $USER_ID --project $USER_TENANT_ID $MEMBER_ROLE
fi

if openstack role list --user $ADMIN_USER_ID --project $USER_TENANT_ID | grep -q "\s$ADMIN_ROLE\s"; then
    echo "Role $ADMIN_ROLE is already granted for user $ADMIN_USER_ID with tenant $USER_TENANT_ID"
else
    openstack role add --user $ADMIN_USER_ID --project $USER_TENANT_ID $ADMIN_ROLE
fi
