#!/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)

DESCRIPTION=""
ADMIN_URL=""
INTERNAL_URL=""
REGION="regionOne" # NB: This is the default keystone uses.
DEBUG=""

function show_options {
    echo "Usage: $SCRIPT_NAME [options] <name> <type> <public_url>"
    echo
    echo "Register a service and create an endpoint for it."
    echo "The script assumes that the service tenant is called 'service' and "
    echo "the admin role is called 'admin'."
    echo
    echo "Supported types are ec2, image, orchestration, identity,"
    echo "network, compute, baremetal, dashboard and metering."
    echo
    echo "Options:"
    echo "    -d, --description -- the description for the service."
    echo "    -a, --admin       -- the admin URL prefix for this endpoint. If"
    echo "                         not supplied, defaults to the internal url."
    echo "    -i, --internal    -- the internal URL prefix for this endpoint."
    echo "                         If not supplied, defaults to the public url."
    echo "    -r, --region      -- Override the default region 'regionOne'."
    echo "    --debug           -- Debug API calls made."
    echo
    echo "For instance: $SCRIPT_NAME nova compute https://api.cloud.com/nova/"
    echo "would create a nova service and register"
    echo "https://api.cloud.com/nova/v2/\$(tenant_id)s for all three endpoints."
    exit 0
}

TEMP=`getopt -o d:a:i:r: -l debug,description:,admin:,internal:,region: -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
        -d | --description) export DESCRIPTION="$2"; shift 2 ;;
        --debug) export DEBUG="--debug"; shift 1 ;;
        -a | --admin) export ADMIN_URL="$2"; shift 2 ;;
        -i | --internal) export INTERNAL_URL="$2"; shift 2 ;;
        -r | --region) export REGION="$2"; shift 2 ;;
        -h) show_options;;
        --) shift ; break ;;
        *) echo "Error: unsupported option $1." ; exit 1 ;;
    esac
done

NAME=${1:-""}
TYPE=${2:-""}
PUBLIC_URL=${3:-""}
EXTRA=${4:-""}

if [ -z "NAME" -o -z "$TYPE" -o -z "$PUBLIC_URL" -o -n "$EXTRA" ]; then
    show_options
fi

ADMIN_SUFFIX=
case "$TYPE" in
    ec2)
        SUFFIX="/services/Cloud"
        ADMIN_SUFFIX="/services/Admin"
        ;;
    image|baremetal|network|metering)
        SUFFIX="/"
        ;;
    orchestration|volume)
        SUFFIX="/v1/%(tenant_id)s"
        ;;
    volumev2)
        SUFFIX="/v2/%(tenant_id)s"
        ;;
    identity)
        SUFFIX="/v2.0"
        ;;
    compute)
        SUFFIX="/v2/\$(tenant_id)s"
        ;;
    computev3)
        SUFFIX="/v3"
        ;;
    object-store)
        SUFFIX="/v1/AUTH_%(tenant_id)s"
        ADMIN_SUFFIX="/v1"
        ;;
    dashboard)
        SUFFIX="/"
        ADMIN_SUFFIX="/admin"
        ;;
    management)
        SUFFIX="/v2"
        ;;
    *)
        echo "Unknown service type" >&2
        exit 1
esac

if [ -z "$ADMIN_SUFFIX" ]; then
    ADMIN_SUFFIX="$SUFFIX"
fi

if [ -n "$DESCRIPTION" ]; then
    DESCRIPTION="--description=$DESCRIPTION"
fi

if [ -z "$INTERNAL_URL" ]; then
    INTERNAL_URL="$PUBLIC_URL"
fi

if [ -z "$ADMIN_URL" ]; then
    ADMIN_URL="$INTERNAL_URL"
fi

ADMIN_ROLE=$(openstack $DEBUG role list | awk '/ admin / {print $2}')
if [ -z "$ADMIN_ROLE" ]; then
    echo "Could not find admin role" >&2
    exit 1
fi

# Some services don't need a user
if [ "dashboard" != "$TYPE" ]; then
    SERVICE_TENANT=$(openstack $DEBUG project list | awk '/ service / {print $2}')
    PASSWORD=${PASSWORD:-$(os-make-password)}

    # Some services have multiple endpoints, the user doesn't need to be recreated
    USER_ID=$(openstack $DEBUG user show $NAME | awk '$2=="id" { print $4 }')
    if [ -z "$USER_ID" ]; then
        USER_ID=$(openstack $DEBUG user create --password $PASSWORD --project $SERVICE_TENANT --email=nobody@example.com $NAME | awk ' / id / {print $4}')
    fi
    if ! openstack role list --project $SERVICE_TENANT --user $USER_ID | grep -q " $ADMIN_ROLE "; then
        echo "Creating user-role assignment for user $NAME, role admin, tenant service"
        openstack role add $DEBUG \
            --project  $SERVICE_TENANT \
            --user $USER_ID \
            $ADMIN_ROLE
    fi
    #Add the admin tenant role for ceilometer user to enable polling services
    if  [ "metering" == "$TYPE" ]; then
        ADMIN_TENANT=$(openstack $DEBUG project list | awk '/ admin / {print $2}')
        if ! openstack role list --project $ADMIN_TENANT --user $USER_ID | grep -q " $ADMIN_ROLE "; then
            echo "Creating user-role assignment for user $NAME, role admin, tenant admin"
            openstack role add $DEBUG \
                --project $ADMIN_TENANT \
                --user $USER_ID \
                $ADMIN_ROLE
            #swift polling requires ResellerAdmin role to be added to the Ceilometer user
            RESELLER_ADMIN_ROLE=$(openstack $DEBUG role list | awk '/ ResellerAdmin / {print $2}')
            openstack role add $DEBUG \
                --project $ADMIN_TENANT \
                --user $USER_ID \
                $RESELLER_ADMIN_ROLE
        fi
    fi

fi
SERVICE_ID=$(openstack $DEBUG service create --name $NAME "$DESCRIPTION" $TYPE | awk '/ id / {print $4}')
openstack endpoint create $DEBUG \
    --publicurl   "${PUBLIC_URL}${SUFFIX}" \
    --adminurl    "${ADMIN_URL}${ADMIN_SUFFIX}" \
    --internalurl "${INTERNAL_URL}${SUFFIX}"  --region "$REGION" $SERVICE_ID
echo "Service $TYPE created"
