Skip to content

Commit 005363e

Browse files
committed
Keyword argument protocol changes - argspec version
1 parent b965f9c commit 005363e

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

src/ansible_runner/interface.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,35 @@ def init_runner(**kwargs):
133133
finished_callback=finished_callback)
134134

135135

136-
def run(**kwargs):
136+
def run(*,
137+
private_data_dir,
138+
ident,
139+
json_mode,
140+
playbook,
141+
module, module_args,
142+
host_pattern, inventory,
143+
role, roles_path,
144+
envvars, extravars,
145+
passwords,
146+
settings,
147+
ssh_key,
148+
cmdline,
149+
suppress_env_files,
150+
limit, forks, verbosity, quiet,
151+
artifact_dir, project_dir,
152+
rotate_artifacts,
153+
timeout,
154+
streamer,
155+
_input, _output,
156+
event_handler, status_handler, artifacts_handler,
157+
cancel_callback, finished_callback,
158+
process_isolation, process_isolation_executable, process_isolation_path,
159+
process_isolation_hide_paths, process_isolation_show_paths, process_isolation_ro_paths,
160+
container_image, container_volume_mounts, container_options,
161+
directory_isolation_base_path,
162+
fact_cache, fact_cache_type,
163+
omit_event_data, only_failed_event_data, check_job_event_data,
164+
):
137165
'''
138166
Run an Ansible Runner task in the foreground and return a Runner object when complete.
139167

src/ansible_runner/streaming.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations # allow newer type syntax until 3.10 is our minimum
22

33
import codecs
4+
import inspect
45
import json
56
import os
67
import stat
@@ -188,6 +189,17 @@ def run(self):
188189
return self.status, self.rc
189190

190191
if 'kwargs' in data:
192+
spec = inspect.getfullargspec(ansible_runner.interface.run)
193+
diff = set(data['kwargs']).difference(set(spec.kwonlyargs))
194+
if diff:
195+
self.status_handler(
196+
{
197+
'status': 'error',
198+
'job_explanation': f'Unhandled keyword argument(s) in transmitted data: {diff}'
199+
},
200+
None)
201+
self.finished_callback(None) # send eof line
202+
return self.status, self.rc
191203
self.job_kwargs = self.update_paths(data['kwargs'])
192204
elif 'zipfile' in data:
193205
try:

test/unit/test_streaming.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import io
12
import os
23

3-
from ansible_runner.streaming import Processor
4+
from ansible_runner.streaming import Processor, Transmitter, Worker
45

56

67
class TestProcessor:
@@ -14,3 +15,66 @@ def test_artifact_dir_with_int_ident(self, tmp_path):
1415
assert p.artifact_dir == os.path.join(kwargs['private_data_dir'],
1516
'artifacts',
1617
str(kwargs['ident']))
18+
19+
class TestTransmitter:
20+
21+
def test_job_arguments(self, tmp_path, project_fixtures):
22+
"""
23+
Test format of sending job arguments.
24+
"""
25+
transmit_dir = project_fixtures / 'debug'
26+
outgoing_buffer_file = tmp_path / 'buffer_out'
27+
outgoing_buffer_file.touch()
28+
29+
kwargs = {
30+
'playbook': 'debug.yml',
31+
'only_transmit_kwargs': True
32+
}
33+
34+
with outgoing_buffer_file.open('b+r') as outgoing_buffer:
35+
transmitter = Transmitter(
36+
_output=outgoing_buffer,
37+
private_data_dir=transmit_dir,
38+
**kwargs)
39+
transmitter.run()
40+
outgoing_buffer.seek(0)
41+
sent = outgoing_buffer.read()
42+
43+
expected = b'{"runner_version": "1.0.0", "kwargs": {"playbook": "debug.yml"}}\n{"eof": true}\n'
44+
assert sent == expected
45+
46+
def test_unhandled_argument(self, project_fixtures):
47+
transmit_dir = project_fixtures / 'debug'
48+
transmit_buffer = io.BytesIO()
49+
output_buffer = io.BytesIO()
50+
51+
for buffer in (transmit_buffer, output_buffer):
52+
buffer.name = 'foo'
53+
54+
kwargs = {
55+
'playbook': 'debug.yml',
56+
'oopsie': True,
57+
'only_transmit_kwargs': True
58+
}
59+
60+
status, rc = Transmitter(
61+
_output=transmit_buffer,
62+
private_data_dir=transmit_dir,
63+
**kwargs).run()
64+
65+
assert rc in (None, 0)
66+
assert status == 'unstarted'
67+
transmit_buffer.seek(0)
68+
69+
worker = Worker(_input=transmit_buffer,
70+
_output=output_buffer)
71+
72+
status, rc = worker.run()
73+
74+
assert status == 'error'
75+
assert rc in (None, 0)
76+
77+
output_buffer.seek(0)
78+
output = output_buffer.read()
79+
80+
assert output == b'{"status": "error", "job_explanation": "Unhandled keyword argument(s) in transmitted data: {\'oopsie\'}"}\n{"eof": true}\n'

0 commit comments

Comments
 (0)