Merge "Quote and escape extra vars passed to ansible"

This commit is contained in:
Zuul 2019-01-04 16:54:04 +00:00 committed by Gerrit Code Review
commit 45c4e09f9f
7 changed files with 45 additions and 2 deletions

View File

@ -133,9 +133,13 @@ def build_args(parsed_args, playbooks,
cmd += ["-e", "@%s" % vars_file]
if parsed_args.extra_vars:
for extra_var in parsed_args.extra_vars:
# Don't quote or escape variables passed via the kayobe -e CLI
# argument, to match Ansible's behaviour.
cmd += ["-e", extra_var]
if extra_vars:
for extra_var_name, extra_var_value in extra_vars.items():
# Quote and escape variables originating within the python CLI.
extra_var_value = utils.quote_and_escape(extra_var_value)
cmd += ["-e", "%s=%s" % (extra_var_name, extra_var_value)]
if parsed_args.become:
cmd += ["--become"]

View File

@ -122,9 +122,13 @@ def build_args(parsed_args, command, inventory_filename, extra_vars=None,
os.path.join(parsed_args.kolla_config_path, "passwords.yml")]
if parsed_args.kolla_extra_vars:
for extra_var in parsed_args.kolla_extra_vars:
# Don't quote or escape variables passed via the kayobe -e CLI
# argument, to match Ansible's behaviour.
cmd += ["-e", extra_var]
if extra_vars:
for extra_var_name, extra_var_value in extra_vars.items():
# Quote and escape variables originating within the python CLI.
extra_var_value = utils.quote_and_escape(extra_var_value)
cmd += ["-e", "%s=%s" % (extra_var_name, extra_var_value)]
if parsed_args.kolla_limit or limit:
limits = [l for l in [parsed_args.kolla_limit, limit] if l]

View File

@ -251,7 +251,7 @@ class TestCase(unittest.TestCase):
"-e", "@/etc/kayobe/vars-file1.yml",
"-e", "@/etc/kayobe/vars-file2.yaml",
"-e", "ev_name1=ev_value1",
"-e", "ev_name2=ev_value2",
"-e", "ev_name2='ev_value2'",
"--check",
"--limit", "group1:host1:&group2:host2",
"--tags", "tag1,tag2,tag3,tag4",

View File

@ -190,7 +190,7 @@ class TestCase(unittest.TestCase):
"-v",
"--inventory", "/etc/kolla/inventory/overcloud",
"-e", "ev_name1=ev_value1",
"-e", "ev_name2=ev_value2",
"-e", "ev_name2='ev_value2'",
"--tags", "tag1,tag2,tag3,tag4",
"--arg1", "--arg2",
]

View File

@ -96,3 +96,16 @@ key2: value2
mock_call.side_effect = subprocess.CalledProcessError(1, "command")
self.assertRaises(subprocess.CalledProcessError, utils.run_command,
["command", "to", "run"])
def test_quote_and_escape_no_whitespace(self):
self.assertEqual("'foo'", utils.quote_and_escape("foo"))
def test_quote_and_escape_whitespace(self):
self.assertEqual("'foo bar'", utils.quote_and_escape("foo bar"))
def test_quote_and_escape_whitespace_with_quotes(self):
self.assertEqual("'foo '\\''bar'\\'''",
utils.quote_and_escape("foo 'bar'"))
def test_quote_and_escape_non_string(self):
self.assertEqual(True, utils.quote_and_escape(True))

View File

@ -116,3 +116,19 @@ def run_command(cmd, quiet=False, check_output=False, **kwargs):
return subprocess.check_output(cmd, **kwargs)
else:
subprocess.check_call(cmd, **kwargs)
def quote_and_escape(value):
"""Quote and escape a string.
Adds enclosing single quotes to the string passed, and escapes single
quotes within the string using backslashes. This is useful for passing
'extra vars' to Ansible. Without this, Ansible only uses the part of the
string up to the first whitespace.
:param value: the string to quote and escape.
:returns: the quoted and escaped string.
"""
if not isinstance(value, six.string_types):
return value
return "'" + value.replace("'", "'\\''") + "'"

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixes an issue where CLI arguments containing whitespace that are passed to
Ansible needed to be quoted. See `Story 2004379
<https://storyboard.openstack.org/#!/story/2004379>`__ for details.