Browse code

Adds support for multi-region

Change-Id: Ib85fe7cb375692b04aca4c46f61ba7e1fbfa501b
Implements: blueprint multi-region

Bartosz Górski authored on 2014/02/28 22:15:19
Showing 18 changed files
... ...
@@ -330,6 +330,25 @@ which includes the following, with the IP address of the above controller node:
330 330
     Q_HOST=$SERVICE_HOST
331 331
     MATCHMAKER_REDIS_HOST=$SERVICE_HOST
332 332
 
333
+# Multi-Region Setup
334
+
335
+We want to setup two devstack (RegionOne and RegionTwo) with shared keystone
336
+(same users and services) and horizon.
337
+Keystone and Horizon will be located in RegionOne.
338
+Full spec is available at:
339
+https://wiki.openstack.org/wiki/Heat/Blueprints/Multi_Region_Support_for_Heat.
340
+
341
+In RegionOne:
342
+
343
+    REGION_NAME=RegionOne
344
+
345
+In RegionTwo:
346
+
347
+    disable_service horizon
348
+    KEYSTONE_SERVICE_HOST=<KEYSTONE_IP_ADDRESS_FROM_REGION_ONE>
349
+    KEYSTONE_AUTH_HOST=<KEYSTONE_IP_ADDRESS_FROM_REGION_ONE>
350
+    REGION_NAME=RegionTwo
351
+
333 352
 # Cells
334 353
 
335 354
 Cells is a new scaling option with a full spec at:
... ...
@@ -719,6 +719,109 @@ function policy_add {
719 719
     mv ${tmpfile} ${policy_file}
720 720
 }
721 721
 
722
+# Gets or creates user
723
+# Usage: get_or_create_user <username> <password> <project> <email>
724
+function get_or_create_user {
725
+    # Gets user id
726
+    USER_ID=$(
727
+        # Gets user id
728
+        openstack user show $1 -f value -c id 2>/dev/null ||
729
+        # Creates new user
730
+        openstack user create \
731
+            $1 \
732
+            --password "$2" \
733
+            --project $3 \
734
+            --email $4 \
735
+            -f value -c id
736
+    )
737
+    echo $USER_ID
738
+}
739
+
740
+# Gets or creates project
741
+# Usage: get_or_create_project <name>
742
+function get_or_create_project {
743
+    # Gets project id
744
+    PROJECT_ID=$(
745
+        # Gets project id
746
+        openstack project show $1 -f value -c id 2>/dev/null ||
747
+        # Creates new project if not exists
748
+        openstack project create $1 -f value -c id
749
+    )
750
+    echo $PROJECT_ID
751
+}
752
+
753
+# Gets or creates role
754
+# Usage: get_or_create_role <name>
755
+function get_or_create_role {
756
+    ROLE_ID=$(
757
+        # Gets role id
758
+        openstack role show $1 -f value -c id 2>/dev/null ||
759
+        # Creates role if not exists
760
+        openstack role create $1 -f value -c id
761
+    )
762
+    echo $ROLE_ID
763
+}
764
+
765
+# Gets or adds user role
766
+# Usage: get_or_add_user_role <role> <user> <project>
767
+function get_or_add_user_role {
768
+    # Gets user role id
769
+    USER_ROLE_ID=$(openstack user role list \
770
+        $2 \
771
+        --project $3 \
772
+        --column "ID" \
773
+        --column "Name" \
774
+        | grep " $1 " | get_field 1)
775
+    if [[ -z "$USER_ROLE_ID" ]]; then
776
+        # Adds role to user
777
+        USER_ROLE_ID=$(openstack role add \
778
+            $1 \
779
+            --user $2 \
780
+            --project $3 \
781
+            | grep " id " | get_field 2)
782
+    fi
783
+    echo $USER_ROLE_ID
784
+}
785
+
786
+# Gets or creates service
787
+# Usage: get_or_create_service <name> <type> <description>
788
+function get_or_create_service {
789
+    # Gets service id
790
+    SERVICE_ID=$(
791
+        # Gets service id
792
+        openstack service show $1 -f value -c id 2>/dev/null ||
793
+        # Creates new service if not exists
794
+        openstack service create \
795
+            $1 \
796
+            --type=$2 \
797
+            --description="$3" \
798
+            -f value -c id
799
+    )
800
+    echo $SERVICE_ID
801
+}
802
+
803
+# Gets or creates endpoint
804
+# Usage: get_or_create_endpoint <service> <region> <publicurl> <adminurl> <internalurl>
805
+function get_or_create_endpoint {
806
+    # Gets endpoint id
807
+    ENDPOINT_ID=$(openstack endpoint list \
808
+        --column "ID" \
809
+        --column "Region" \
810
+        --column "Service Name" \
811
+        | grep " $2 " \
812
+        | grep " $1 " | get_field 1)
813
+    if [[ -z "$ENDPOINT_ID" ]]; then
814
+        # Creates new endpoint
815
+        ENDPOINT_ID=$(openstack endpoint create \
816
+            $1 \
817
+            --region $2 \
818
+            --publicurl $3 \
819
+            --adminurl $4 \
820
+            --internalurl $5 \
821
+            | grep " id " | get_field 2)
822
+    fi
823
+    echo $ENDPOINT_ID
824
+}
722 825
 
723 826
 # Package Functions
724 827
 # =================
... ...
@@ -81,35 +81,22 @@ create_ceilometer_accounts() {
81 81
 
82 82
     # Ceilometer
83 83
     if [[ "$ENABLED_SERVICES" =~ "ceilometer-api" ]]; then
84
-        CEILOMETER_USER=$(openstack user create \
85
-            ceilometer \
86
-            --password "$SERVICE_PASSWORD" \
87
-            --project $SERVICE_TENANT \
88
-            --email ceilometer@example.com \
89
-            | grep " id " | get_field 2)
90
-        openstack role add \
91
-            $ADMIN_ROLE \
92
-            --project $SERVICE_TENANT \
93
-            --user $CEILOMETER_USER
84
+        CEILOMETER_USER=$(get_or_create_user "ceilometer" \
85
+            "$SERVICE_PASSWORD" $SERVICE_TENANT "ceilometer@example.com")
86
+        get_or_add_user_role $ADMIN_ROLE $CEILOMETER_USER $SERVICE_TENANT
87
+
94 88
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
95
-            CEILOMETER_SERVICE=$(openstack service create \
96
-                ceilometer \
97
-                --type=metering \
98
-                --description="OpenStack Telemetry Service" \
99
-                | grep " id " | get_field 2)
100
-            openstack endpoint create \
101
-                $CEILOMETER_SERVICE \
102
-                --region RegionOne \
103
-                --publicurl "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/" \
104
-                --adminurl "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/" \
105
-                --internalurl "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/"
89
+            CEILOMETER_SERVICE=$(get_or_create_service "ceilometer" \
90
+                "metering" "OpenStack Telemetry Service")
91
+            get_or_create_endpoint $CEILOMETER_SERVICE \
92
+                "$REGION_NAME" \
93
+                "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/" \
94
+                "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/" \
95
+                "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/"
106 96
         fi
107 97
         if is_service_enabled swift; then
108 98
             # Ceilometer needs ResellerAdmin role to access swift account stats.
109
-            openstack role add \
110
-                --project $SERVICE_TENANT_NAME \
111
-                --user ceilometer \
112
-                ResellerAdmin
99
+            get_or_add_user_role "ResellerAdmin" "ceilometer" $SERVICE_TENANT_NAME
113 100
         fi
114 101
     fi
115 102
 }
... ...
@@ -339,39 +339,26 @@ function create_cinder_accounts {
339 339
 
340 340
     # Cinder
341 341
     if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then
342
-        CINDER_USER=$(openstack user create \
343
-            cinder \
344
-            --password "$SERVICE_PASSWORD" \
345
-            --project $SERVICE_TENANT \
346
-            --email cinder@example.com \
347
-            | grep " id " | get_field 2)
348
-        openstack role add \
349
-            $ADMIN_ROLE \
350
-            --project $SERVICE_TENANT \
351
-            --user $CINDER_USER
342
+
343
+        CINDER_USER=$(get_or_create_user "cinder" \
344
+            "$SERVICE_PASSWORD" $SERVICE_TENANT "cinder@example.com")
345
+        get_or_add_user_role $ADMIN_ROLE $CINDER_USER $SERVICE_TENANT
346
+
352 347
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
353
-            CINDER_SERVICE=$(openstack service create \
354
-                cinder \
355
-                --type=volume \
356
-                --description="Cinder Volume Service" \
357
-                | grep " id " | get_field 2)
358
-            openstack endpoint create \
359
-                $CINDER_SERVICE \
360
-                --region RegionOne \
361
-                --publicurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s" \
362
-                --adminurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s" \
363
-                --internalurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s"
364
-            CINDER_V2_SERVICE=$(openstack service create \
365
-                cinderv2 \
366
-                --type=volumev2 \
367
-                --description="Cinder Volume Service V2" \
368
-                | grep " id " | get_field 2)
369
-            openstack endpoint create \
370
-                $CINDER_V2_SERVICE \
371
-                --region RegionOne \
372
-                --publicurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(tenant_id)s" \
373
-                --adminurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(tenant_id)s" \
374
-                --internalurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(tenant_id)s"
348
+
349
+            CINDER_SERVICE=$(get_or_create_service "cinder" \
350
+                "volume" "Cinder Volume Service")
351
+            get_or_create_endpoint $CINDER_SERVICE "$REGION_NAME" \
352
+                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s" \
353
+                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s" \
354
+                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s"
355
+
356
+            CINDER_V2_SERVICE=$(get_or_create_service "cinderv2" \
357
+                "volumev2" "Cinder Volume Service V2")
358
+            get_or_create_endpoint $CINDER_V2_SERVICE "$REGION_NAME" \
359
+                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(tenant_id)s" \
360
+                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(tenant_id)s" \
361
+                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(tenant_id)s"
375 362
         fi
376 363
     fi
377 364
 }
... ...
@@ -164,36 +164,28 @@ function configure_glance {
164 164
 
165 165
 function create_glance_accounts {
166 166
     if is_service_enabled g-api; then
167
-        openstack user create \
168
-            --password "$SERVICE_PASSWORD" \
169
-            --project $SERVICE_TENANT_NAME \
170
-            glance
171
-        openstack role add \
172
-            --project $SERVICE_TENANT_NAME \
173
-            --user glance \
174
-            service
167
+
168
+        GLANCE_USER=$(get_or_create_user "glance" \
169
+            "$SERVICE_PASSWORD" $SERVICE_TENANT_NAME "glance@example.com")
170
+        get_or_add_user_role service $GLANCE_USER $SERVICE_TENANT_NAME
171
+
175 172
         # required for swift access
176 173
         if is_service_enabled s-proxy; then
177
-            openstack user create \
178
-                --password "$SERVICE_PASSWORD" \
179
-                --project $SERVICE_TENANT_NAME \
180
-                glance-swift
181
-            openstack role add \
182
-                --project $SERVICE_TENANT_NAME \
183
-                --user glance-swift \
184
-                ResellerAdmin
174
+
175
+            GLANCE_SWIFT_USER=$(get_or_create_user "glance-swift" \
176
+                "$SERVICE_PASSWORD" $SERVICE_TENANT_NAME "glance-swift@example.com")
177
+            get_or_add_user_role "ResellerAdmin" $GLANCE_SWIFT_USER $SERVICE_TENANT_NAME
185 178
         fi
179
+
186 180
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
187
-            openstack service create \
188
-                --type image \
189
-                --description "Glance Image Service" \
190
-                glance
191
-            openstack endpoint create \
192
-                --region RegionOne \
193
-                --publicurl "http://$GLANCE_HOSTPORT" \
194
-                --adminurl "http://$GLANCE_HOSTPORT" \
195
-                --internalurl "http://$GLANCE_HOSTPORT" \
196
-                glance
181
+
182
+            GLANCE_SERVICE=$(get_or_create_service "glance" \
183
+                "image" "Glance Image Service")
184
+            get_or_create_endpoint $GLANCE_SERVICE \
185
+                "$REGION_NAME" \
186
+                "http://$GLANCE_HOSTPORT" \
187
+                "http://$GLANCE_HOSTPORT" \
188
+                "http://$GLANCE_HOSTPORT"
197 189
         fi
198 190
     fi
199 191
 }
... ...
@@ -98,6 +98,8 @@ function configure_heat {
98 98
     iniset $HEAT_CONF database connection `database_connection_url heat`
99 99
     iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/urandom`
100 100
 
101
+    iniset $HEAT_CONF DEFAULT region_name_for_services "$REGION_NAME"
102
+
101 103
     # logging
102 104
     iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
103 105
     iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
... ...
@@ -214,57 +216,44 @@ function create_heat_accounts {
214 214
     SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
215 215
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
216 216
 
217
-    HEAT_USER=$(openstack user create \
218
-        heat \
219
-        --password "$SERVICE_PASSWORD" \
220
-        --project $SERVICE_TENANT \
221
-        --email heat@example.com \
222
-        | grep " id " | get_field 2)
223
-    openstack role add \
224
-        $ADMIN_ROLE \
225
-        --project $SERVICE_TENANT \
226
-        --user $HEAT_USER
217
+    HEAT_USER=$(get_or_create_user "heat" \
218
+        "$SERVICE_PASSWORD" $SERVICE_TENANT "heat@example.com")
219
+    get_or_add_user_role $ADMIN_ROLE $HEAT_USER $SERVICE_TENANT
220
+
227 221
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
228
-        HEAT_SERVICE=$(openstack service create \
229
-            heat \
230
-            --type=orchestration \
231
-            --description="Heat Orchestration Service" \
232
-            | grep " id " | get_field 2)
233
-        openstack endpoint create \
234
-                $HEAT_SERVICE \
235
-                --region RegionOne \
236
-                --publicurl "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
237
-                --adminurl "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
238
-                --internalurl "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"
239
-        HEAT_CFN_SERVICE=$(openstack service create \
240
-            heat \
241
-            --type=cloudformation \
242
-            --description="Heat CloudFormation Service" \
243
-            | grep " id " | get_field 2)
244
-        openstack endpoint create \
245
-                $HEAT_CFN_SERVICE \
246
-                --region RegionOne \
247
-                --publicurl "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
248
-                --adminurl "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
249
-                --internalurl "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
222
+
223
+        HEAT_SERVICE=$(get_or_create_service "heat" \
224
+                "orchestration" "Heat Orchestration Service")
225
+        get_or_create_endpoint $HEAT_SERVICE \
226
+            "$REGION_NAME" \
227
+            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
228
+            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
229
+            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"
230
+
231
+        HEAT_CFN_SERVICE=$(get_or_create_service "heat-cfn" \
232
+                "cloudformation" "Heat CloudFormation Service")
233
+        get_or_create_endpoint $HEAT_CFN_SERVICE \
234
+            "$REGION_NAME" \
235
+            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
236
+            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
237
+            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
250 238
     fi
251 239
 
252 240
     # heat_stack_user role is for users created by Heat
253
-    openstack role create heat_stack_user
241
+    get_or_create_role "heat_stack_user"
254 242
 
255 243
     if [[ $HEAT_DEFERRED_AUTH == trusts ]]; then
244
+
256 245
         # heat_stack_owner role is given to users who create Heat stacks,
257 246
         # it's the default role used by heat to delegate to the heat service
258 247
         # user (for performing deferred operations via trusts), see heat.conf
259
-        HEAT_OWNER_ROLE=$(openstack role create \
260
-            heat_stack_owner \
261
-            | grep " id " | get_field 2)
248
+        HEAT_OWNER_ROLE=$(get_or_create_role "heat_stack_owner")
262 249
 
263 250
         # Give the role to the demo and admin users so they can create stacks
264 251
         # in either of the projects created by devstack
265
-        openstack role add $HEAT_OWNER_ROLE --project demo --user demo
266
-        openstack role add $HEAT_OWNER_ROLE --project demo --user admin
267
-        openstack role add $HEAT_OWNER_ROLE --project admin --user admin
252
+        get_or_add_user_role $HEAT_OWNER_ROLE demo demo
253
+        get_or_add_user_role $HEAT_OWNER_ROLE admin demo
254
+        get_or_add_user_role $HEAT_OWNER_ROLE admin admin
268 255
         iniset $HEAT_CONF DEFAULT deferred_auth_method trusts
269 256
     fi
270 257
 
... ...
@@ -272,21 +261,27 @@ function create_heat_accounts {
272 272
         # Note we have to pass token/endpoint here because the current endpoint and
273 273
         # version negotiation in OSC means just --os-identity-api-version=3 won't work
274 274
         KS_ENDPOINT_V3="$KEYSTONE_SERVICE_URI/v3"
275
+
275 276
         D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
276
-            --os-identity-api-version=3 domain create heat \
277
-            --description "Owns users and projects created by heat" \
278
-            | grep ' id ' | get_field 2)
279
-        iniset $HEAT_CONF DEFAULT stack_user_domain ${D_ID}
280
-
281
-        openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
282
-            --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
283
-            --domain $D_ID heat_domain_admin \
284
-            --description "Manages users and projects created by heat"
285
-        openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
286
-            --os-identity-api-version=3 role add \
287
-            --user heat_domain_admin --domain ${D_ID} admin
288
-        iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
289
-        iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
277
+            --os-identity-api-version=3 domain list | grep ' heat ' | get_field 1)
278
+
279
+        if [[ -z "$D_ID" ]]; then
280
+            D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
281
+                --os-identity-api-version=3 domain create heat \
282
+                --description "Owns users and projects created by heat" \
283
+                | grep ' id ' | get_field 2)
284
+            iniset $HEAT_CONF DEFAULT stack_user_domain ${D_ID}
285
+
286
+            openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
287
+                --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
288
+                --domain $D_ID heat_domain_admin \
289
+                --description "Manages users and projects created by heat"
290
+            openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
291
+                --os-identity-api-version=3 role add \
292
+                --user heat_domain_admin --domain ${D_ID} admin
293
+            iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
294
+            iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
295
+        fi
290 296
     fi
291 297
 }
292 298
 
... ...
@@ -223,28 +223,21 @@ function create_ironic_accounts {
223 223
 
224 224
     # Ironic
225 225
     if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
226
-        IRONIC_USER=$(openstack user create \
227
-            ironic \
228
-            --password "$SERVICE_PASSWORD" \
229
-            --project $SERVICE_TENANT \
230
-            --email ironic@example.com \
231
-            | grep " id " | get_field 2)
232
-        openstack role add \
233
-            $ADMIN_ROLE \
234
-            --project $SERVICE_TENANT \
235
-            --user $IRONIC_USER
226
+        # Get ironic user if exists
227
+
228
+        IRONIC_USER=$(get_or_create_user "ironic" \
229
+            "$SERVICE_PASSWORD" $SERVICE_TENANT "ironic@example.com")
230
+        get_or_add_user_role $ADMIN_ROLE $IRONIC_USER $SERVICE_TENANT
231
+
236 232
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
237
-            IRONIC_SERVICE=$(openstack service create \
238
-                ironic \
239
-                --type=baremetal \
240
-                --description="Ironic baremetal provisioning service" \
241
-                | grep " id " | get_field 2)
242
-            openstack endpoint create \
243
-                $IRONIC_SERVICE \
244
-                --region RegionOne \
245
-                --publicurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
246
-                --adminurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
247
-                --internalurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT"
233
+
234
+            IRONIC_SERVICE=$(get_or_create_service "ironic" \
235
+                "baremetal" "Ironic baremetal provisioning service")
236
+            get_or_create_endpoint $IRONIC_SERVICE \
237
+                "$REGION_NAME" \
238
+                "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
239
+                "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
240
+                "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT"
248 241
         fi
249 242
     fi
250 243
 }
... ...
@@ -277,6 +277,8 @@ function configure_keystone {
277 277
         iniset $KEYSTONE_CONF DEFAULT logging_exception_prefix "%(process)d TRACE %(name)s %(instance)s"
278 278
         _config_keystone_apache_wsgi
279 279
     fi
280
+
281
+    iniset $KEYSTONE_CONF DEFAULT max_token_size 16384
280 282
 }
281 283
 
282 284
 function configure_keystone_extensions {
... ...
@@ -315,79 +317,55 @@ function configure_keystone_extensions {
315 315
 function create_keystone_accounts {
316 316
 
317 317
     # admin
318
-    ADMIN_TENANT=$(openstack project create \
319
-        admin \
320
-        | grep " id " | get_field 2)
321
-    ADMIN_USER=$(openstack user create \
322
-        admin \
323
-        --project "$ADMIN_TENANT" \
324
-        --email admin@example.com \
325
-        --password "$ADMIN_PASSWORD" \
326
-        | grep " id " | get_field 2)
327
-    ADMIN_ROLE=$(openstack role create \
328
-        admin \
329
-        | grep " id " | get_field 2)
330
-    openstack role add \
331
-        $ADMIN_ROLE \
332
-        --project $ADMIN_TENANT \
333
-        --user $ADMIN_USER
318
+    ADMIN_TENANT=$(get_or_create_project "admin")
319
+    ADMIN_USER=$(get_or_create_user "admin" \
320
+        "$ADMIN_PASSWORD" "$ADMIN_TENANT" "admin@example.com")
321
+    ADMIN_ROLE=$(get_or_create_role "admin")
322
+    get_or_add_user_role $ADMIN_ROLE $ADMIN_USER $ADMIN_TENANT
334 323
 
335 324
     # Create service project/role
336
-    openstack project create $SERVICE_TENANT_NAME
325
+    get_or_create_project "$SERVICE_TENANT_NAME"
337 326
 
338 327
     # Service role, so service users do not have to be admins
339
-    openstack role create service
328
+    get_or_create_role service
340 329
 
341 330
     # The ResellerAdmin role is used by Nova and Ceilometer so we need to keep it.
342 331
     # The admin role in swift allows a user to act as an admin for their tenant,
343 332
     # but ResellerAdmin is needed for a user to act as any tenant. The name of this
344 333
     # role is also configurable in swift-proxy.conf
345
-    openstack role create ResellerAdmin
334
+    get_or_create_role ResellerAdmin
346 335
 
347 336
     # The Member role is used by Horizon and Swift so we need to keep it:
348
-    MEMBER_ROLE=$(openstack role create \
349
-        Member \
350
-        | grep " id " | get_field 2)
337
+    MEMBER_ROLE=$(get_or_create_role "Member")
338
+
351 339
     # ANOTHER_ROLE demonstrates that an arbitrary role may be created and used
352 340
     # TODO(sleepsonthefloor): show how this can be used for rbac in the future!
353
-    ANOTHER_ROLE=$(openstack role create \
354
-        anotherrole \
355
-        | grep " id " | get_field 2)
341
+
342
+    ANOTHER_ROLE=$(get_or_create_role "anotherrole")
356 343
 
357 344
     # invisible tenant - admin can't see this one
358
-    INVIS_TENANT=$(openstack project create \
359
-        invisible_to_admin \
360
-        | grep " id " | get_field 2)
345
+    INVIS_TENANT=$(get_or_create_project "invisible_to_admin")
361 346
 
362 347
     # demo
363
-    DEMO_TENANT=$(openstack project create \
364
-        demo \
365
-        | grep " id " | get_field 2)
366
-    DEMO_USER=$(openstack user create \
367
-        demo \
368
-        --project $DEMO_TENANT \
369
-        --email demo@example.com \
370
-        --password "$ADMIN_PASSWORD" \
371
-        | grep " id " | get_field 2)
372
-
373
-    openstack role add --project $DEMO_TENANT --user $DEMO_USER $MEMBER_ROLE
374
-    openstack role add --project $DEMO_TENANT --user $ADMIN_USER $ADMIN_ROLE
375
-    openstack role add --project $DEMO_TENANT --user $DEMO_USER $ANOTHER_ROLE
376
-    openstack role add --project $INVIS_TENANT --user $DEMO_USER $MEMBER_ROLE
348
+    DEMO_TENANT=$(get_or_create_project "demo")
349
+    DEMO_USER=$(get_or_create_user "demo" \
350
+        "$ADMIN_PASSWORD" "$DEMO_TENANT" "demo@example.com")
351
+
352
+    get_or_add_user_role $MEMBER_ROLE $DEMO_USER $DEMO_TENANT
353
+    get_or_add_user_role $ADMIN_ROLE $ADMIN_USER $DEMO_TENANT
354
+    get_or_add_user_role $ANOTHER_ROLE $DEMO_USER $DEMO_TENANT
355
+    get_or_add_user_role $MEMBER_ROLE $DEMO_USER $INVIS_TENANT
377 356
 
378 357
     # Keystone
379 358
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
380
-        KEYSTONE_SERVICE=$(openstack service create \
381
-            keystone \
382
-            --type identity \
383
-            --description "Keystone Identity Service" \
384
-            | grep " id " | get_field 2)
385
-        openstack endpoint create \
386
-            $KEYSTONE_SERVICE \
387
-            --region RegionOne \
388
-            --publicurl "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
389
-            --adminurl "$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v$IDENTITY_API_VERSION" \
390
-            --internalurl "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"
359
+
360
+        KEYSTONE_SERVICE=$(get_or_create_service "keystone" \
361
+            "identity" "Keystone Identity Service")
362
+        get_or_create_endpoint $KEYSTONE_SERVICE \
363
+            "$REGION_NAME" \
364
+            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
365
+            "$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v$IDENTITY_API_VERSION" \
366
+            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"
391 367
     fi
392 368
 }
393 369
 
... ...
@@ -178,29 +178,19 @@ function create_marconi_accounts {
178 178
     SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
179 179
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
180 180
 
181
-    MARCONI_USER=$(openstack user create \
182
-        marconi \
183
-        --password "$SERVICE_PASSWORD" \
184
-        --project $SERVICE_TENANT \
185
-        --email marconi@example.com \
186
-        | grep " id " | get_field 2)
187
-    openstack role add \
188
-        $ADMIN_ROLE \
189
-        --project $SERVICE_TENANT \
190
-        --user $MARCONI_USER
181
+    MARCONI_USER=$(get_or_create_user "marconi" \
182
+        "$SERVICE_PASSWORD" $SERVICE_TENANT "marconi@example.com")
183
+    get_or_add_user_role $ADMIN_ROLE $MARCONI_USER $SERVICE_TENANT
191 184
 
192 185
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
193
-        MARCONI_SERVICE=$(openstack service create \
194
-            marconi \
195
-            --type=queuing \
196
-            --description="Marconi Service" \
197
-            | grep " id " | get_field 2)
198
-        openstack endpoint create \
199
-            $MARCONI_SERVICE \
200
-            --region RegionOne \
201
-            --publicurl "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
202
-            --adminurl "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
203
-            --internalurl "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT"
186
+
187
+        MARCONI_SERVICE=$(get_or_create_service "marconi" \
188
+            "queuing" "Marconi Service")
189
+        get_or_create_endpoint $MARCONI_SERVICE \
190
+            "$REGION_NAME" \
191
+            "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
192
+            "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
193
+            "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT"
204 194
     fi
205 195
 
206 196
 }
... ...
@@ -307,7 +307,7 @@ function create_nova_conf_neutron {
307 307
     iniset $NOVA_CONF neutron admin_auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v2.0"
308 308
     iniset $NOVA_CONF neutron auth_strategy "$Q_AUTH_STRATEGY"
309 309
     iniset $NOVA_CONF neutron admin_tenant_name "$SERVICE_TENANT_NAME"
310
-    iniset $NOVA_CONF neutron region_name "RegionOne"
310
+    iniset $NOVA_CONF neutron region_name "$REGION_NAME"
311 311
     iniset $NOVA_CONF neutron url "http://$Q_HOST:$Q_PORT"
312 312
 
313 313
     if [[ "$Q_USE_SECGROUP" == "True" ]]; then
... ...
@@ -350,28 +350,20 @@ function create_neutron_accounts {
350 350
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
351 351
 
352 352
     if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then
353
-        NEUTRON_USER=$(openstack user create \
354
-            neutron \
355
-            --password "$SERVICE_PASSWORD" \
356
-            --project $SERVICE_TENANT \
357
-            --email neutron@example.com \
358
-            | grep " id " | get_field 2)
359
-        openstack role add \
360
-            $ADMIN_ROLE \
361
-            --project $SERVICE_TENANT \
362
-            --user $NEUTRON_USER
353
+
354
+        NEUTRON_USER=$(get_or_create_user "neutron" \
355
+            "$SERVICE_PASSWORD" $SERVICE_TENANT "neutron@example.com")
356
+        get_or_add_user_role $ADMIN_ROLE $NEUTRON_USER $SERVICE_TENANT
357
+
363 358
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
364
-            NEUTRON_SERVICE=$(openstack service create \
365
-                neutron \
366
-                --type=network \
367
-                --description="Neutron Service" \
368
-                | grep " id " | get_field 2)
369
-            openstack endpoint create \
370
-                $NEUTRON_SERVICE \
371
-                --region RegionOne \
372
-                --publicurl "http://$SERVICE_HOST:9696/" \
373
-                --adminurl "http://$SERVICE_HOST:9696/" \
374
-                --internalurl "http://$SERVICE_HOST:9696/"
359
+
360
+            NEUTRON_SERVICE=$(get_or_create_service "neutron" \
361
+                "network" "Neutron Service")
362
+            get_or_create_endpoint $NEUTRON_SERVICE \
363
+                "$REGION_NAME" \
364
+                "http://$SERVICE_HOST:9696/" \
365
+                "http://$SERVICE_HOST:9696/" \
366
+                "http://$SERVICE_HOST:9696/"
375 367
         fi
376 368
     fi
377 369
 }
... ...
@@ -333,39 +333,28 @@ create_nova_accounts() {
333 333
 
334 334
     # Nova
335 335
     if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
336
-        NOVA_USER=$(openstack user create \
337
-            nova \
338
-            --password "$SERVICE_PASSWORD" \
339
-            --project $SERVICE_TENANT \
340
-            --email nova@example.com \
341
-            | grep " id " | get_field 2)
342
-        openstack role add \
343
-            $ADMIN_ROLE \
344
-            --project $SERVICE_TENANT \
345
-            --user $NOVA_USER
336
+
337
+        NOVA_USER=$(get_or_create_user "nova" \
338
+            "$SERVICE_PASSWORD" $SERVICE_TENANT "nova@example.com")
339
+        get_or_add_user_role $ADMIN_ROLE $NOVA_USER $SERVICE_TENANT
340
+
346 341
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
347
-            NOVA_SERVICE=$(openstack service create \
348
-                nova \
349
-                --type=compute \
350
-                --description="Nova Compute Service" \
351
-                | grep " id " | get_field 2)
352
-            openstack endpoint create \
353
-                $NOVA_SERVICE \
354
-                --region RegionOne \
355
-                --publicurl "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s" \
356
-                --adminurl "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s" \
357
-                --internalurl "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s"
358
-            NOVA_V3_SERVICE=$(openstack service create \
359
-                novav3 \
360
-                --type=computev3 \
361
-                --description="Nova Compute Service V3" \
362
-                | grep " id " | get_field 2)
363
-            openstack endpoint create \
364
-                $NOVA_V3_SERVICE \
365
-                --region RegionOne \
366
-                --publicurl "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3" \
367
-                --adminurl "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3" \
368
-                --internalurl "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3"
342
+
343
+            NOVA_SERVICE=$(get_or_create_service "nova" \
344
+                "compute" "Nova Compute Service")
345
+            get_or_create_endpoint $NOVA_SERVICE \
346
+                "$REGION_NAME" \
347
+                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s" \
348
+                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s" \
349
+                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s"
350
+
351
+            NOVA_V3_SERVICE=$(get_or_create_service "novav3" \
352
+                "computev3" "Nova Compute Service V3")
353
+            get_or_create_endpoint $NOVA_V3_SERVICE \
354
+                "$REGION_NAME" \
355
+                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3" \
356
+                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3" \
357
+                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3"
369 358
         fi
370 359
     fi
371 360
 
... ...
@@ -374,40 +363,32 @@ create_nova_accounts() {
374 374
         if is_service_enabled swift; then
375 375
             # Nova needs ResellerAdmin role to download images when accessing
376 376
             # swift through the s3 api.
377
-            openstack role add \
378
-                --project $SERVICE_TENANT_NAME \
379
-                --user nova \
380
-                ResellerAdmin
377
+            get_or_add_user_role ResellerAdmin nova $SERVICE_TENANT_NAME
381 378
         fi
382 379
 
383 380
         # EC2
384 381
         if [[ "$KEYSTONE_CATALOG_BACKEND" = "sql" ]]; then
385
-            openstack service create \
386
-                --type ec2 \
387
-                --description "EC2 Compatibility Layer" \
388
-                ec2
389
-            openstack endpoint create \
390
-                --region RegionOne \
391
-                --publicurl "http://$SERVICE_HOST:8773/services/Cloud" \
392
-                --adminurl "http://$SERVICE_HOST:8773/services/Admin" \
393
-                --internalurl "http://$SERVICE_HOST:8773/services/Cloud" \
394
-                ec2
382
+
383
+            EC2_SERVICE=$(get_or_create_service "ec2" \
384
+                "ec2" "EC2 Compatibility Layer")
385
+            get_or_create_endpoint $EC2_SERVICE \
386
+                "$REGION_NAME" \
387
+                "http://$SERVICE_HOST:8773/services/Cloud" \
388
+                "http://$SERVICE_HOST:8773/services/Admin" \
389
+                "http://$SERVICE_HOST:8773/services/Cloud"
395 390
         fi
396 391
     fi
397 392
 
398 393
     # S3
399 394
     if is_service_enabled n-obj swift3; then
400 395
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
401
-            openstack service create \
402
-                --type s3 \
403
-                --description "S3" \
404
-                s3
405
-            openstack endpoint create \
406
-                --region RegionOne \
407
-                --publicurl "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
408
-                --adminurl "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
409
-                --internalurl "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
410
-                s3
396
+
397
+            S3_SERVICE=$(get_or_create_service "s3" "s3" "S3")
398
+            get_or_create_endpoint $S3_SERVICE \
399
+                "$REGION_NAME" \
400
+                "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
401
+                "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
402
+                "http://$SERVICE_HOST:$S3_SERVICE_PORT"
411 403
         fi
412 404
     fi
413 405
 }
... ...
@@ -60,29 +60,19 @@ function create_sahara_accounts {
60 60
     SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
61 61
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
62 62
 
63
-    SAHARA_USER=$(openstack user create \
64
-        sahara \
65
-        --password "$SERVICE_PASSWORD" \
66
-        --project $SERVICE_TENANT \
67
-        --email sahara@example.com \
68
-        | grep " id " | get_field 2)
69
-    openstack role add \
70
-        $ADMIN_ROLE \
71
-        --project $SERVICE_TENANT \
72
-        --user $SAHARA_USER
63
+    SAHARA_USER=$(get_or_create_user "sahara" \
64
+        "$SERVICE_PASSWORD" $SERVICE_TENANT "sahara@example.com")
65
+    get_or_add_user_role $ADMIN_ROLE $SAHARA_USER $SERVICE_TENANT
73 66
 
74 67
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
75
-        SAHARA_SERVICE=$(openstack service create \
76
-            sahara \
77
-            --type=data_processing \
78
-            --description="Sahara Data Processing" \
79
-            | grep " id " | get_field 2)
80
-        openstack endpoint create \
81
-            $SAHARA_SERVICE \
82
-            --region RegionOne \
83
-            --publicurl "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
84
-            --adminurl "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
85
-            --internalurl "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s"
68
+
69
+        SAHARA_SERVICE=$(get_or_create_service "sahara" \
70
+            "data_processing" "Sahara Data Processing")
71
+        get_or_create_endpoint $SAHARA_SERVICE \
72
+            "$REGION_NAME" \
73
+            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
74
+            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
75
+            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s"
86 76
     fi
87 77
 }
88 78
 
... ...
@@ -542,50 +542,40 @@ function create_swift_accounts {
542 542
     SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
543 543
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
544 544
 
545
-    SWIFT_USER=$(openstack user create \
546
-        swift \
547
-        --password "$SERVICE_PASSWORD" \
548
-        --project $SERVICE_TENANT \
549
-        --email=swift@example.com \
550
-        | grep " id " | get_field 2)
551
-    openstack role add \
552
-        $ADMIN_ROLE \
553
-        --project $SERVICE_TENANT \
554
-        --user $SWIFT_USER
545
+    SWIFT_USER=$(get_or_create_user "swift" \
546
+        "$SERVICE_PASSWORD" $SERVICE_TENANT "swift@example.com")
547
+    get_or_add_user_role $ADMIN_ROLE $SWIFT_USER $SERVICE_TENANT
555 548
 
556 549
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
557
-        SWIFT_SERVICE=$(openstack service create \
558
-            swift \
559
-            --type="object-store" \
560
-            --description="Swift Service" \
561
-            | grep " id " | get_field 2)
562
-        openstack endpoint create \
563
-            $SWIFT_SERVICE \
564
-            --region RegionOne \
565
-            --publicurl "http://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s" \
566
-            --adminurl "http://$SERVICE_HOST:8080" \
567
-            --internalurl "http://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s"
550
+
551
+        SWIFT_SERVICE=$(get_or_create_service "swift" \
552
+            "object-store" "Swift Service")
553
+        get_or_create_endpoint $SWIFT_SERVICE \
554
+            "$REGION_NAME" \
555
+            "http://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s" \
556
+            "http://$SERVICE_HOST:8080" \
557
+            "http://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s"
568 558
     fi
569 559
 
570
-    SWIFT_TENANT_TEST1=$(openstack project create swifttenanttest1 | grep " id " | get_field 2)
560
+    SWIFT_TENANT_TEST1=$(get_or_create_project swifttenanttest1)
571 561
     die_if_not_set $LINENO SWIFT_TENANT_TEST1 "Failure creating SWIFT_TENANT_TEST1"
572
-    SWIFT_USER_TEST1=$(openstack user create swiftusertest1 --password=$SWIFTUSERTEST1_PASSWORD \
573
-        --project "$SWIFT_TENANT_TEST1" --email=test@example.com | grep " id " | get_field 2)
562
+    SWIFT_USER_TEST1=$(get_or_create_user swiftusertest1 $SWIFTUSERTEST1_PASSWORD \
563
+        "$SWIFT_TENANT_TEST1" "test@example.com")
574 564
     die_if_not_set $LINENO SWIFT_USER_TEST1 "Failure creating SWIFT_USER_TEST1"
575
-    openstack role add --user $SWIFT_USER_TEST1 --project $SWIFT_TENANT_TEST1 $ADMIN_ROLE
565
+    get_or_add_user_role $ADMIN_ROLE $SWIFT_USER_TEST1 $SWIFT_TENANT_TEST1
576 566
 
577
-    SWIFT_USER_TEST3=$(openstack user create swiftusertest3 --password=$SWIFTUSERTEST3_PASSWORD \
578
-        --project "$SWIFT_TENANT_TEST1" --email=test3@example.com | grep " id " | get_field 2)
567
+    SWIFT_USER_TEST3=$(get_or_create_user swiftusertest3 $SWIFTUSERTEST3_PASSWORD \
568
+        "$SWIFT_TENANT_TEST1" "test3@example.com")
579 569
     die_if_not_set $LINENO SWIFT_USER_TEST3 "Failure creating SWIFT_USER_TEST3"
580
-    openstack role add --user $SWIFT_USER_TEST3 --project $SWIFT_TENANT_TEST1 $ANOTHER_ROLE
570
+    get_or_add_user_role $ANOTHER_ROLE $SWIFT_USER_TEST3 $SWIFT_TENANT_TEST1
581 571
 
582
-    SWIFT_TENANT_TEST2=$(openstack project create swifttenanttest2 | grep " id " | get_field 2)
572
+    SWIFT_TENANT_TEST2=$(get_or_create_project swifttenanttest2)
583 573
     die_if_not_set $LINENO SWIFT_TENANT_TEST2 "Failure creating SWIFT_TENANT_TEST2"
584 574
 
585
-    SWIFT_USER_TEST2=$(openstack user create swiftusertest2 --password=$SWIFTUSERTEST2_PASSWORD \
586
-        --project "$SWIFT_TENANT_TEST2" --email=test2@example.com | grep " id " | get_field 2)
575
+    SWIFT_USER_TEST2=$(get_or_create_user swiftusertest2 $SWIFTUSERTEST2_PASSWORD \
576
+        "$SWIFT_TENANT_TEST2" "test2@example.com")
587 577
     die_if_not_set $LINENO SWIFT_USER_TEST2 "Failure creating SWIFT_USER_TEST2"
588
-    openstack role add --user $SWIFT_USER_TEST2 --project $SWIFT_TENANT_TEST2 $ADMIN_ROLE
578
+    get_or_add_user_role $ADMIN_ROLE $SWIFT_USER_TEST2 $SWIFT_TENANT_TEST2
589 579
 }
590 580
 
591 581
 # init_swift() - Initialize rings
... ...
@@ -397,16 +397,9 @@ function create_tempest_accounts {
397 397
     if is_service_enabled tempest; then
398 398
         # Tempest has some tests that validate various authorization checks
399 399
         # between two regular users in separate tenants
400
-        openstack project create \
401
-            alt_demo
402
-        openstack user create \
403
-            --project alt_demo \
404
-            --password "$ADMIN_PASSWORD" \
405
-            alt_demo
406
-        openstack role add \
407
-            --project alt_demo \
408
-            --user alt_demo \
409
-            Member
400
+        get_or_create_project alt_demo
401
+        get_or_create_user alt_demo "$ADMIN_PASSWORD" alt_demo "alt_demo@example.com"
402
+        get_or_add_user_role Member alt_demo alt_demo
410 403
     fi
411 404
 }
412 405
 
... ...
@@ -82,28 +82,20 @@ function create_trove_accounts {
82 82
     SERVICE_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
83 83
 
84 84
     if [[ "$ENABLED_SERVICES" =~ "trove" ]]; then
85
-        TROVE_USER=$(openstack user create \
86
-            trove \
87
-            --password "$SERVICE_PASSWORD" \
88
-            --project $SERVICE_TENANT \
89
-            --email trove@example.com \
90
-            | grep " id " | get_field 2)
91
-        openstack role add \
92
-            $SERVICE_ROLE \
93
-            --project $SERVICE_TENANT \
94
-            --user $TROVE_USER
85
+
86
+        TROVE_USER=$(get_or_create_user "trove" \
87
+            "$SERVICE_PASSWORD" $SERVICE_TENANT "trove@example.com")
88
+        get_or_add_user_role $SERVICE_ROLE $TROVE_USER $SERVICE_TENANT
89
+
95 90
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
96
-            TROVE_SERVICE=$(openstack service create \
97
-                trove \
98
-                --type=database \
99
-                --description="Trove Service" \
100
-                | grep " id " | get_field 2)
101
-            openstack endpoint create \
102
-                $TROVE_SERVICE \
103
-                --region RegionOne \
104
-                --publicurl "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s" \
105
-                --adminurl "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s" \
106
-                --internalurl "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s"
91
+
92
+            TROVE_SERVICE=$(get_or_create_service "trove" \
93
+                "database" "Trove Service")
94
+            get_or_create_endpoint $TROVE_SERVICE \
95
+                "$REGION_NAME" \
96
+                "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s" \
97
+                "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s" \
98
+                "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s"
107 99
         fi
108 100
     fi
109 101
 }
... ...
@@ -53,12 +53,16 @@ export OS_PASSWORD=${ADMIN_PASSWORD:-secrete}
53 53
 # easier with this off.
54 54
 export OS_NO_CACHE=${OS_NO_CACHE:-1}
55 55
 
56
+# Region
57
+export OS_REGION_NAME=${REGION_NAME:-RegionOne}
58
+
56 59
 # Set api HOST_IP endpoint.  SERVICE_HOST may also be used to specify the endpoint,
57 60
 # which is convenient for some localrc configurations.
58 61
 HOST_IP=${HOST_IP:-127.0.0.1}
59 62
 SERVICE_HOST=${SERVICE_HOST:-$HOST_IP}
60 63
 SERVICE_PROTOCOL=${SERVICE_PROTOCOL:-http}
61 64
 KEYSTONE_AUTH_PROTOCOL=${KEYSTONE_AUTH_PROTOCOL:-$SERVICE_PROTOCOL}
65
+KEYSTONE_AUTH_HOST=${KEYSTONE_AUTH_HOST:-$SERVICE_HOST}
62 66
 
63 67
 # Some exercises call glance directly.  On a single-node installation, Glance
64 68
 # should be listening on HOST_IP.  If its running elsewhere, it can be set here
... ...
@@ -72,7 +76,7 @@ export OS_IDENTITY_API_VERSION=${IDENTITY_API_VERSION:-2.0}
72 72
 # the user/tenant has access to - including nova, glance, keystone, swift, ...
73 73
 # We currently recommend using the 2.0 *identity api*.
74 74
 #
75
-export OS_AUTH_URL=$KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:5000/v${OS_IDENTITY_API_VERSION}
75
+export OS_AUTH_URL=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:5000/v${OS_IDENTITY_API_VERSION}
76 76
 
77 77
 # Set the pointer to our CA certificate chain.  Harmless if TLS is not used.
78 78
 export OS_CACERT=${OS_CACERT:-$INT_CA_DIR/ca-chain.pem}
... ...
@@ -726,8 +726,10 @@ git_clone $OPENSTACKCLIENT_REPO $OPENSTACKCLIENT_DIR $OPENSTACKCLIENT_BRANCH
726 726
 setup_develop $OPENSTACKCLIENT_DIR
727 727
 
728 728
 if is_service_enabled key; then
729
-    install_keystone
730
-    configure_keystone
729
+    if [ "$KEYSTONE_AUTH_HOST" == "$SERVICE_HOST" ]; then
730
+        install_keystone
731
+        configure_keystone
732
+    fi
731 733
 fi
732 734
 
733 735
 if is_service_enabled s-proxy; then
... ...
@@ -926,8 +928,11 @@ fi
926 926
 
927 927
 if is_service_enabled key; then
928 928
     echo_summary "Starting Keystone"
929
-    init_keystone
930
-    start_keystone
929
+
930
+    if [ "$KEYSTONE_AUTH_HOST" == "$SERVICE_HOST" ]; then
931
+        init_keystone
932
+        start_keystone
933
+    fi
931 934
 
932 935
     # Set up a temporary admin URI for Keystone
933 936
     SERVICE_ENDPOINT=$KEYSTONE_AUTH_URI/v2.0
... ...
@@ -968,6 +973,7 @@ if is_service_enabled key; then
968 968
     export OS_TENANT_NAME=admin
969 969
     export OS_USERNAME=admin
970 970
     export OS_PASSWORD=$ADMIN_PASSWORD
971
+    export OS_REGION_NAME=$REGION_NAME
971 972
 fi
972 973
 
973 974
 
... ...
@@ -19,6 +19,9 @@ else
19 19
     STACK_USER=$(whoami)
20 20
 fi
21 21
 
22
+# Specify region name Region
23
+REGION_NAME=${REGION_NAME:-RegionOne}
24
+
22 25
 # Specify which services to launch.  These generally correspond to
23 26
 # screen tabs. To change the default list, use the ``enable_service`` and
24 27
 # ``disable_service`` functions in ``local.conf``.