Adds support for multi-region

Change-Id: Ib85fe7cb375692b04aca4c46f61ba7e1fbfa501b
Implements: blueprint multi-region
diff --git a/lib/heat b/lib/heat
index b8c0359..afed52b 100644
--- a/lib/heat
+++ b/lib/heat
@@ -98,6 +98,8 @@
     iniset $HEAT_CONF database connection `database_connection_url heat`
     iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/urandom`
 
+    iniset $HEAT_CONF DEFAULT region_name_for_services "$REGION_NAME"
+
     # logging
     iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
@@ -214,57 +216,44 @@
     SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
 
-    HEAT_USER=$(openstack user create \
-        heat \
-        --password "$SERVICE_PASSWORD" \
-        --project $SERVICE_TENANT \
-        --email heat@example.com \
-        | grep " id " | get_field 2)
-    openstack role add \
-        $ADMIN_ROLE \
-        --project $SERVICE_TENANT \
-        --user $HEAT_USER
+    HEAT_USER=$(get_or_create_user "heat" \
+        "$SERVICE_PASSWORD" $SERVICE_TENANT "heat@example.com")
+    get_or_add_user_role $ADMIN_ROLE $HEAT_USER $SERVICE_TENANT
+
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
-        HEAT_SERVICE=$(openstack service create \
-            heat \
-            --type=orchestration \
-            --description="Heat Orchestration Service" \
-            | grep " id " | get_field 2)
-        openstack endpoint create \
-                $HEAT_SERVICE \
-                --region RegionOne \
-                --publicurl "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
-                --adminurl "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
-                --internalurl "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"
-        HEAT_CFN_SERVICE=$(openstack service create \
-            heat \
-            --type=cloudformation \
-            --description="Heat CloudFormation Service" \
-            | grep " id " | get_field 2)
-        openstack endpoint create \
-                $HEAT_CFN_SERVICE \
-                --region RegionOne \
-                --publicurl "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
-                --adminurl "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
-                --internalurl "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
+
+        HEAT_SERVICE=$(get_or_create_service "heat" \
+                "orchestration" "Heat Orchestration Service")
+        get_or_create_endpoint $HEAT_SERVICE \
+            "$REGION_NAME" \
+            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
+            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
+            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"
+
+        HEAT_CFN_SERVICE=$(get_or_create_service "heat-cfn" \
+                "cloudformation" "Heat CloudFormation Service")
+        get_or_create_endpoint $HEAT_CFN_SERVICE \
+            "$REGION_NAME" \
+            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
+            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
+            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
     fi
 
     # heat_stack_user role is for users created by Heat
-    openstack role create heat_stack_user
+    get_or_create_role "heat_stack_user"
 
     if [[ $HEAT_DEFERRED_AUTH == trusts ]]; then
+
         # heat_stack_owner role is given to users who create Heat stacks,
         # it's the default role used by heat to delegate to the heat service
         # user (for performing deferred operations via trusts), see heat.conf
-        HEAT_OWNER_ROLE=$(openstack role create \
-            heat_stack_owner \
-            | grep " id " | get_field 2)
+        HEAT_OWNER_ROLE=$(get_or_create_role "heat_stack_owner")
 
         # Give the role to the demo and admin users so they can create stacks
         # in either of the projects created by devstack
-        openstack role add $HEAT_OWNER_ROLE --project demo --user demo
-        openstack role add $HEAT_OWNER_ROLE --project demo --user admin
-        openstack role add $HEAT_OWNER_ROLE --project admin --user admin
+        get_or_add_user_role $HEAT_OWNER_ROLE demo demo
+        get_or_add_user_role $HEAT_OWNER_ROLE admin demo
+        get_or_add_user_role $HEAT_OWNER_ROLE admin admin
         iniset $HEAT_CONF DEFAULT deferred_auth_method trusts
     fi
 
@@ -272,21 +261,27 @@
         # Note we have to pass token/endpoint here because the current endpoint and
         # version negotiation in OSC means just --os-identity-api-version=3 won't work
         KS_ENDPOINT_V3="$KEYSTONE_SERVICE_URI/v3"
-        D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
-            --os-identity-api-version=3 domain create heat \
-            --description "Owns users and projects created by heat" \
-            | grep ' id ' | get_field 2)
-        iniset $HEAT_CONF DEFAULT stack_user_domain ${D_ID}
 
-        openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
-            --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
-            --domain $D_ID heat_domain_admin \
-            --description "Manages users and projects created by heat"
-        openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
-            --os-identity-api-version=3 role add \
-            --user heat_domain_admin --domain ${D_ID} admin
-        iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
-        iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
+        D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+            --os-identity-api-version=3 domain list | grep ' heat ' | get_field 1)
+
+        if [[ -z "$D_ID" ]]; then
+            D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+                --os-identity-api-version=3 domain create heat \
+                --description "Owns users and projects created by heat" \
+                | grep ' id ' | get_field 2)
+            iniset $HEAT_CONF DEFAULT stack_user_domain ${D_ID}
+
+            openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+                --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
+                --domain $D_ID heat_domain_admin \
+                --description "Manages users and projects created by heat"
+            openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+                --os-identity-api-version=3 role add \
+                --user heat_domain_admin --domain ${D_ID} admin
+            iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
+            iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
+        fi
     fi
 }