summaryrefslogtreecommitdiff
path: root/devstack/lib/heat
blob: 2a04d9dca4b7f6ef3eae200e7279f6873e55fb16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
#!/bin/bash
#
# lib/heat
# Install and start **Heat** service

# To enable, add the following to localrc
#
#   ENABLED_SERVICES+=,heat,h-api,h-api-cfn,h-api-cw,h-eng

# Dependencies:
# (none)

# stack.sh
# ---------
# - install_heatclient
# - install_heat
# - configure_heatclient
# - configure_heat
# - init_heat
# - start_heat
# - stop_heat
# - cleanup_heat

# Save trace setting
_XTRACE_HEAT=$(set +o | grep xtrace)
set +o xtrace

# Defaults
# --------

# set up default directories
GITDIR["python-heatclient"]=$DEST/python-heatclient

# heat service
HEAT_REPO=${HEAT_REPO:-${GIT_BASE}/openstack/heat.git}
HEAT_BRANCH=${HEAT_BRANCH:-master}

# python heat client library
GITREPO["python-heatclient"]=${HEATCLIENT_REPO:-${GIT_BASE}/openstack/python-heatclient.git}
GITBRANCH["python-heatclient"]=${HEATCLIENT_BRANCH:-master}

# Toggle for deploying Heat-API under HTTPD + mod_wsgi
HEAT_USE_MOD_WSGI=${HEAT_USE_MOD_WSGI:-True}

HEAT_DIR=$DEST/heat
HEAT_FILES_DIR=$HEAT_DIR/devstack/files

HEAT_AUTH_CACHE_DIR=${HEAT_AUTH_CACHE_DIR:-/var/cache/heat}
HEAT_STANDALONE=$(trueorfalse False HEAT_STANDALONE)
HEAT_ENABLE_ADOPT_ABANDON=$(trueorfalse False HEAT_ENABLE_ADOPT_ABANDON)
HEAT_CONF_DIR=/etc/heat
HEAT_CONF=$HEAT_CONF_DIR/heat.conf
HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
HEAT_API_PORT=${HEAT_API_PORT:-8004}
HEAT_SERVICE_USER=${HEAT_SERVICE_USER:-heat}
HEAT_TRUSTEE_USER=${HEAT_TRUSTEE_USER:-$HEAT_SERVICE_USER}
HEAT_TRUSTEE_PASSWORD=${HEAT_TRUSTEE_PASSWORD:-$SERVICE_PASSWORD}
HEAT_TRUSTEE_DOMAIN=${HEAT_TRUSTEE_DOMAIN:-default}

# Support entry points installation of console scripts
HEAT_BIN_DIR=$(get_python_exec_prefix)

# other default options
if [[ "$HEAT_STANDALONE" = "True" ]]; then
    # for standalone, use defaults which require no service user
    HEAT_STACK_DOMAIN=$(trueorfalse False HEAT_STACK_DOMAIN)
    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-password}
    if [[ ${HEAT_DEFERRED_AUTH} != "password" ]]; then
        # Heat does not support keystone trusts when deployed in
        # standalone mode
        die $LINENO \
            'HEAT_DEFERRED_AUTH can only be set to "password" when HEAT_STANDALONE is True.'
    fi
else
    HEAT_STACK_DOMAIN=$(trueorfalse True HEAT_STACK_DOMAIN)
    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-}
fi
HEAT_PLUGIN_DIR=${HEAT_PLUGIN_DIR:-$DATA_DIR/heat/plugins}
ENABLE_HEAT_PLUGINS=${ENABLE_HEAT_PLUGINS:-}

# Functions
# ---------

# Test if any Heat services are enabled
# is_heat_enabled
function is_heat_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"h-" ]] && return 0
    return 1
}

# cleanup_heat() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_heat {
    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        _cleanup_heat_apache_wsgi
    fi
    sudo rm -rf $HEAT_AUTH_CACHE_DIR
    sudo rm -rf $HEAT_ENV_DIR
    sudo rm -rf $HEAT_TEMPLATES_DIR
    sudo rm -rf $HEAT_CONF_DIR
}

# configure_heat() - Set config files, create data dirs, etc
function configure_heat {

    sudo install -d -o $STACK_USER $HEAT_CONF_DIR
    # remove old config files
    rm -f $HEAT_CONF_DIR/heat-*.conf

    HEAT_API_CFN_HOST=${HEAT_API_CFN_HOST:-$HOST_IP}
    HEAT_API_CFN_PORT=${HEAT_API_CFN_PORT:-8000}
    HEAT_ENGINE_HOST=${HEAT_ENGINE_HOST:-$SERVICE_HOST}
    HEAT_ENGINE_PORT=${HEAT_ENGINE_PORT:-8001}
    HEAT_API_CW_HOST=${HEAT_API_CW_HOST:-$HOST_IP}
    HEAT_API_CW_PORT=${HEAT_API_CW_PORT:-8003}
    HEAT_API_PASTE_FILE=$HEAT_CONF_DIR/api-paste.ini
    HEAT_POLICY_FILE=$HEAT_CONF_DIR/policy.json

    cp $HEAT_DIR/etc/heat/api-paste.ini $HEAT_API_PASTE_FILE
    cp $HEAT_DIR/etc/heat/policy.json $HEAT_POLICY_FILE

    # common options
    iniset_rpc_backend heat $HEAT_CONF
    iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT
    iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
    iniset $HEAT_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
    iniset $HEAT_CONF database connection `database_connection_url heat`
    iniset $HEAT_CONF DEFAULT auth_encryption_key $(generate_hex_string 16)

    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
    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] && [ "$HEAT_USE_MOD_WSGI" == "False" ]  ; then
        # Add color to logging output
        setup_colorized_logging $HEAT_CONF DEFAULT tenant user
    fi

    if [ ! -z "$HEAT_DEFERRED_AUTH" ]; then
        iniset $HEAT_CONF DEFAULT deferred_auth_method $HEAT_DEFERRED_AUTH
    fi

    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        _config_heat_apache_wsgi
    fi

    if [[ "$HEAT_STANDALONE" = "True" ]]; then
        iniset $HEAT_CONF paste_deploy flavor standalone
        iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
    else
        configure_auth_token_middleware $HEAT_CONF heat $HEAT_AUTH_CACHE_DIR
    fi

    # If HEAT_DEFERRED_AUTH is unset or explicitly set to trusts, configure
    # the section for the client plugin associated with the trustee
    if [ -z "$HEAT_DEFERRED_AUTH" -o "trusts" == "$HEAT_DEFERRED_AUTH" ]; then
        iniset $HEAT_CONF trustee auth_type password
        iniset $HEAT_CONF trustee auth_url $KEYSTONE_AUTH_URI
        iniset $HEAT_CONF trustee username $HEAT_TRUSTEE_USER
        iniset $HEAT_CONF trustee password $HEAT_TRUSTEE_PASSWORD
        iniset $HEAT_CONF trustee user_domain_id $HEAT_TRUSTEE_DOMAIN
    fi

    # clients_keystone
    iniset $HEAT_CONF clients_keystone auth_uri $KEYSTONE_AUTH_URI

    # OpenStack API
    iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT
    iniset $HEAT_CONF heat_api workers "$API_WORKERS"

    # Cloudformation API
    iniset $HEAT_CONF heat_api_cfn bind_port $HEAT_API_CFN_PORT

    # Cloudwatch API
    iniset $HEAT_CONF heat_api_cloudwatch bind_port $HEAT_API_CW_PORT

    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
        iniset $HEAT_CONF clients_keystone ca_file $SSL_BUNDLE_FILE
    fi

    if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
        iniset $HEAT_CONF clients_nova ca_file $SSL_BUNDLE_FILE
    fi

    if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
        iniset $HEAT_CONF clients_cinder ca_file $SSL_BUNDLE_FILE
    fi

    if [[ "$HEAT_ENABLE_ADOPT_ABANDON" = "True" ]]; then
        iniset $HEAT_CONF DEFAULT enable_stack_adopt true
        iniset $HEAT_CONF DEFAULT enable_stack_abandon true
    fi

    iniset $HEAT_CONF cache enabled "True"
    iniset $HEAT_CONF cache backend "dogpile.cache.memory"

    if ! is_service_enabled c-bak; then
        iniset $HEAT_CONF volumes backups_enabled false
    fi

    sudo install -d -o $STACK_USER $HEAT_ENV_DIR $HEAT_TEMPLATES_DIR

    # copy the default environment
    cp $HEAT_DIR/etc/heat/environment.d/* $HEAT_ENV_DIR/

    # copy the default templates
    cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/

    # Enable heat plugins.
    # NOTE(nic): The symlink nonsense is necessary because when
    # plugins are installed in "developer mode", the final component
    # of their target directory is always "resources", which confuses
    # Heat's plugin loader into believing that all plugins are named
    # "resources", and therefore are all the same plugin; so it
    # will only load one of them.  Linking them all to a common
    # location with unique names avoids that type of collision,
    # while still allowing the plugins to be edited in-tree.
    local err_count=0

    if [ -n "$ENABLE_HEAT_PLUGINS" ]; then
        mkdir -p $HEAT_PLUGIN_DIR
        # Clean up cruft from any previous runs
        rm -f $HEAT_PLUGIN_DIR/*
        iniset $HEAT_CONF DEFAULT plugin_dirs $HEAT_PLUGIN_DIR
    fi

    for heat_plugin in $ENABLE_HEAT_PLUGINS; do
        if [ -d $HEAT_DIR/contrib/$heat_plugin ]; then
            setup_package $HEAT_DIR/contrib/$heat_plugin -e
            ln -s $HEAT_DIR/contrib/$heat_plugin/$heat_plugin/resources $HEAT_PLUGIN_DIR/$heat_plugin
        else
            : # clear retval on the test so that we can roll up errors
            err $LINENO "Requested Heat plugin(${heat_plugin}) not found."
            err_count=$(($err_count + 1))
        fi
    done
    [ $err_count -eq 0 ] || die $LINENO "$err_count of the requested Heat plugins could not be installed."
}

# init_heat() - Initialize database
function init_heat {
    # recreate db only if one of the db services is enabled
    if is_service_enabled $DATABASE_BACKENDS; then
        # (re)create heat database
        recreate_database heat
        $HEAT_BIN_DIR/heat-manage db_sync
    fi
    create_heat_cache_dir
}

# create_heat_cache_dir() - Part of the init_heat() process
function create_heat_cache_dir {
    # Create cache dirs
    sudo install -d -o $STACK_USER $HEAT_AUTH_CACHE_DIR
}

# install_heatclient() - Collect source and prepare
function install_heatclient {
    if use_library_from_git "python-heatclient"; then
        git_clone_by_name "python-heatclient"
        setup_dev_lib "python-heatclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-heatclient"]}/tools/,/etc/bash_completion.d/}heat.bash_completion
    fi
}

# install_heat() - Collect source and prepare
function install_heat {
    git_clone $HEAT_REPO $HEAT_DIR $HEAT_BRANCH
    setup_develop $HEAT_DIR
    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        install_apache_wsgi
    fi
}

# dummy function called by stack.sh, remove it once moved to plugin
function install_heat_other {
    :
}

# start_heat() - Start running processes, including screen
function start_heat {
    run_process h-eng "$HEAT_BIN_DIR/heat-engine --config-file=$HEAT_CONF"

    # If the site is not enabled then we are in a grenade scenario
    local enabled_site_file
    enabled_site_file=$(apache_site_config_for heat-api)
    if [ -f ${enabled_site_file} ] && [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        enable_apache_site heat-api
        enable_apache_site heat-api-cfn
        enable_apache_site heat-api-cloudwatch
        restart_apache_server
        tail_log heat-api /var/log/$APACHE_NAME/heat-api.log
        tail_log heat-api-cfn /var/log/$APACHE_NAME/heat-api-cfn.log
        tail_log heat-api-cloudwatch /var/log/$APACHE_NAME/heat-api-cloudwatch.log
    else
        run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
        run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
        run_process h-api-cw "$HEAT_BIN_DIR/heat-api-cloudwatch --config-file=$HEAT_CONF"
    fi
}

# stop_heat() - Stop running processes
function stop_heat {
    # Kill the screen windows
    stop_process h-eng

    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        disable_apache_site heat-api
        disable_apache_site heat-api-cfn
        disable_apache_site heat-api-cloudwatch
        restart_apache_server
    else
        local serv
        for serv in h-api h-api-cfn h-api-cw; do
            stop_process $serv
        done
    fi

}

# _cleanup_heat_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cleanup_heat_apache_wsgi {
    sudo rm -f $(apache_site_config_for heat-api)
    sudo rm -f $(apache_site_config_for heat-api-cfn)
    sudo rm -f $(apache_site_config_for heat-api-cloudwatch)
}

# _config_heat_apache_wsgi() - Set WSGI config files of Heat
function _config_heat_apache_wsgi {

    local heat_apache_conf
    heat_apache_conf=$(apache_site_config_for heat-api)
    local heat_cfn_apache_conf
    heat_cfn_apache_conf=$(apache_site_config_for heat-api-cfn)
    local heat_cloudwatch_apache_conf
    heat_cloudwatch_apache_conf=$(apache_site_config_for heat-api-cloudwatch)
    local heat_ssl=""
    local heat_certfile=""
    local heat_keyfile=""
    local heat_api_port=$HEAT_API_PORT
    local heat_cfn_api_port=$HEAT_API_CFN_PORT
    local heat_cw_api_port=$HEAT_API_CW_PORT
    local venv_path=""

    sudo cp $HEAT_FILES_DIR/apache-heat-api.template $heat_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$heat_api_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
        s|%API_WORKERS%|$API_WORKERS|g;
        s|%SSLENGINE%|$heat_ssl|g;
        s|%SSLCERTFILE%|$heat_certfile|g;
        s|%SSLKEYFILE%|$heat_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
    " -i $heat_apache_conf

    sudo cp $HEAT_FILES_DIR/apache-heat-api-cfn.template $heat_cfn_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$heat_cfn_api_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
        s|%API_WORKERS%|$API_WORKERS|g;
        s|%SSLENGINE%|$heat_ssl|g;
        s|%SSLCERTFILE%|$heat_certfile|g;
        s|%SSLKEYFILE%|$heat_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
    " -i $heat_cfn_apache_conf

    sudo cp $HEAT_FILES_DIR/apache-heat-api-cloudwatch.template $heat_cloudwatch_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$heat_cw_api_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
        s|%API_WORKERS%|$API_WORKERS|g;
        s|%SSLENGINE%|$heat_ssl|g;
        s|%SSLCERTFILE%|$heat_certfile|g;
        s|%SSLKEYFILE%|$heat_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
    " -i $heat_cloudwatch_apache_conf
}


# create_heat_accounts() - Set up common required heat accounts
function create_heat_accounts {
    if [[ "$HEAT_STANDALONE" != "True" ]]; then

        create_service_user "heat" "admin"
        get_or_create_service "heat" "orchestration" "Heat Orchestration Service"
        get_or_create_endpoint \
            "orchestration" \
            "$REGION_NAME" \
            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s" \
            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s" \
            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s"

        get_or_create_service "heat-cfn" "cloudformation" "Heat CloudFormation Service"
        get_or_create_endpoint \
            "cloudformation"  \
            "$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"

        # heat_stack_user role is for users created by Heat
        get_or_create_role "heat_stack_user"
    fi

    if [[ "$HEAT_STACK_DOMAIN" == "True" ]]; then
        # domain -> heat and user -> heat_domain_admin
        domain_id=$(get_or_create_domain heat 'Owns users and projects created by heat')
        iniset $HEAT_CONF DEFAULT stack_user_domain_id ${domain_id}
        get_or_create_user heat_domain_admin $SERVICE_PASSWORD heat
        get_or_add_user_domain_role admin heat_domain_admin heat
        iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
        iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
    fi
}

# Restore xtrace
$_XTRACE_HEAT

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End: