Merge "Add new interface to run arbitrary playbooks from a plan"

This commit is contained in:
Zuul 2020-03-31 04:00:36 +00:00 committed by Gerrit Code Review
commit 1b38e856e0
3 changed files with 145 additions and 1 deletions

View File

@ -0,0 +1,26 @@
---
features:
- |
A new interface has been created allowing deployers to run arbitrary
playbooks which are defined within a deployment plan. This interface is
being created to replace the existing Mistral interface, which is largely
used for HCI and NFV use cases. The interface will now process playbooks
when they're defined within a plan under the `playbook_parameters` key.
Playbook entries can be defined with, and without the base path. If no base
path is defined within the entry, the interface will fall back to the
constant tripleo playbook path, `/usr/share/ansible/tripleo-playbooks`.
Options fined within a playbook entry will be passed into the playbook at
runtime using extra-vars.
* Interface usage example
.. code-block:: yaml
playbook_parameters:
sample-playbook-0.yaml:
x: 1
y: a
/path/to/sample-playbook-1.yaml:
x: a
y: 1

View File

@ -111,6 +111,86 @@ class TestParameterWorkflows(utils.TestCommand):
'user_inputs': {
'num_phy_cores_per_numa_node_for_pmd': 2}})
@mock.patch('yaml.safe_load')
@mock.patch("six.moves.builtins.open")
@mock.patch('tripleoclient.utils.run_ansible_playbook', autospec=True)
@mock.patch('tripleoclient.utils.get_tripleo_ansible_inventory',
autospec=True)
def test_invoke_plan_env_workflows_single_playbook(self,
mock_inventory,
mock_playbook,
mock_open,
mock_safe_load):
plan_env_data = {
'name': 'overcloud',
'playbook_parameters': {
'sample-playbook-1.yaml': {
'num_phy_cores_per_numa_node_for_pmd': 2
}
}
}
mock_safe_load.return_value = plan_env_data
parameters.invoke_plan_env_workflows(
self.app.client_manager,
'overcloud',
'the-plan-environment.yaml'
)
calls = [
mock.call(
playbook='sample-playbook-1.yaml',
inventory=mock.ANY,
workdir=mock.ANY,
playbook_dir=mock.ANY,
extra_vars={'num_phy_cores_per_numa_node_for_pmd': 2}
)
]
mock_playbook.assert_has_calls(calls, any_order=True)
@mock.patch('yaml.safe_load')
@mock.patch("six.moves.builtins.open")
@mock.patch('tripleoclient.utils.run_ansible_playbook', autospec=True)
@mock.patch('tripleoclient.utils.get_tripleo_ansible_inventory',
autospec=True)
def test_invoke_plan_env_workflows_multi_playbook(self,
mock_inventory,
mock_playbook,
mock_open,
mock_safe_load):
plan_env_data = {
'name': 'overcloud',
'playbook_parameters': {
'sample-playbook-1.yaml': {
'num_phy_cores_per_numa_node_for_pmd': 2
},
'/playbook/dir-1/sample-playbook-2.yaml': {
'some_opt': 0
}
}
}
mock_safe_load.return_value = plan_env_data
parameters.invoke_plan_env_workflows(
self.app.client_manager,
'overcloud',
'the-plan-environment.yaml'
)
calls = [
mock.call(
playbook='sample-playbook-1.yaml',
inventory=mock.ANY,
workdir=mock.ANY,
playbook_dir=mock.ANY,
extra_vars={'num_phy_cores_per_numa_node_for_pmd': 2}
),
mock.call(
playbook='sample-playbook-2.yaml',
inventory=mock.ANY,
workdir=mock.ANY,
playbook_dir='/playbook/dir-1',
extra_vars={'some_opt': 0}
)
]
mock_playbook.assert_has_calls(calls, any_order=True)
@mock.patch('yaml.safe_load')
@mock.patch("six.moves.builtins.open")
def test_invoke_plan_env_workflow_failed(self, mock_open,

View File

@ -11,13 +11,16 @@
# under the License.
import logging
import os
import re
import yaml
from tripleo_common.utils import stack_parameters as stk_parameters
from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS
from tripleoclient.constants import UNUSED_PARAMETER_EXCLUDES_RE
from tripleoclient import exceptions
from tripleoclient import utils
from tripleoclient.workflows import base
from tripleoclient.workflows import roles
@ -40,7 +43,42 @@ def invoke_plan_env_workflows(clients, stack_name, plan_env_file):
raise exceptions.PlanEnvWorkflowError('File (%s) is not found: '
'%s' % (plan_env_file, exc))
if plan_env_data and "workflow_parameters" in plan_env_data:
if plan_env_data and "playbook_parameters" in plan_env_data:
static_inventory = utils.get_tripleo_ansible_inventory(
ssh_user='heat-admin',
stack=stack_name,
undercloud_connection='local',
return_inventory_file_path=True
)
with utils.TempDirs() as tmp:
for pb, pb_vars in plan_env_data["playbook_parameters"].items():
print('Invoking playbook ({}) specified in plan-environment'
' file'.format(pb))
LOG.debug(
'Running playbook "{}" with the'
' following options {}.'.format(
pb,
pb_vars
)
)
playbook_dir = os.path.dirname(pb)
if not playbook_dir:
playbook_dir = ANSIBLE_TRIPLEO_PLAYBOOKS
utils.run_ansible_playbook(
playbook=os.path.basename(pb),
inventory=static_inventory,
workdir=tmp,
playbook_dir=playbook_dir,
extra_vars=pb_vars
)
# NOTE(cloudnull): Remove this when mistral is gone.
elif plan_env_data and "workflow_parameters" in plan_env_data:
LOG.warning(
'The workflow_parameters interface is deprecated, begin using'
' playbook_parameters instead.'
)
for wf_name, wf_inputs in plan_env_data["workflow_parameters"].items():
print('Invoking workflow (%s) specified in plan-environment '
'file' % wf_name)