Skip to content

Commit 7c94c05

Browse files
authored
[Enabler] [Various modules] Remove use of deprecated pipes library (#1565)
* Replace use of pipes for shlex * Remove import of pipes due to use of Python 2 * Add changelog fragment * Remove import of PY3 * Add special symbols workaround * Fix syntax error * Fix another syntax error * Fix pep8 issues * Add ZOAUResponse to keep compatibility * Fix ZOAU exception * Update changed attribute in response * Add cmd to result * Add single quotes to data set names * Add workaround for batches * Fix pylint issue * Fix cat issue
1 parent 24d693a commit 7c94c05

File tree

10 files changed

+179
-71
lines changed

10 files changed

+179
-71
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
trivial:
2+
- zos_find - remove deprecated library pipes in favor of shlex.
3+
(https://github.com/ansible-collections/ibm_zos_core/pull/1565).
4+
- zos_mvs_raw - remove deprecated library pipes in favor of shlex.
5+
(https://github.com/ansible-collections/ibm_zos_core/pull/1565).
6+
- module_utils/backup.py - remove deprecated library pipes in favor of shlex.
7+
(https://github.com/ansible-collections/ibm_zos_core/pull/1565).
8+
- module_utils/copy.py - remove deprecated library pipes in favor of shlex.
9+
(https://github.com/ansible-collections/ibm_zos_core/pull/1565).
10+
- module_utils/encode.py - remove deprecated library pipes in favor of shlex.
11+
(https://github.com/ansible-collections/ibm_zos_core/pull/1565).

plugins/module_utils/backup.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
__metaclass__ = type
1616

1717
import os
18-
from ansible.module_utils.six import PY3
1918
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.ansible_module import (
2019
AnsibleModuleHelper,
2120
)
@@ -44,10 +43,8 @@
4443
except Exception:
4544
datasets = ZOAUImportError(traceback.format_exc())
4645
exceptions = ZOAUImportError(traceback.format_exc())
47-
if PY3:
48-
from shlex import quote
49-
else:
50-
from pipes import quote
46+
47+
from shlex import quote
5148

5249

5350
def _validate_data_set_name(ds):

plugins/module_utils/copy.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import traceback
1919
from os import path
20-
from ansible.module_utils.six import PY3
2120
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.ansible_module import (
2221
AnsibleModuleHelper,
2322
)
@@ -30,10 +29,7 @@
3029
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.import_handler import \
3130
ZOAUImportError
3231

33-
if PY3:
34-
from shlex import quote
35-
else:
36-
from pipes import quote
32+
from shlex import quote
3733

3834
try:
3935
from zoautil_py import datasets, gdgs

plugins/module_utils/encode.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from tempfile import NamedTemporaryFile, mkstemp, mkdtemp
1818
from math import floor, ceil
1919
from os import path, walk, makedirs, unlink
20-
from ansible.module_utils.six import PY3
2120

2221
import shutil
2322
import errno
@@ -42,11 +41,7 @@
4241
except Exception:
4342
datasets = ZOAUImportError(traceback.format_exc())
4443

45-
46-
if PY3:
47-
from shlex import quote
48-
else:
49-
from pipes import quote
44+
from shlex import quote
5045

5146

5247
class Defaults:

plugins/modules/zos_apf.py

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,10 @@
305305

306306
try:
307307
from zoautil_py import zsystem
308+
from zoautil_py import ztypes
308309
except Exception:
309310
zsystem = ZOAUImportError(traceback.format_exc())
311+
ztypes = ZOAUImportError(traceback.format_exc())
310312

311313

312314
# supported data set types
@@ -361,6 +363,107 @@ def backupOper(module, src, backup, tmphlq=None):
361363
return backup_name
362364

363365

366+
def make_apf_command(library, opt, volume=None, sms=None, force_dynamic=None, persistent=None):
367+
"""Returns a string that can run an APF command in a shell.
368+
369+
Parameters
370+
----------
371+
library : str
372+
Name of the data set that will be operated on.
373+
opt : str
374+
APF operation (either add or del)
375+
volume : str
376+
Volume of library.
377+
sms : bool
378+
Whether library is managed by SMS.
379+
force_dynamic : bool
380+
Whether the APF list format should be dynamic.
381+
persistent : dict
382+
Options for persistent entries that should be modified by APF.
383+
384+
Returns
385+
-------
386+
str
387+
APF command.
388+
"""
389+
operation = "-A" if opt == "add" else "-D"
390+
operation_args = library
391+
392+
if volume:
393+
operation_args = f"{operation_args},{volume}"
394+
elif sms:
395+
operation_args = f"{operation_args},SMS"
396+
397+
command = f"apfadm {operation} '{operation_args}'"
398+
399+
if force_dynamic:
400+
command = f"{command} -f"
401+
402+
if persistent:
403+
if opt == "add":
404+
persistent_args = f""" -P '{persistent.get("addDataset")}' """
405+
else:
406+
persistent_args = f""" -R '{persistent.get("delDataset")}' """
407+
408+
if persistent.get("marker"):
409+
persistent_args = f""" {persistent_args} -M '{persistent.get("marker")}' """
410+
411+
command = f"{command} {persistent_args}"
412+
413+
return command
414+
415+
416+
def make_apf_batch_command(batch, force_dynamic=None, persistent=None):
417+
"""Returns a string that can run an APF command for multiple operations
418+
in a shell.
419+
420+
Parameters
421+
----------
422+
batch : list
423+
List of dicts containing different APF add/del operations.
424+
force_dynamic : bool
425+
Whether the APF list format should be dynamic.
426+
persistent : dict
427+
Options for persistent entries that should be modified by APF.
428+
429+
Returns
430+
-------
431+
str
432+
APF command.
433+
"""
434+
command = "apfadm"
435+
436+
for item in batch:
437+
operation = "-A" if item["opt"] == "add" else "-D"
438+
operation_args = item["dsname"]
439+
440+
volume = item.get("volume")
441+
sms = item.get("sms")
442+
443+
if volume:
444+
operation_args = f"{operation_args},{volume}"
445+
elif sms:
446+
operation_args = f"{operation_args},SMS"
447+
448+
command = f"{command} {operation} '{operation_args}'"
449+
450+
if force_dynamic:
451+
command = f"{command} -f"
452+
453+
if persistent:
454+
if persistent.get("addDataset"):
455+
persistent_args = f""" -P '{persistent.get("addDataset")}' """
456+
else:
457+
persistent_args = f""" -R '{persistent.get("delDataset")}' """
458+
459+
if persistent.get("marker"):
460+
persistent_args = f""" {persistent_args} -M '{persistent.get("marker")}' """
461+
462+
command = f"{command} {persistent_args}"
463+
464+
return command
465+
466+
364467
def main():
365468
"""Initialize the module.
366469
@@ -551,18 +654,32 @@ def main():
551654
item['opt'] = opt
552655
item['dsname'] = item.get('library')
553656
del item['library']
554-
ret = zsystem.apf(batch=batch, forceDynamic=force_dynamic, persistent=persistent)
657+
# Commenting this line to implement a workaround for names with '$'. ZOAU should
658+
# release a fix soon so we can uncomment this Python API call.
659+
# ret = zsystem.apf(batch=batch, forceDynamic=force_dynamic, persistent=persistent)
660+
apf_command = make_apf_batch_command(batch, force_dynamic=force_dynamic, persistent=persistent)
661+
rc, out, err = module.run_command(apf_command)
662+
ret = ztypes.ZOAUResponse(rc, out, err, apf_command, 'utf-8')
555663
else:
556664
if not library:
557665
module.fail_json(msg='library is required')
558-
ret = zsystem.apf(opt=opt, dsname=library, volume=volume, sms=sms, forceDynamic=force_dynamic, persistent=persistent)
666+
# Commenting this line to implement a workaround for names with '$'. ZOAU should
667+
# release a fix soon so we can uncomment this Python API call.
668+
# ret = zsystem.apf(opt=opt, dsname=library, volume=volume, sms=sms, forceDynamic=force_dynamic, persistent=persistent)
669+
apf_command = make_apf_command(library, opt, volume=volume, sms=sms, force_dynamic=force_dynamic, persistent=persistent)
670+
rc, out, err = module.run_command(apf_command)
671+
ret = ztypes.ZOAUResponse(rc, out, err, apf_command, 'utf-8')
559672

560673
operOut = ret.stdout_response
561674
operErr = ret.stderr_response
562675
operRc = ret.rc
563676
result['stderr'] = operErr
564677
result['rc'] = operRc
565678
result['stdout'] = operOut
679+
680+
if operation != 'list' and operRc == 0:
681+
result['changed'] = True
682+
566683
if operation == 'list':
567684
try:
568685
data = json.loads(operOut)

plugins/modules/zos_find.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,6 @@
304304
from re import match as fullmatch
305305

306306

307-
from ansible.module_utils.six import PY3
308307
from ansible.module_utils.basic import AnsibleModule
309308

310309
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils import (
@@ -319,10 +318,7 @@
319318
AnsibleModuleHelper
320319
)
321320

322-
if PY3:
323-
from shlex import quote
324-
else:
325-
from pipes import quote
321+
from shlex import quote
326322

327323

328324
def content_filter(module, patterns, content):

plugins/modules/zos_mvs_raw.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,12 +1645,8 @@
16451645
)
16461646
import re
16471647
import traceback
1648-
from ansible.module_utils.six import PY3
16491648

1650-
if PY3:
1651-
from shlex import quote
1652-
else:
1653-
from pipes import quote
1649+
from shlex import quote
16541650

16551651
try:
16561652
from zoautil_py import datasets

tests/functional/modules/test_module_security.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import pytest
1919
from pprint import pprint
20-
from pipes import quote
20+
from shlex import quote
2121
import unittest
2222

2323
# TODO: remove some of the logic from tests and make pytest fixtures

0 commit comments

Comments
 (0)