Skip to content

Commit f9e9e65

Browse files
AndreMarcel99André Marcel Gutiérrez Benítezrexemin
authored
[Enabler][zos_operator] Update module interface (#2230)
* Test * Fix test xos operator * Fix tab * Fix tab * Fix tab * Fix tab * Fix tab * Fix tab * Fix tab * Fix tab * Add fragment * Fix sanity * Update changelogs/fragments/2230_zos_operator_interface_update.yml Co-authored-by: Alex Moreno <[email protected]> * Update changelogs/fragments/2230_zos_operator_interface_update.yml Co-authored-by: Alex Moreno <[email protected]> * Update plugins/modules/zos_operator.py Co-authored-by: Alex Moreno <[email protected]> * Update plugins/modules/zos_operator.py Co-authored-by: Alex Moreno <[email protected]> * Update plugins/modules/zos_operator.py Co-authored-by: Alex Moreno <[email protected]> * Fix validation * Modify operation test --------- Co-authored-by: André Marcel Gutiérrez Benítez <[email protected]> Co-authored-by: Alex Moreno <[email protected]>
1 parent 73190da commit f9e9e65

File tree

3 files changed

+140
-36
lines changed

3 files changed

+140
-36
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
breaking_changes:
2+
- zos_operator - Option ``wait_time_s`` is being deprecated in favor of ``wait_time``. New option ``time_unit`` is being added to select
3+
seconds or centiseconds. New return value ``time_unit`` is being added. Return value ``wait_time_s`` is being deprecated in favor of ``wait_time``.
4+
(https://github.com/ansible-collections/ibm_zos_core/pull/2230).

plugins/modules/zos_operator.py

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,26 @@
5050
type: bool
5151
required: false
5252
default: false
53-
wait_time_s:
53+
wait_time:
5454
description:
5555
- Set maximum time in seconds to wait for the commands to execute.
5656
- When set to 0, the system default is used.
5757
- This option is helpful on a busy system requiring more time to execute
5858
commands.
5959
- Setting I(wait) can instruct if execution should wait the
60-
full I(wait_time_s).
60+
full I(wait_time).
6161
type: int
6262
required: false
6363
default: 1
64+
time_unit:
65+
description:
66+
- Set the C(wait_time) unit of time, which can be C(s) (seconds) or C(cs) (centiseconds).
67+
type: str
68+
required: false
69+
default: s
70+
choices:
71+
- s
72+
- cs
6473
case_sensitive:
6574
description:
6675
- If C(true), the command will not be converted to uppercase before
@@ -103,11 +112,17 @@
103112
- name: Execute operator command to show jobs, always waiting 5 seconds for response
104113
zos_operator:
105114
cmd: 'd a,all'
106-
wait_time_s: 5
115+
wait_time: 5
107116
108117
- name: Display the system symbols and associated substitution texts.
109118
zos_operator:
110119
cmd: 'D SYMBOLS'
120+
121+
- name: Execute an operator command to show device status and allocation wait 10 centiseconds.
122+
zos_operator:
123+
cmd: 'd u'
124+
wait_time : 10
125+
time_unit : 'cs'
111126
"""
112127

113128
RETURN = r"""
@@ -125,16 +140,22 @@
125140
sample: d u,all
126141
elapsed:
127142
description:
128-
The number of seconds that elapsed waiting for the command to complete.
143+
The number of seconds or centiseconds that elapsed waiting for the command to complete.
129144
returned: always
130145
type: float
131146
sample: 51.53
132-
wait_time_s:
147+
wait_time:
133148
description:
134-
The maximum time in seconds to wait for the commands to execute.
149+
The maximum time in the time_unit set to wait for the commands to execute.
135150
returned: always
136151
type: int
137152
sample: 5
153+
time_unit:
154+
description:
155+
The time unit set for wait_time.
156+
returned: always
157+
type: str
158+
sample: s
138159
content:
139160
description:
140161
The resulting text from the command submitted.
@@ -200,14 +221,16 @@
200221
opercmd = ZOAUImportError(traceback.format_exc())
201222

202223

203-
def execute_command(operator_cmd, timeout_s=1, preserve=False, *args, **kwargs):
224+
def execute_command(operator_cmd, time_unit, timeout=1, preserve=False, *args, **kwargs):
204225
"""
205226
Executes an operator command.
206227
207228
Parameters
208229
----------
209230
operator_cmd : str
210231
Command to execute.
232+
time_unit : str
233+
Unit of time to wait of execution of the command.
211234
timeout : int
212235
Time until it stops whether it finished or not.
213236
preserve : bool
@@ -223,15 +246,20 @@ def execute_command(operator_cmd, timeout_s=1, preserve=False, *args, **kwargs):
223246
Return code, standard output, standard error and time elapsed from start to finish.
224247
"""
225248
# as of ZOAU v1.3.0, timeout is measured in centiseconds, therefore:
226-
timeout_c = 100 * timeout_s
249+
if time_unit == "s":
250+
timeout = 100 * timeout
227251

228252
start = timer()
229-
response = opercmd.execute(operator_cmd, timeout=timeout_c, preserve=preserve, *args, **kwargs)
253+
response = opercmd.execute(operator_cmd, timeout=timeout, preserve=preserve, *args, **kwargs)
230254
end = timer()
231255
rc = response.rc
232256
stdout = response.stdout_response
233257
stderr = response.stderr_response
234-
elapsed = round(end - start, 2)
258+
if time_unit == "cs":
259+
elapsed = round((end - start) * 100, 2)
260+
else:
261+
elapsed = round(end - start, 2)
262+
235263
return rc, stdout, stderr, elapsed
236264

237265

@@ -252,7 +280,8 @@ def run_module():
252280
module_args = dict(
253281
cmd=dict(type="str", required=True),
254282
verbose=dict(type="bool", required=False, default=False),
255-
wait_time_s=dict(type="int", required=False, default=1),
283+
wait_time=dict(type="int", required=False, default=1),
284+
time_unit=dict(type="str", required=False, choices=["s", "cs"], default="s"),
256285
case_sensitive=dict(type="bool", required=False, default=False),
257286
)
258287

@@ -294,7 +323,8 @@ def run_module():
294323
# call is returned from run_operator_command, specifying what was run.
295324
# result["cmd"] = new_params.get("cmd")
296325
result["cmd"] = rc_message.get("call")
297-
result["wait_time_s"] = new_params.get("wait_time_s")
326+
result["wait_time"] = new_params.get("wait_time")
327+
result["time_unit"] = new_params.get("time_unit")
298328
result["changed"] = False
299329

300330
# rc=0, something succeeded (the calling script ran),
@@ -309,7 +339,8 @@ def run_module():
309339
module.fail_json(msg=("A non-zero return code was received : {0}. Review the response for more details.").format(result["rc"]),
310340
cmd=result["cmd"],
311341
elapsed_time=result["elapsed"],
312-
wait_time_s=result["wait_time_s"],
342+
wait_time=result["wait_time"],
343+
time_unit=result["time_unit"],
313344
stderr=str(error) if error is not None else result["content"],
314345
stderr_lines=str(error).splitlines() if error is not None else result["content"],
315346
changed=result["changed"],)
@@ -338,9 +369,10 @@ def parse_params(params):
338369
"""
339370
arg_defs = dict(
340371
cmd=dict(arg_type="str", required=True),
341-
verbose=dict(arg_type="bool", required=False),
342-
wait_time_s=dict(arg_type="int", required=False),
343-
case_sensitive=dict(arg_type="bool", required=False),
372+
verbose=dict(arg_type="bool", required=False, default=False),
373+
wait_time=dict(arg_type="int", required=False, default=1),
374+
time_unit=dict(type="str", required=False, choices=["s", "cs"], default="s"),
375+
case_sensitive=dict(arg_type="bool", required=False, default=False),
344376
)
345377
parser = BetterArgParser(arg_defs)
346378
new_params = parser.parse_args(params)
@@ -369,7 +401,8 @@ def run_operator_command(params):
369401
kwargs.update({"verbose": True})
370402
kwargs.update({"debug": True})
371403

372-
wait_s = params.get("wait_time_s")
404+
wait_time = params.get("wait_time")
405+
time_unit = params.get("time_unit")
373406
cmdtxt = params.get("cmd")
374407
preserve = params.get("case_sensitive")
375408

@@ -381,7 +414,7 @@ def run_operator_command(params):
381414
kwargs.update({"wait": True})
382415

383416
args = []
384-
rc, stdout, stderr, elapsed = execute_command(cmdtxt, timeout_s=wait_s, preserve=preserve, *args, **kwargs)
417+
rc, stdout, stderr, elapsed = execute_command(cmdtxt, time_unit=time_unit, timeout=wait_time, preserve=preserve, *args, **kwargs)
385418

386419
if rc > 0:
387420
message = "\nOut: {0}\nErr: {1}\nRan: {2}".format(stdout, stderr, cmdtxt)

tests/functional/modules/test_zos_operator_func.py

Lines changed: 85 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
- name: zos_operator
4646
zos_operator:
4747
cmd: 'd a,all'
48-
wait_time_s: 3
48+
wait_time: 3
4949
verbose: true
5050
register: output
5151
@@ -77,22 +77,42 @@ def test_zos_operator_various_command(ansible_zos_module):
7777
hosts = ansible_zos_module
7878
results = hosts.all.zos_operator(cmd=command)
7979
for result in results.contacted.values():
80-
assert result["rc"] == expected_rc
80+
print(result)
81+
assert result.get("rc") == expected_rc
8182
assert result.get("changed") is changed
83+
assert result.get("msg", False) is False
84+
assert result.get("cmd") == command
85+
assert result.get("elapsed") is not None
86+
assert result.get("wait_time") is not None
87+
assert result.get("time_unit") == "s"
88+
assert result.get("content") is not None
8289

8390

8491
def test_zos_operator_invalid_command(ansible_zos_module):
8592
hosts = ansible_zos_module
8693
results = hosts.all.zos_operator(cmd="invalid,command", verbose=False)
8794
for result in results.contacted.values():
95+
print(result)
8896
assert result.get("changed") is True
97+
assert result.get("rc") == 0
98+
assert result.get("cmd") is not None
99+
assert result.get("elapsed") is not None
100+
assert result.get("wait_time") is not None
101+
assert result.get("time_unit") == "s"
102+
assert result.get("content") is not None
89103

90104

91105
def test_zos_operator_invalid_command_to_ensure_transparency(ansible_zos_module):
92106
hosts = ansible_zos_module
93107
results = hosts.all.zos_operator(cmd="DUMP COMM=('ERROR DUMP')", verbose=False)
94108
for result in results.contacted.values():
95109
assert result.get("changed") is True
110+
assert result.get("rc") == 0
111+
assert result.get("cmd") is not None
112+
assert result.get("elapsed") is not None
113+
assert result.get("wait_time") is not None
114+
assert result.get("time_unit") == "s"
115+
assert result.get("content") is not None
96116
transparency = False
97117
if any('DUMP COMMAND' in str for str in result.get("content")):
98118
transparency = True
@@ -103,17 +123,27 @@ def test_zos_operator_positive_path(ansible_zos_module):
103123
hosts = ansible_zos_module
104124
results = hosts.all.zos_operator(cmd="d u,all", verbose=False)
105125
for result in results.contacted.values():
106-
assert result["rc"] == 0
126+
assert result.get("rc") == 0
107127
assert result.get("changed") is True
128+
assert result.get("msg", False) is False
129+
assert result.get("cmd") is not None
130+
assert result.get("elapsed") is not None
131+
assert result.get("wait_time") is not None
132+
assert result.get("time_unit") == "s"
108133
assert result.get("content") is not None
109134

110135

111136
def test_zos_operator_positive_path_verbose(ansible_zos_module):
112137
hosts = ansible_zos_module
113138
results = hosts.all.zos_operator(cmd="d u,all", verbose=True)
114139
for result in results.contacted.values():
115-
assert result["rc"] == 0
140+
assert result.get("rc") == 0
116141
assert result.get("changed") is True
142+
assert result.get("msg", False) is False
143+
assert result.get("cmd") is not None
144+
assert result.get("elapsed") is not None
145+
assert result.get("wait_time") is not None
146+
assert result.get("time_unit") == "s"
117147
assert result.get("content") is not None
118148
# Traverse the content list for a known verbose keyword and track state
119149
is_verbose = False
@@ -127,45 +157,55 @@ def test_zos_operator_positive_verbose_with_full_delay(ansible_zos_module):
127157
hosts = ansible_zos_module
128158
wait_time = 10
129159
results = hosts.all.zos_operator(
130-
cmd="RO *ALL,LOG 'dummy syslog message'", verbose=True, wait_time_s=wait_time
160+
cmd="RO *ALL,LOG 'dummy syslog message'", verbose=True, wait_time=wait_time
131161
)
132162

133163
for result in results.contacted.values():
134-
assert result["rc"] == 0
164+
assert result.get("rc") == 0
135165
assert result.get("changed") is True
136-
assert result.get("content") is not None
166+
assert result.get("msg", False) is False
167+
assert result.get("cmd") is not None
137168
assert result.get("elapsed") > wait_time
169+
assert result.get("wait_time") is not None
170+
assert result.get("time_unit") == "s"
171+
assert result.get("content") is not None
138172

139173

140174
def test_zos_operator_positive_verbose_with_quick_delay(ansible_zos_module):
141175
hosts = ansible_zos_module
142-
wait_time_s=10
176+
wait_time=10
143177
results = hosts.all.zos_operator(
144-
cmd="d u,all", verbose=True, wait_time_s=wait_time_s
178+
cmd="d u,all", verbose=True, wait_time=wait_time
145179
)
146180

147181
for result in results.contacted.values():
148-
assert result["rc"] == 0
182+
assert result.get("rc") == 0
149183
assert result.get("changed") is True
184+
assert result.get("msg", False) is False
185+
assert result.get("cmd") is not None
186+
assert result.get("elapsed") <= (2 * wait_time)
187+
assert result.get("wait_time") is not None
188+
assert result.get("time_unit") == "s"
150189
assert result.get("content") is not None
151-
# Account for slower network
152-
assert result.get('elapsed') <= (2 * wait_time_s)
153190

154191

155192
def test_zos_operator_positive_verbose_blocking(ansible_zos_module):
156193
hosts = ansible_zos_module
157194
if is_zoau_version_higher_than(hosts,"1.2.4.5"):
158-
wait_time_s=5
195+
wait_time=5
159196
results = hosts.all.zos_operator(
160-
cmd="d u,all", verbose=True, wait_time_s=wait_time_s
197+
cmd="d u,all", verbose=True, wait_time=wait_time
161198
)
162199

163200
for result in results.contacted.values():
164-
assert result["rc"] == 0
201+
assert result.get("rc") == 0
165202
assert result.get("changed") is True
203+
assert result.get("msg", False) is False
204+
assert result.get("cmd") is not None
205+
assert result.get("elapsed") >= wait_time
206+
assert result.get("wait_time") is not None
207+
assert result.get("time_unit") == "s"
166208
assert result.get("content") is not None
167-
# Account for slower network
168-
assert result.get('elapsed') >= wait_time_s
169209

170210

171211
def test_zos_operator_positive_path_preserve_case(ansible_zos_module):
@@ -178,8 +218,13 @@ def test_zos_operator_positive_path_preserve_case(ansible_zos_module):
178218
)
179219

180220
for result in results.contacted.values():
181-
assert result["rc"] == 0
221+
assert result.get("rc") == 0
182222
assert result.get("changed") is True
223+
assert result.get("msg", False) is False
224+
assert result.get("cmd") is not None
225+
assert result.get("wait_time") is not None
226+
assert result.get("elapsed") is not None
227+
assert result.get("time_unit") == "s"
183228
assert result.get("content") is not None
184229
# Making sure the output from opercmd logged the command
185230
# exactly as it was written.
@@ -193,12 +238,34 @@ def test_response_come_back_complete(ansible_zos_module):
193238
res = {}
194239
res["stdout"] = []
195240
for result in results.contacted.values():
241+
assert result.get("rc") == 0
242+
assert result.get("changed") is True
243+
assert result.get("msg", False) is False
244+
assert result.get("cmd") is not None
245+
assert result.get("wait_time") is not None
246+
assert result.get("elapsed") is not None
247+
assert result.get("time_unit") == "s"
248+
assert result.get("content") is not None
196249
stdout = result.get('content')
197250
# HASP646 Only appears in the last line that before did not appears
198251
last_line = len(stdout)
199252
assert "HASP646" in stdout[last_line - 1]
200253

201254

255+
def test_operator_sentiseconds(ansible_zos_module):
256+
hosts = ansible_zos_module
257+
results = hosts.all.zos_operator(cmd="d a", time_unit="cs", wait_time=100)
258+
for result in results.contacted.values():
259+
assert result.get("rc") == 0
260+
assert result.get("changed") is True
261+
assert result.get("msg", False) is False
262+
assert result.get("cmd") is not None
263+
assert result.get("elapsed") is not None
264+
assert result.get("wait_time") is not None
265+
assert result.get("time_unit") == "cs"
266+
assert result.get("content") is not None
267+
268+
202269
def test_zos_operator_parallel_terminal(get_config):
203270
path = get_config
204271
with open(path, 'r') as file:

0 commit comments

Comments
 (0)