bootstrap keystone using new bootstrap command

Be gone ADMIN_TOKEN, long live keystone-manage bootstrap.

This patch reworks the initial setup for keystone by using
the new bootstrap command. After a minimal service catalog
has been created, using this process, we simply authenticate
as usual.

implements bp: bootstrap
Depends-On: I113c6934b6b83ceff23a94101967a6df1126873f
Change-Id: Ia1475d461eab60b68c6a0356714b21c7f92e0194
diff --git a/lib/keystone b/lib/keystone
index 057bb47..6f13ec6 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -12,7 +12,6 @@
 # - ``IDENTITY_API_VERSION``
 # - ``BASE_SQL_CONN``
 # - ``SERVICE_HOST``, ``SERVICE_PROTOCOL``
-# - ``SERVICE_TOKEN``
 # - ``S3_SERVICE_PORT`` (template backend only)
 
 # ``stack.sh`` calls the entry points in this order:
@@ -22,6 +21,7 @@
 # - _config_keystone_apache_wsgi
 # - init_keystone
 # - start_keystone
+# - bootstrap_keystone
 # - create_keystone_accounts
 # - stop_keystone
 # - cleanup_keystone
@@ -230,8 +230,6 @@
         iniset $KEYSTONE_CONF DEFAULT admin_endpoint $KEYSTONE_AUTH_URI
     fi
 
-    iniset $KEYSTONE_CONF DEFAULT admin_token "$SERVICE_TOKEN"
-
     if [[ "$KEYSTONE_TOKEN_FORMAT" != "" ]]; then
         iniset $KEYSTONE_CONF token provider $KEYSTONE_TOKEN_FORMAT
     fi
@@ -324,14 +322,16 @@
 # Migrated from keystone_data.sh
 function create_keystone_accounts {
 
-    # admin
+    # The keystone bootstrapping process (performed via keystone-manage bootstrap)
+    # creates an admin user, admin role and admin project. As a sanity check
+    # we exercise the CLI to retrieve the IDs for these values.
     local admin_tenant
-    admin_tenant=$(get_or_create_project "admin" default)
+    admin_tenant=$(openstack project show "admin" -f value -c id)
     local admin_user
-    admin_user=$(get_or_create_user "admin" "$ADMIN_PASSWORD" default)
+    admin_user=$(openstack user show "admin" -f value -c id)
     local admin_role
-    admin_role=$(get_or_create_role "admin")
-    get_or_add_user_project_role $admin_role $admin_user $admin_tenant
+    admin_role=$(openstack role show "admin" -f value -c id)
+
     get_or_add_user_domain_role $admin_role $admin_user default
 
     # Create service project/role
@@ -381,17 +381,6 @@
     get_or_add_group_project_role $member_role $non_admin_group $demo_tenant
     get_or_add_group_project_role $another_role $non_admin_group $demo_tenant
     get_or_add_group_project_role $admin_role $admin_group $admin_tenant
-
-    # Keystone
-    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
-
-        get_or_create_service "keystone" "identity" "Keystone Identity Service"
-        get_or_create_endpoint "identity" \
-            "$REGION_NAME" \
-            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
-            "$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v$IDENTITY_API_VERSION" \
-            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"
-    fi
 }
 
 # Create a user that is capable of verifying keystone tokens for use with auth_token middleware.
@@ -565,6 +554,55 @@
     stop_process key
 }
 
+# bootstrap_keystone() - Initialize user, role and project
+# This function uses the following GLOBAL variables:
+# - ``KEYSTONE_BIN_DIR``
+# - ``ADMIN_PASSWORD``
+# - ``IDENTITY_API_VERSION``
+# - ``KEYSTONE_CATALOG_BACKEND``
+# - ``KEYSTONE_AUTH_URI``
+# - ``REGION_NAME``
+# - ``KEYSTONE_SERVICE_PROTOCOL``
+# - ``KEYSTONE_SERVICE_HOST``
+# - ``KEYSTONE_SERVICE_PORT``
+function bootstrap_keystone {
+
+    # Initialize keystone, this will create an 'admin' user, 'admin' project,
+    # 'admin' role, and assign the user the role on the project. These resources
+    # are created only if they do not already exist.
+    $KEYSTONE_BIN_DIR/keystone-manage bootstrap --bootstrap-password $ADMIN_PASSWORD
+
+    # Create the keystone service and endpoints. To do this with the new
+    # bootstrapping process, we need to get a token and use that token to
+    # interact with the new APIs. The token will only be used to create services
+    # and endpoints, thus creating a minimal service catalog.
+    # They are unset immediately after.
+    # TODO(stevemar): OpenStackClient and KeystoneClient do not have support to
+    # handle interactions that not return service catalogs. Eventually remove
+    # this section when the support is in place. Use token based auth for now.
+    local token_id
+    token_id=$(openstack token issue -c id -f value \
+        --os-username admin --os-project-name admin \
+        --os-user-domain-id default --os-project-domain-id default \
+        --os-identity-api-version 3 --os-auth-url $KEYSTONE_AUTH_URI \
+        --os-password $ADMIN_PASSWORD)
+
+    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
+
+        export OS_TOKEN=$token_id
+        export OS_URL=$KEYSTONE_AUTH_URI/v3
+        export OS_IDENTITY_API_VERSION=3
+
+        get_or_create_service "keystone" "identity" "Keystone Identity Service"
+        get_or_create_endpoint "identity" \
+            "$REGION_NAME" \
+            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
+            "$KEYSTONE_AUTH_URI/v$IDENTITY_API_VERSION" \
+            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"
+    fi
+
+    unset OS_TOKEN OS_URL OS_IDENTITY_API_VERSION
+}
 
 # Restore xtrace
 $_XTRACE_KEYSTONE