Merge "Add support of extra variables."

This commit is contained in:
Zuul
2019-03-04 12:37:02 +00:00
committed by Gerrit Code Review
9 changed files with 219 additions and 16 deletions

View File

@@ -1440,3 +1440,73 @@ class TestAnsibleSymlink(TestCase):
def test_ansible_symlink_not_needed(self, mock_path, mock_cmd):
utils.ansible_symlink()
mock_cmd.assert_not_called()
class TestParseExtraVars(TestCase):
def test_simple_case_text_format(self):
input_parameter = ['key1=val1', 'key2=val2 key3=val3']
expected = {
'key1': 'val1',
'key2': 'val2',
'key3': 'val3'
}
result = utils.parse_extra_vars(input_parameter)
self.assertEqual(result, expected)
def test_simple_case_json_format(self):
input_parameter = ['{"key1": "val1", "key2": "val2"}']
expected = {
'key1': 'val1',
'key2': 'val2'
}
result = utils.parse_extra_vars(input_parameter)
self.assertEqual(result, expected)
def test_multiple_format(self):
input_parameter = [
'key1=val1', 'key2=val2 key3=val3',
'{"key4": "val4", "key5": "val5"}']
expected = {
'key1': 'val1',
'key2': 'val2',
'key3': 'val3',
'key4': 'val4',
'key5': 'val5'
}
result = utils.parse_extra_vars(input_parameter)
self.assertEqual(result, expected)
def test_same_key(self):
input_parameter = [
'key1=val1', 'key2=val2 key3=val3',
'{"key1": "other_value", "key5": "val5"}']
expected = {
'key1': 'other_value',
'key2': 'val2',
'key3': 'val3',
'key5': 'val5'
}
result = utils.parse_extra_vars(input_parameter)
self.assertEqual(result, expected)
def test_with_multiple_space(self):
input_parameter = ['key1=val1', ' key2=val2 key3=val3 ']
expected = {
'key1': 'val1',
'key2': 'val2',
'key3': 'val3'
}
result = utils.parse_extra_vars(input_parameter)
self.assertEqual(result, expected)
def test_invalid_string(self):
input_parameter = [
'key1=val1', 'key2=val2 key3=val3',
'{"key1": "other_value", "key5": "val5']
self.assertRaises(
ValueError, utils.parse_extra_vars, input_parameter)
def test_invalid_format(self):
input_parameter = ['key1 val1']
self.assertRaises(
ValueError, utils.parse_extra_vars, input_parameter)

View File

@@ -61,5 +61,38 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
node_user='tripleo-admin',
tags='ceph',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars={}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_update_with_user_and_extra_vars(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin',
'--extra-vars', 'key1=val1',
'--extra-vars', 'key2=val2']
verifylist = [
('ssh_user', 'tripleo-admin'),
('extra_vars', ['key1=val1', 'key2=val2'])
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
nodes='all',
inventory_file=mock_open().read(),
playbook='external_update_steps_playbook.yaml',
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1,
extra_vars={'key1': 'val1', 'key2': 'val2'}
)

View File

@@ -61,5 +61,38 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
node_user='tripleo-admin',
tags='ceph',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars={}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_with_user_and_extra_vars(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin',
'--extra-vars', 'key1=val1',
'--extra-vars', 'key2=val2']
verifylist = [
('ssh_user', 'tripleo-admin'),
('extra_vars', ['key1=val1', 'key2=val2'])
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
nodes='all',
inventory_file=mock_open().read(),
playbook='external_upgrade_steps_playbook.yaml',
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1,
extra_vars={'key1': 'val1', 'key2': 'val2'}
)

View File

@@ -169,7 +169,8 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
node_user='heat-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -195,7 +196,8 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
node_user='my-user',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',

View File

@@ -151,7 +151,8 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -182,7 +183,8 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -212,7 +214,8 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',

View File

@@ -171,7 +171,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -204,7 +205,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
node_user='tripleo-admin',
tags='',
skip_tags='validation',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -238,6 +240,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
tags='validation',
skip_tags='',
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -268,7 +271,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -299,7 +303,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@@ -332,7 +337,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
node_user='tripleo-admin',
tags='',
skip_tags='pre-upgrade,validation',
verbosity=1
verbosity=1,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',

View File

@@ -1042,7 +1042,7 @@ def process_multiple_environments(created_env_files, tht_root,
def run_update_ansible_action(log, clients, nodes, inventory, playbook,
all_playbooks, action, ssh_user, tags='',
skip_tags='', verbosity='1'):
skip_tags='', verbosity='1', extra_vars=None):
playbooks = [playbook]
if playbook == "all":
playbooks = all_playbooks
@@ -1050,7 +1050,51 @@ def run_update_ansible_action(log, clients, nodes, inventory, playbook,
log.debug("Running ansible playbook %s " % book)
action.update_ansible(clients, nodes=nodes, inventory_file=inventory,
playbook=book, node_user=ssh_user, tags=tags,
skip_tags=skip_tags, verbosity=verbosity)
skip_tags=skip_tags, verbosity=verbosity,
extra_vars=extra_vars)
def parse_extra_vars(extra_var_strings):
"""Parses extra variables like Ansible would.
Each element in extra_var_strings is like the raw value of -e
parameter of ansible-playbook command. It can either be very
simple 'key=val key2=val2' format or it can be '{ ... }'
representing a YAML/JSON object.
The 'key=val key2=val2' format gets processed as if it was
'{"key": "val", "key2": "val2"}' object, and all YAML/JSON objects
get shallow-merged together in the order as they appear in
extra_var_strings, latter objects taking precedence over earlier
ones.
:param extra_var_strings: unparsed value(s) of -e parameter(s)
:type extra_var_strings: list of strings
:returns dict representing a merged object of all extra vars
"""
result = {}
for extra_var_string in extra_var_strings:
invalid_yaml = False
try:
parse_vars = yaml.safe_load(extra_var_string)
except yaml.YAMLError:
invalid_yaml = True
if invalid_yaml or not isinstance(parse_vars, dict):
try:
parse_vars = dict(
item.split('=') for item in extra_var_string.split())
except ValueError:
raise ValueError(
'Invalid format for {extra_var_string}'.format(
extra_var_string=extra_var_string))
result.update(parse_vars)
return result
def prepend_environment(environment_files, templates_dir, environment):

View File

@@ -79,6 +79,10 @@ class ExternalUpdateRun(command.Command):
'(default=Env: OVERCLOUD_STACK_NAME)'),
default=utils.env('OVERCLOUD_STACK_NAME',
default='overcloud'))
parser.add_argument(
'-e', '--extra-vars', dest='extra_vars', action='append',
help='Set additional variables as key=value or yaml/json',
default=[])
return parser
@@ -93,11 +97,13 @@ class ExternalUpdateRun(command.Command):
parsed_args.static_inventory, parsed_args.ssh_user, stack)
limit_hosts = 'all'
playbook = 'all'
extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars)
oooutils.run_update_ansible_action(
self.log, clients, limit_hosts, inventory, playbook,
constants.EXTERNAL_UPDATE_PLAYBOOKS,
package_update, parsed_args.ssh_user,
tags=parsed_args.tags, skip_tags=parsed_args.skip_tags,
verbosity=verbosity)
verbosity=verbosity, extra_vars=extra_vars)
self.log.info("Completed Overcloud External Update Run.")

View File

@@ -79,6 +79,10 @@ class ExternalUpgradeRun(command.Command):
'(default=Env: OVERCLOUD_STACK_NAME)'),
default=utils.env('OVERCLOUD_STACK_NAME',
default='overcloud'))
parser.add_argument(
'-e', '--extra-vars', dest='extra_vars', action='append',
help='Set additional variables as key=value or yaml/json',
default=[])
return parser
@@ -93,11 +97,13 @@ class ExternalUpgradeRun(command.Command):
parsed_args.static_inventory, parsed_args.ssh_user, stack)
limit_hosts = 'all'
playbook = 'all'
extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars)
oooutils.run_update_ansible_action(
self.log, clients, limit_hosts, inventory, playbook,
constants.EXTERNAL_UPGRADE_PLAYBOOKS,
package_update, parsed_args.ssh_user,
tags=parsed_args.tags, skip_tags=parsed_args.skip_tags,
verbosity=verbosity)
verbosity=verbosity, extra_vars=extra_vars)
self.log.info("Completed Overcloud External Upgrade Run.")