Skip to content

Commit 5c47f33

Browse files
authored
Fix missing ansible cli extra_vars (#154)
1 parent bb69c0e commit 5c47f33

File tree

6 files changed

+54
-11
lines changed

6 files changed

+54
-11
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ It can be used to add a layer of templating (using jinja2) on top of Terraform f
4242
* [Terraform landscape](#terraform-landscape)
4343
* [SSH](#ssh)
4444
* [SSHPass](#sshpass)
45+
* [Balabit SCB](#scb)
4546
* [Play](#play)
4647
* [Run command](#run-command)
4748
* [Sync files](#sync-files)

src/ops/cli/config.py

+37-6
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,22 @@
88
# OF ANY KIND, either express or implied. See the License for the specific language
99
# governing permissions and limitations under the License.
1010

11-
import collections
1211
import os
13-
1412
import yaml
1513

1614
from ansible.module_utils.common.collections import ImmutableDict
1715
from ansible.parsing.dataloader import DataLoader
18-
from ansible.plugins.loader import PluginLoader
1916
from ansible.template import Templar
20-
from ansible.utils.vars import load_extra_vars
17+
from ansible.utils.vars import combine_vars
2118
from ansible.vars.manager import VariableManager
2219
from ops.cli import display
2320
from ansible import constants as C
2421
from ansible import context
2522
import logging
23+
from ansible.errors import AnsibleOptionsError
24+
from ansible.module_utils._text import to_text
25+
from ansible.parsing.splitter import parse_kv
26+
from collections.abc import MutableMapping
2627

2728
logger = logging.getLogger(__name__)
2829

@@ -34,6 +35,38 @@ def get_cluster_name(cluster_config_path):
3435
'/')[-1].replace('.yaml', '').replace('.yml', '')
3536

3637

38+
def load_extra_vars(loader):
39+
"""
40+
Overriding Ansible function using version before slight var loading optimization
41+
in order to avoid caching issues https://github.com/ansible/ansible/pull/78835/files
42+
"""
43+
44+
extra_vars = {}
45+
for extra_vars_opt in context.CLIARGS.get('extra_vars', tuple()):
46+
data = None
47+
extra_vars_opt = to_text(extra_vars_opt, errors='surrogate_or_strict')
48+
if extra_vars_opt is None or not extra_vars_opt:
49+
continue
50+
51+
if extra_vars_opt.startswith(u"@"):
52+
# Argument is a YAML file (JSON is a subset of YAML)
53+
data = loader.load_from_file(extra_vars_opt[1:])
54+
elif extra_vars_opt[0] in [u'/', u'.']:
55+
raise AnsibleOptionsError("Please prepend extra_vars filename '%s' with '@'" % extra_vars_opt)
56+
elif extra_vars_opt[0] in [u'[', u'{']:
57+
# Arguments as YAML
58+
data = loader.load(extra_vars_opt)
59+
else:
60+
# Arguments as Key-value
61+
data = parse_kv(extra_vars_opt)
62+
63+
if isinstance(data, MutableMapping):
64+
extra_vars = combine_vars(extra_vars, data)
65+
else:
66+
raise AnsibleOptionsError("Invalid extra vars data supplied. '%s' could not be made into a dictionary" % extra_vars_opt)
67+
return extra_vars
68+
69+
3770
class ClusterConfig(object):
3871
def __init__(self, cluster_config_generator,
3972
ops_config, cluster_config_path):
@@ -119,7 +152,6 @@ def get(self):
119152
context_cliargs['extra_vars'] = tuple(extra_vars)
120153

121154
context.CLIARGS = ImmutableDict(context_cliargs)
122-
setattr(load_extra_vars, 'extra_vars', {})
123155
variable_manager._extra_vars = load_extra_vars(
124156
loader=data_loader)
125157

@@ -159,7 +191,6 @@ def get(self):
159191
context_cliargs['extra_vars'] = tuple(extra_vars)
160192

161193
context.CLIARGS = ImmutableDict(context_cliargs)
162-
setattr(load_extra_vars, 'extra_vars', {})
163194
variable_manager._extra_vars = load_extra_vars(
164195
loader=data_loader)
165196

src/ops/cli/ssh.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def run(self, args, extra_args):
286286
if args.proxy:
287287
if scb_enabled:
288288
proxy_port = args.local or SshConfigGenerator.generate_ssh_scb_proxy_port(
289-
self.ansible_inventory.generated_path.rstrip("/inventory"),
289+
self.ansible_inventory.generated_path.removesuffix("/inventory"),
290290
args.auto_scb_port,
291291
scb_proxy_port
292292
)

src/ops/inventory/sshconfig.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def generate_ssh_scb_config(ssh_config_tpl_path, scb_proxy_port):
9090
ssh_config_content = ssh_config_template.format(
9191
scb_proxy_port=scb_proxy_port
9292
)
93-
ssh_config_path = ssh_config_tpl_path.rstrip("_tpl")
93+
ssh_config_path = ssh_config_tpl_path.removesuffix("_tpl")
9494
with open(ssh_config_path, 'w') as f:
9595
f.write(ssh_config_content)
9696
os.fchmod(f.fileno(), 0o644)
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
- hosts: web
22
gather_facts: no
3+
vars:
4+
test_cmd_var: false
5+
test_cmd_bool_var: True
36
tasks:
47
- debug: msg="{{ 'filter_this' | my_filter }}"
58
- my_module:
69
set_facts:
710
the_module_works: yep
8-
- debug: var=the_module_works
11+
- debug: var=the_module_works
12+
- debug: msg="test_cmd_var = {{ test_cmd_var | bool }}"
13+
- debug: msg="test_cmd_bool_var = {{ test_cmd_bool_var }}"

tests/e2e/test_playbook.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,26 @@ def _app(args):
3131
def test_loading_of_modules_and_extensions(capsys, app):
3232
root_dir = current_dir + '/fixture/ansible'
3333
container = app(['-vv', '--root-dir', root_dir, 'clusters/test.yaml', 'play',
34-
'playbooks/play_module.yaml'])
34+
'playbooks/play_module.yaml', '--', '-e', 'test_cmd_var=true',
35+
'-e', '\'{"test_cmd_bool_var": false}\''])
3536
command = container.run()
3637
code = container.execute(command, pass_trough=False)
3738
out, err = capsys.readouterr()
3839
display(out, color='gray')
3940
display(err, color='red')
4041
assert code is 0
41-
4242
# the filter plugins work
4343
assert '"msg": "filtered: filter_this"' in out
4444

4545
# custom modules are interpreted
4646
assert '"the_module_works": "yep"' in out
4747

48+
# cmd extra_vars override playbook vars
49+
assert '"test_cmd_var = True"' in out
50+
51+
# cmd extra_vars bool var
52+
assert '"test_cmd_bool_var = False"' in out
53+
4854
# cluster is present as a variable in the command line
4955
assert '-e cluster=test' in command['command']
5056

0 commit comments

Comments
 (0)