Port password generation from tripleoclient to tripleo-common
At the moment the CLI generates various passwords, this logic is then not available to the GUI. We should move this to further standardise the process. This patch ports the necessary utility methods and adds an action to generate and store passwords in a mistral environment or retrieve previously generated passwords from the mistral environment. The action will generate and replace any missing passwords. The passwords are stored in parameter_defaults and are used in any subsequent calls to heat (e.g. Parameters and Stack Creation). The order of the merge of parameter_defaults and passwords allows a user to override a password value. The action is added to workflows in the plan_management workbook. Closes-Bug: #1621097 Change-Id: Ic476a09f7981d4e6ee12e05b333a18cda5b4626b
This commit is contained in:
committed by
Dougal Matthews
parent
7d8c9acde4
commit
49a7b8e80e
@@ -16,3 +16,4 @@ mistral!=2015.1.0,>=2.0.0 # Apache-2.0
|
||||
python-ironic-inspector-client>=1.5.0 # Apache-2.0
|
||||
Jinja2>=2.8 # BSD License (3 clause)
|
||||
python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
|
||||
passlib>=1.6 # BSD
|
||||
|
||||
@@ -71,6 +71,7 @@ mistral.actions =
|
||||
tripleo.parameters.reset = tripleo_common.actions.parameters:ResetParametersAction
|
||||
tripleo.parameters.update = tripleo_common.actions.parameters:UpdateParametersAction
|
||||
tripleo.parameters.update_role = tripleo_common.actions.parameters:UpdateRoleParametersAction
|
||||
tripleo.parameters.generate_passwords = tripleo_common.actions.parameters:GeneratePasswordsAction
|
||||
tripleo.plan.create = tripleo_common.actions.plan:CreatePlanAction
|
||||
tripleo.plan.update = tripleo_common.actions.plan:UpdatePlanAction
|
||||
tripleo.plan.create_container = tripleo_common.actions.plan:CreateContainerAction
|
||||
|
||||
@@ -34,6 +34,7 @@ from tripleo_common.actions import base
|
||||
from tripleo_common.actions import templates
|
||||
from tripleo_common import constants
|
||||
from tripleo_common.utils import parameters
|
||||
from tripleo_common.utils import passwords as password_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@@ -128,3 +129,45 @@ class UpdateRoleParametersAction(UpdateParametersAction):
|
||||
self.parameters = parameters.set_count_and_flavor_params(
|
||||
self.role, baremetal_client, compute_client)
|
||||
return super(UpdateRoleParametersAction, self).run()
|
||||
|
||||
|
||||
class GeneratePasswordsAction(base.TripleOAction):
|
||||
"""Generates passwords needed for Overcloud deployment
|
||||
|
||||
This method generates passwords and ensures they are stored in the
|
||||
mistral environment associated with a plan. This method respects
|
||||
previously generated passwords and adds new passwords as necessary.
|
||||
"""
|
||||
|
||||
def __init__(self, container=constants.DEFAULT_CONTAINER_NAME):
|
||||
self.container = container
|
||||
|
||||
def run(self):
|
||||
wc = self._get_workflow_client()
|
||||
try:
|
||||
wf_env = wc.environments.get(self.container)
|
||||
except Exception:
|
||||
msg = "Error retrieving mistral environment: %s" % self.container
|
||||
LOG.exception(msg)
|
||||
return mistral_workflow_utils.Result("", msg)
|
||||
|
||||
passwords = password_utils.generate_overcloud_passwords()
|
||||
|
||||
# if passwords don't yet exist in mistral environment
|
||||
if 'passwords' not in wf_env.variables:
|
||||
wf_env.variables['passwords'] = {}
|
||||
|
||||
# ensure all generated passwords are present in mistral env,
|
||||
# but respect any values previously generated and stored
|
||||
for name, password in passwords.items():
|
||||
if name not in wf_env.variables['passwords']:
|
||||
wf_env.variables['passwords'][name] = password
|
||||
|
||||
env_kwargs = {
|
||||
'name': wf_env.name,
|
||||
'variables': wf_env.variables,
|
||||
}
|
||||
|
||||
wc.environments.update(**env_kwargs)
|
||||
|
||||
return wf_env.variables['passwords']
|
||||
|
||||
@@ -160,11 +160,20 @@ class ProcessTemplatesAction(base.TripleOAction):
|
||||
temp_files.append(env_temp_file)
|
||||
env_paths.append(env_temp_file)
|
||||
|
||||
# handle user set parameter values
|
||||
params = mistral_environment.variables.get('parameter_defaults')
|
||||
if params:
|
||||
# create a dict to hold all user set params and merge
|
||||
# them in the appropriate order
|
||||
merged_params = {}
|
||||
# merge generated passwords into params first
|
||||
passwords = mistral_environment.variables.get('passwords', {})
|
||||
merged_params.update(passwords)
|
||||
# handle user set parameter values next in case a user has set
|
||||
# a new value for a password parameter
|
||||
params = mistral_environment.variables.get(
|
||||
'parameter_defaults', {})
|
||||
merged_params.update(params)
|
||||
if merged_params:
|
||||
env_temp_file = _create_temp_file(
|
||||
{'parameter_defaults': params})
|
||||
{'parameter_defaults': merged_params})
|
||||
temp_files.append(env_temp_file)
|
||||
env_paths.append(env_temp_file)
|
||||
|
||||
|
||||
@@ -50,3 +50,38 @@ TRIPLEO_META_USAGE_KEY = 'x-container-meta-usage-tripleo'
|
||||
# OBJECT_META_KEY_PREFIX is used to prefix Swift metadata keys per object
|
||||
# in SwiftPlanStorageBackend
|
||||
OBJECT_META_KEY_PREFIX = 'x-object-meta-'
|
||||
|
||||
#: List of names of parameters that contain passwords
|
||||
PASSWORD_PARAMETER_NAMES = (
|
||||
'AdminPassword',
|
||||
'AdminToken',
|
||||
'AodhPassword',
|
||||
'BarbicanPassword',
|
||||
'CeilometerPassword',
|
||||
'CeilometerMeteringSecret',
|
||||
'CinderPassword',
|
||||
'GlancePassword',
|
||||
'GnocchiPassword',
|
||||
'HAProxyStatsPassword',
|
||||
'HeatPassword',
|
||||
'HeatStackDomainAdminPassword',
|
||||
'IronicPassword',
|
||||
'MistralPassword',
|
||||
'MysqlClustercheckPassword',
|
||||
'NeutronPassword',
|
||||
'NovaPassword',
|
||||
'RabbitPassword',
|
||||
'RedisPassword',
|
||||
'SaharaPassword',
|
||||
'SwiftHashSuffix',
|
||||
'SwiftPassword',
|
||||
'SnmpdReadonlyUserPassword',
|
||||
'TrovePassword',
|
||||
'ZaqarPassword',
|
||||
'ManilaPassword',
|
||||
'NeutronMetadataProxySharedSecret',
|
||||
'CephMonKey',
|
||||
'CephAdminKey',
|
||||
'CephClientKey',
|
||||
'CephRgwKey',
|
||||
)
|
||||
|
||||
@@ -20,6 +20,40 @@ from tripleo_common.actions import parameters
|
||||
from tripleo_common import constants
|
||||
from tripleo_common.tests import base
|
||||
|
||||
_EXISTING_PASSWORDS = {
|
||||
'MistralPassword': 'VFJeqBKbatYhQm9jja67hufft',
|
||||
'BarbicanPassword': 'MGGQBtgKT7FnywvkcdMwE9nhx',
|
||||
'AdminPassword': 'jFmY8FTpvtF2e4d4ReXvmUP8k',
|
||||
'CeilometerMeteringSecret': 'CbHTGK4md4Cc8P8ZyzTns6wry',
|
||||
'ZaqarPassword': 'bbFgCTFbAH8vf9n3xvZCP8aMR',
|
||||
'NovaPassword': '7dZATgVPwD7Ergs9kTTDMCr7F',
|
||||
'IronicPassword': '4hFDgn9ANeVfuqk84pHpD4ksa',
|
||||
'RedisPassword': 'xjj3QZDcUQmU6Q7NzWBHRUhGd',
|
||||
'SaharaPassword': 'spFvYGezdFwnTk7NPxgYTbUPh',
|
||||
'AdminToken': 'jq6G6HyZtj7dcZEvuyhAfjutM',
|
||||
'CinderPassword': 'dcxC3xyUcrmvzfrrxpAd3REcm',
|
||||
'GlancePassword': 'VqJYNEdKKsGZtgnHct77XBtrV',
|
||||
'RabbitPassword': 'ahuHRXdPMx9rzCdjD9CJJNCgA',
|
||||
'CephAdminKey': b'AQCQXtlXAAAAABAAT4Gk+U8EqqStL+JFa9bp1Q==',
|
||||
'HAProxyStatsPassword': 'P8tbdK6n4YUkTaUyy8XgEVTe6',
|
||||
'TrovePassword': 'V7A7zegkMdRFnYuN23gdc4KQC',
|
||||
'CeilometerPassword': 'RRdpwK6qf2pbKz2UtzxqauAdk',
|
||||
'GnocchiPassword': 'cRYHcUkMuJeK3vyU9pCaznUZc',
|
||||
'HeatStackDomainAdminPassword': 'GgTRyWzKYsxK4mReTJ4CM6sMc',
|
||||
'CephRgwKey': b'AQCQXtlXAAAAABAAUKcqUMu6oMjAXMjoUV4/3A==',
|
||||
'AodhPassword': '8VZXehsKc2HbmFFMKYuqxTJHn',
|
||||
'ManilaPassword': 'NYJN86Fua3X8AVFWmMhQa2zTH',
|
||||
'NeutronMetadataProxySharedSecret': 'Q2YgUCwmBkYdqsdhhCF4hbghu',
|
||||
'CephMonKey': b'AQCQXtlXAAAAABAA9l+59N3yH+C49Y0JiKeGFg==',
|
||||
'SwiftHashSuffix': 'td8mV6k7TYEGKCDvjVBwckpn9',
|
||||
'SnmpdReadonlyUserPassword': 'TestPassword',
|
||||
'SwiftPassword': 'z6EWAVfW7CuxvKdzjWTdrXCeg',
|
||||
'HeatPassword': 'bREnsXtMHKTHxt8XW6NXAYr48',
|
||||
'MysqlClustercheckPassword': 'jN4RMMWWJ4sycaRwh7UvrAtfX',
|
||||
'CephClientKey': b'AQCQXtlXAAAAABAAKyc+8St8i9onHyu2mPk+vg==',
|
||||
'NeutronPassword': 'ZxAjdU2UXCV4GM3WyPKrzAZXD'
|
||||
}
|
||||
|
||||
|
||||
class GetParametersActionTest(base.TestCase):
|
||||
|
||||
@@ -126,6 +160,7 @@ class UpdateParametersActionTest(base.TestCase):
|
||||
test_parameters = {'SomeTestParameter': 42}
|
||||
action = parameters.UpdateParametersAction(test_parameters)
|
||||
action.run()
|
||||
|
||||
mock_mistral.environments.update.assert_called_once_with(
|
||||
name=constants.DEFAULT_CONTAINER_NAME,
|
||||
variables={
|
||||
@@ -134,3 +169,64 @@ class UpdateParametersActionTest(base.TestCase):
|
||||
'environments': [{u'path': u'environments/test.yaml'}],
|
||||
'parameter_defaults': {'SomeTestParameter': 42}}
|
||||
)
|
||||
|
||||
|
||||
class GeneratePasswordsActionTest(base.TestCase):
|
||||
|
||||
@mock.patch('tripleo_common.utils.passwords.'
|
||||
'get_hiera_key')
|
||||
@mock.patch('tripleo_common.actions.base.TripleOAction.'
|
||||
'_get_workflow_client')
|
||||
@mock.patch('mistral.context.ctx')
|
||||
def test_run(self, mock_ctx, mock_get_workflow_client,
|
||||
mock_hiera_key):
|
||||
|
||||
mock_hiera_key.return_value = "TestPassword"
|
||||
|
||||
mock_ctx.return_value = mock.MagicMock()
|
||||
mock_mistral = mock.MagicMock()
|
||||
mock_env = mock.MagicMock()
|
||||
mock_env.name = constants.DEFAULT_CONTAINER_NAME
|
||||
mock_env.variables = {
|
||||
'temp_environment': 'temp_environment',
|
||||
'template': 'template',
|
||||
'environments': [{u'path': u'environments/test.yaml'}],
|
||||
}
|
||||
mock_mistral.environments.get.return_value = mock_env
|
||||
mock_get_workflow_client.return_value = mock_mistral
|
||||
|
||||
action = parameters.GeneratePasswordsAction()
|
||||
result = action.run()
|
||||
|
||||
for password_param_name in constants.PASSWORD_PARAMETER_NAMES:
|
||||
self.assertTrue(password_param_name in result,
|
||||
"%s is not in %s" % (password_param_name, result))
|
||||
|
||||
@mock.patch('tripleo_common.utils.passwords.'
|
||||
'get_hiera_key')
|
||||
@mock.patch('tripleo_common.actions.base.TripleOAction.'
|
||||
'_get_workflow_client')
|
||||
@mock.patch('mistral.context.ctx')
|
||||
def test_run_passwords_exist(self, mock_ctx, mock_get_workflow_client,
|
||||
mock_hiera_key):
|
||||
|
||||
mock_hiera_key.return_value = "TestPassword"
|
||||
|
||||
mock_ctx.return_value = mock.MagicMock()
|
||||
mock_mistral = mock.MagicMock()
|
||||
mock_env = mock.MagicMock()
|
||||
mock_env.name = constants.DEFAULT_CONTAINER_NAME
|
||||
mock_env.variables = {
|
||||
'temp_environment': 'temp_environment',
|
||||
'template': 'template',
|
||||
'environments': [{u'path': u'environments/test.yaml'}],
|
||||
'passwords': _EXISTING_PASSWORDS
|
||||
}
|
||||
mock_mistral.environments.get.return_value = mock_env
|
||||
mock_get_workflow_client.return_value = mock_mistral
|
||||
|
||||
action = parameters.GeneratePasswordsAction()
|
||||
result = action.run()
|
||||
|
||||
# ensure old passwords used and no new generation
|
||||
self.assertEqual(_EXISTING_PASSWORDS, result)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# 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.
|
||||
import mock
|
||||
|
||||
from tripleo_common.tests import base
|
||||
from tripleo_common.utils import passwords as password_utils
|
||||
|
||||
|
||||
class TestPasswords(base.TestCase):
|
||||
|
||||
def test_create_cephx_key(self):
|
||||
key = password_utils.create_cephx_key()
|
||||
self.assertEqual(len(key), 40)
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_get_hiera_key(self, mock_popen):
|
||||
|
||||
process_mock = mock.Mock()
|
||||
process_mock.communicate.return_value = ["pa$$word", ""]
|
||||
mock_popen.return_value = process_mock
|
||||
|
||||
value = password_utils.get_hiera_key('password_name')
|
||||
|
||||
self.assertEqual(value, "pa$$word")
|
||||
@@ -0,0 +1,75 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# 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.
|
||||
import base64
|
||||
import logging
|
||||
import os
|
||||
import struct
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import passlib.utils as passutils
|
||||
from tripleo_common import constants
|
||||
|
||||
|
||||
_MIN_PASSWORD_SIZE = 25
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def generate_overcloud_passwords():
|
||||
"""Create the passwords needed for the overcloud
|
||||
|
||||
This will create the set of passwords required by the overcloud, store
|
||||
them in the output file path and return a dictionary of passwords. If the
|
||||
file already exists the existing passwords will be returned instead,
|
||||
"""
|
||||
|
||||
passwords = {}
|
||||
|
||||
for name in constants.PASSWORD_PARAMETER_NAMES:
|
||||
# CephX keys aren't random strings
|
||||
if name.startswith("Ceph"):
|
||||
passwords[name] = create_cephx_key()
|
||||
elif name == 'SnmpdReadonlyUserPassword':
|
||||
snmp_password = get_hiera_key(
|
||||
'snmpd_readonly_user_password')
|
||||
passwords[name] = snmp_password
|
||||
if not snmp_password:
|
||||
LOG.warning("Undercloud ceilometer SNMPd password "
|
||||
"missing!")
|
||||
else:
|
||||
passwords[name] = passutils.generate_password(
|
||||
size=_MIN_PASSWORD_SIZE)
|
||||
return passwords
|
||||
|
||||
|
||||
def create_cephx_key():
|
||||
# NOTE(gfidente): Taken from
|
||||
# https://github.com/ceph/ceph-deploy/blob/master/ceph_deploy/new.py#L21
|
||||
key = os.urandom(16)
|
||||
header = struct.pack("<hiih", 1, int(time.time()), 0, len(key))
|
||||
return base64.b64encode(header + key)
|
||||
|
||||
|
||||
def get_hiera_key(key_name):
|
||||
"""Retrieve a key from the hiera store
|
||||
|
||||
:param password_name: Name of the key to retrieve
|
||||
:type password_name: type
|
||||
"""
|
||||
|
||||
command = ["hiera", key_name]
|
||||
p = subprocess.Popen(command, stdout=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
return out
|
||||
@@ -104,6 +104,7 @@ workflows:
|
||||
- queue_name: tripleo
|
||||
|
||||
tasks:
|
||||
|
||||
deploy:
|
||||
action: tripleo.deployment.deploy timeout=<% $.timeout %> container=<% $.container %>
|
||||
on-success: test_validations_enabled
|
||||
|
||||
@@ -12,9 +12,14 @@ workflows:
|
||||
tasks:
|
||||
create_plan:
|
||||
action: tripleo.plan.create container=<% $.container %>
|
||||
on-success: process_templates
|
||||
on-success: ensure_passwords_exist
|
||||
on-error: create_plan_set_status_failed
|
||||
|
||||
ensure_passwords_exist:
|
||||
action: tripleo.parameters.generate_passwords container=<% $.container %>
|
||||
on-success: process_templates
|
||||
on-error: ensure_passwords_exist_set_status_failed
|
||||
|
||||
process_templates:
|
||||
action: tripleo.templates.process container=<% $.container %>
|
||||
on-success: set_status_success
|
||||
@@ -32,6 +37,12 @@ workflows:
|
||||
status: FAILED
|
||||
message: <% task(create_plan).result %>
|
||||
|
||||
ensure_passwords_exist_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(ensure_passwords_exist).result %>
|
||||
|
||||
process_templates_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
@@ -57,7 +68,7 @@ workflows:
|
||||
tasks:
|
||||
update_plan:
|
||||
action: tripleo.plan.update container=<% $.container %>
|
||||
on-success: process_templates
|
||||
on-success: ensure_passwords_exist
|
||||
on-error: update_plan_set_status_failed
|
||||
|
||||
process_templates:
|
||||
@@ -65,6 +76,11 @@ workflows:
|
||||
on-success: set_status_success
|
||||
on-error: process_templates_set_status_failed
|
||||
|
||||
ensure_passwords_exist:
|
||||
action: tripleo.parameters.generate_passwords container=<% $.container %>
|
||||
on-success: process_templates
|
||||
on-error: ensure_passwords_exist_set_status_failed
|
||||
|
||||
set_status_success:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
@@ -77,12 +93,19 @@ workflows:
|
||||
status: FAILED
|
||||
message: <% task(update_plan).result %>
|
||||
|
||||
|
||||
process_templates_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(process_templates).result %>
|
||||
|
||||
ensure_passwords_exist_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(ensure_passwords_exist).result %>
|
||||
|
||||
notify_zaqar:
|
||||
action: zaqar.queue_post
|
||||
input:
|
||||
@@ -129,9 +152,14 @@ workflows:
|
||||
|
||||
create_plan:
|
||||
action: tripleo.plan.create container=<% $.container %>
|
||||
on-success: plan_process_templates
|
||||
on-success: ensure_passwords_exist
|
||||
on-error: plan_set_status_failed
|
||||
|
||||
ensure_passwords_exist:
|
||||
action: tripleo.parameters.generate_passwords container=<% $.container %>
|
||||
on-success: plan_process_templates
|
||||
on-error: ensure_passwords_exist_set_status_failed
|
||||
|
||||
plan_process_templates:
|
||||
action: tripleo.templates.process container=<% $.container %>
|
||||
on-success: plan_set_status_success
|
||||
@@ -149,6 +177,12 @@ workflows:
|
||||
status: FAILED
|
||||
message: <% task(create_plan).result %>
|
||||
|
||||
ensure_passwords_exist_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(ensure_passwords_exist).result %>
|
||||
|
||||
process_templates_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
@@ -178,3 +212,62 @@ workflows:
|
||||
status: <% $.status %>
|
||||
message: <% $.message or '' %>
|
||||
execution: <% execution() %>
|
||||
|
||||
get_passwords:
|
||||
description: Retrieves passwords for a given plan
|
||||
input:
|
||||
- container
|
||||
- queue_name: tripleo
|
||||
|
||||
tasks:
|
||||
|
||||
verify_container_exists:
|
||||
action: swift.head_container container=<% $.container %>
|
||||
on-success: verify_environment_exists
|
||||
on-error: verify_container_set_status_failed
|
||||
|
||||
verify_environment_exists:
|
||||
action: mistral.environments_get name=<% $.container %>
|
||||
on-success: get_or_generate_passwords
|
||||
on-error: verify_environment_set_status_failed
|
||||
|
||||
get_or_generate_passwords:
|
||||
action: tripleo.parameters.generate_passwords container=<% $.container %>
|
||||
on-success: get_passwords_set_status_success
|
||||
on-error: get_passwords_set_status_failed
|
||||
|
||||
get_passwords_set_status_success:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: SUCCESS
|
||||
message: <% task(get_or_generate_passwords).result %>
|
||||
|
||||
get_passwords_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(get_or_generate_passwords).result %>
|
||||
|
||||
verify_container_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(verify_container_exists).result %>
|
||||
|
||||
verify_environment_set_status_failed:
|
||||
on-success: notify_zaqar
|
||||
publish:
|
||||
status: FAILED
|
||||
message: <% task(verify_environment_exists).result %>
|
||||
|
||||
notify_zaqar:
|
||||
action: zaqar.queue_post
|
||||
input:
|
||||
queue_name: <% $.queue_name %>
|
||||
messages:
|
||||
body:
|
||||
type: tripleo.plan_management.v1.get_passwords
|
||||
payload:
|
||||
status: <% $.status %>
|
||||
message: <% $.message or '' %>
|
||||
execution: <% execution() %>
|
||||
|
||||
Reference in New Issue
Block a user