├── .ansible-lint ├── .github ├── ISSUE_TEMPLATE │ ├── bug_issue.yml │ ├── collaboration_issue.yml │ ├── config.yml │ ├── doc_issue.yml │ ├── enabler_issue.yml │ ├── enhancement_feature.issue.yml │ └── module_issue.yml └── workflows │ ├── ac-ansible-test-sanity.yml │ ├── ac-bandit.yml │ ├── ac-galaxy-importer.yml │ ├── ac-module-doc.yml │ ├── ac_changelog.yml │ └── galaxy-importer.cfg ├── .gitignore ├── CHANGELOG.rst ├── Jenkinsfile ├── README.md ├── __init__.py ├── bindep.txt ├── changelogs ├── .plugin-cache.yaml ├── changelog.yaml ├── config.yaml └── fragments │ ├── .gitkeep │ ├── 2030-Set_dynamic_volumes_for_volume_init.yml │ ├── 2033-remove-dev-tools.yml │ ├── 2039-documentation-zos_copy-opercmd.yml │ ├── 2040-zos_backup_restore-fixed_return_backup_name.yml │ ├── 2043-zos_mount-volume-size-resize.yml │ ├── 2047-zos_fetch-update-docs.yml │ ├── 2049-zos_backup_restore-added-return-values-in-doc.yml │ ├── 2055-Zos_apf-shell-commands-to-api.yml │ ├── 2056-zos_job-modules-adding-cpu_time-execution_node-origin_node.yml │ ├── 2057-zos_data_set&data_set-Ensure-Dataset-Volume-Validation.yml │ ├── 2058-Add_sanity_ignore_for_2_18.yml │ ├── 2059-Github-sanity-2-18-fix.yml │ ├── 2060-zos_mount-skip_fsumf168_from_df.yml │ ├── 2061-alias-support-zos_stat.yml │ ├── 2068-zos_data_set-Removed-Extra-Validation.yml │ ├── 2073-zos_find-finding-migrated-datasets.yml │ ├── 2075-migrated-data-sets-support-zos_stat.yml │ ├── 2079-become-use-zos_fetch.yml │ ├── 2080-zos_lineinfile-fixed-json-parsing.yml │ ├── 2081-zos_archive-add-encoding-support.yml │ ├── 2086_Programs_fails_when_need_access_to_the_first_and_second_columns.yml │ ├── 2098-docs-migrated-data-sets-examples.yml │ ├── 2100-zos_copy-Identical-gdg-copy-support.yml │ ├── 2103-zos_copy-supporting-aliases-for-src-and-dest.yml │ └── 2105-zos_unarchive-encoding-support.yml ├── collections └── requirements.yml ├── docs ├── Makefile ├── files │ └── role_sample │ │ ├── defaults-main.yml │ │ ├── doc_role_sample │ │ ├── meta-main.yml │ │ ├── role-doc-readme.txt │ │ ├── role_sample.yml │ │ ├── roles.rst │ │ ├── tasks-main.yml │ │ └── vars-main.yml ├── scripts │ ├── auto-doc-gen.sh │ ├── post-doc-gen.sh │ ├── post-template.sh │ ├── post-zos_apf.sh │ ├── pre-doc-gen.sh │ ├── pre-template.sh │ └── role-sample-gen.sh ├── source │ ├── _static │ │ ├── css │ │ │ ├── custom.css │ │ │ └── table.css │ │ └── my_theme.css │ ├── ansible_content.rst │ ├── character_set.rst │ ├── collection-requirements.rst │ ├── community_guides.rst │ ├── community_guides_docs │ │ ├── better_arg_parser.rst │ │ └── zos_ansible_module_testing.rst │ ├── conf.py │ ├── configuration.rst │ ├── filters.rst │ ├── index.rst │ ├── life-cycle.rst │ ├── modules.rst │ ├── modules │ │ ├── zos_apf.rst │ │ ├── zos_archive.rst │ │ ├── zos_backup_restore.rst │ │ ├── zos_blockinfile.rst │ │ ├── zos_copy.rst │ │ ├── zos_data_set.rst │ │ ├── zos_encode.rst │ │ ├── zos_fetch.rst │ │ ├── zos_find.rst │ │ ├── zos_gather_facts.rst │ │ ├── zos_job_output.rst │ │ ├── zos_job_query.rst │ │ ├── zos_job_submit.rst │ │ ├── zos_lineinfile.rst │ │ ├── zos_mount.rst │ │ ├── zos_mvs_raw.rst │ │ ├── zos_operator.rst │ │ ├── zos_operator_action_query.rst │ │ ├── zos_ping.rst │ │ ├── zos_script.rst │ │ ├── zos_stat.rst │ │ ├── zos_tso_command.rst │ │ ├── zos_unarchive.rst │ │ ├── zos_volume_init.rst │ │ └── zos_zfs_resize.rst │ ├── plugins.rst │ ├── release_notes.rst │ ├── requirements.rst │ └── resources │ │ └── releases_maintenance.rst └── templates │ ├── breadcrumbs.html │ ├── module.rst.j2 │ └── role.rst.j2 ├── galaxy.yml ├── meta ├── execution-environment.yml ├── ibm_zos_core_meta.yml └── runtime.yml ├── plugins ├── __init__.py ├── action │ ├── zos_copy.py │ ├── zos_fetch.py │ ├── zos_job_submit.py │ ├── zos_ping.py │ ├── zos_script.py │ └── zos_unarchive.py ├── doc_fragments │ └── template.py ├── filter │ ├── __init__.py │ └── wtor.py ├── module_utils │ ├── ansible_module.py │ ├── backup.py │ ├── better_arg_parser.py │ ├── copy.py │ ├── data_set.py │ ├── dd_statement.py │ ├── encode.py │ ├── file.py │ ├── ickdsf.py │ ├── import_handler.py │ ├── job.py │ ├── mvs_cmd.py │ ├── system.py │ ├── template.py │ ├── validation.py │ ├── vtoc.py │ ├── zfsadm.py │ ├── zoau_version_checker.py │ └── zos_mvs_raw.py └── modules │ ├── __init__.py │ ├── zos_apf.py │ ├── zos_archive.py │ ├── zos_backup_restore.py │ ├── zos_blockinfile.py │ ├── zos_copy.py │ ├── zos_data_set.py │ ├── zos_encode.py │ ├── zos_fetch.py │ ├── zos_find.py │ ├── zos_gather_facts.py │ ├── zos_job_output.py │ ├── zos_job_query.py │ ├── zos_job_submit.py │ ├── zos_lineinfile.py │ ├── zos_mount.py │ ├── zos_mvs_raw.py │ ├── zos_operator.py │ ├── zos_operator_action_query.py │ ├── zos_ping.py │ ├── zos_ping.rexx │ ├── zos_script.py │ ├── zos_stat.py │ ├── zos_tso_command.py │ ├── zos_unarchive.py │ ├── zos_volume_init.py │ └── zos_zfs_resize.py ├── requirements.txt └── tests ├── __init__.py ├── config.yml ├── conftest.py ├── dependencyfinder.py ├── functional ├── __init__.py ├── module_utils │ └── test_arg_parser.py └── modules │ ├── test_module_security.py │ ├── test_zos_apf_func.py │ ├── test_zos_archive_func.py │ ├── test_zos_backup_restore.py │ ├── test_zos_blockinfile_func.py │ ├── test_zos_copy_func.py │ ├── test_zos_data_set_func.py │ ├── test_zos_encode_func.py │ ├── test_zos_fetch_func.py │ ├── test_zos_find_func.py │ ├── test_zos_gather_facts_func.py │ ├── test_zos_job_output_func.py │ ├── test_zos_job_query_func.py │ ├── test_zos_job_submit_func.py │ ├── test_zos_lineinfile_func.py │ ├── test_zos_mount_func.py │ ├── test_zos_mvs_raw_func.py │ ├── test_zos_operator_action_query_func.py │ ├── test_zos_operator_func.py │ ├── test_zos_ping_func.py │ ├── test_zos_script_func.py │ ├── test_zos_stat_func.py │ ├── test_zos_tso_command_func.py │ ├── test_zos_unarchive_func.py │ ├── test_zos_volume_init_func.py │ └── test_zos_zfs_resize_func.py ├── helpers ├── __init__.py ├── dataset.py ├── users.py ├── utils.py ├── version.py ├── volumes.py ├── zos_blockinfile_helper.py ├── zos_lineinfile_helper.py └── ztest.py ├── pytest.ini ├── requirements.txt ├── sanity ├── ignore-2.10.txt ├── ignore-2.11.txt ├── ignore-2.12.txt ├── ignore-2.13.txt ├── ignore-2.14.txt ├── ignore-2.15.txt ├── ignore-2.16.txt ├── ignore-2.17.txt ├── ignore-2.18.txt └── ignore-2.9.txt └── unit ├── __init__.py ├── test_data_set_utils.py ├── test_module_utils_data_set_unit.py ├── test_zoau_version_checker_unit.py ├── test_zos_backup_restore_unit.py ├── test_zos_gather_facts.py ├── test_zos_mvs_raw_unit.py ├── test_zos_operator_action_query_unit.py └── test_zos_operator_unit.py /.ansible-lint: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) IBM Corporation 2024, 2025 3 | ################################################################################ 4 | # For additonal doc, see https://ansible.readthedocs.io/projects/lint/configuring/ 5 | exclude_paths: 6 | - .tar.gz 7 | - __pycache__/ 8 | - .ansible-lint 9 | - .cache/ 10 | - .DS_Store 11 | - .git/ 12 | - .github/ 13 | - .gitignore 14 | - .python-version 15 | - .pytest_cache/ 16 | - .vscode/ 17 | - Jenkinsfile 18 | - ac 19 | - ansible.cfg 20 | - changelogs/ 21 | - collections/ 22 | - docs/ 23 | - importer_result.json 24 | - scripts/ 25 | - test_config.yml 26 | - tests/*.ini 27 | - tests/*.py 28 | - tests/.pytest_cache 29 | - tests/__pycache__ 30 | - tests/functional 31 | - tests/helpers 32 | - tests/requirements.txt 33 | - tests/unit 34 | - tests/sanity/ignore-2.9.txt 35 | - tests/sanity/ignore-2.10.txt 36 | - tests/sanity/ignore-2.11.txt 37 | - tests/sanity/ignore-2.12.txt 38 | - tests/sanity/ignore-2.13.txt 39 | - tests/sanity/ignore-2.14.txt 40 | - venv* 41 | - ansible_collections/ 42 | - ./*.log 43 | parseable: true 44 | quiet: false 45 | use_default_rules: true 46 | verbosity: 1 47 | # Offline mode disables installation of requirements.yml and schema refreshing often 48 | # found in project_root/collections/requirements.yml. 49 | offline: true 50 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_issue.yml: -------------------------------------------------------------------------------- 1 | name: Report a bug 2 | description: Request that a bug be reviewed. Complete all required fields. 3 | title: "[Bug] Enter description" 4 | labels: ["Bug", "Needs Triage"] 5 | assignees: 6 | - IBMAnsibleHelper 7 | body: 8 | - type: checkboxes 9 | id: existing-issue 10 | attributes: 11 | label: Is there an existing issue for this? 12 | description: Please search to see if an issue already exists for the bug you encountered. 13 | options: 14 | - label: There are no existing issues. 15 | required: true 16 | - type: textarea 17 | id: issue-description 18 | attributes: 19 | label: Bug description 20 | description: Describe the bug you are experiencing. 21 | placeholder: | 22 | Verbosity is encouraged, the more you share the better for us to understand. 23 | 1. Include the steps to reproduce 24 | 2. Include playbook if applicable 25 | 3. Include screen captures of applicable 26 | 4. Include expected vs actual results if applicable 27 | validations: 28 | required: true 29 | - type: dropdown 30 | id: collection-version 31 | attributes: 32 | label: IBM z/OS Ansible core Version 33 | description: Which version of z/OS Ansible core collection are you using. If you are unsure, review the [documentation](https://ibm.github.io/z_ansible_collections_doc/faqs/faqs.html#how-do-i-update-a-collection-to-the-latest-version). 34 | multiple: false 35 | options: 36 | - v1.13.0 37 | - v1.13.0-beta.1 38 | - v1.12.0 39 | - v1.12.0-beta.1 40 | - v1.11.1 41 | - v1.11.0 42 | - v1.10.0 43 | - v1.9.4 44 | - v1.9.3 45 | - v1.9.2 46 | - v1.9.0 47 | - v1.8.0 48 | - v1.7.0 49 | - v1.6.0 50 | - v1.5.0 51 | default: 3 52 | validations: 53 | required: true 54 | - type: dropdown 55 | id: zoau-version 56 | attributes: 57 | label: IBM Z Open Automation Utilities 58 | description: Which version of ZOAU are you using? Please review the supported dependencies in the release notes](https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/release_notes.html). 59 | multiple: false 60 | options: 61 | - v1.3.4 62 | - v1.3.3 63 | - v1.3.2 64 | - v1.3.1 65 | - v1.3.0 66 | - v1.2.5 67 | - v1.2.4 68 | - v1.2.3 69 | - v1.2.2 70 | default: 3 71 | validations: 72 | required: true 73 | - type: dropdown 74 | id: python-version 75 | attributes: 76 | label: IBM Enterprise Python 77 | description: Which version of IBM Enterprise Python are you using? Please review the supported dependencies in the release notes](https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/release_notes.html). 78 | multiple: false 79 | options: 80 | - v3.13.x 81 | - v3.12.x 82 | - v3.11.x 83 | - v3.10.x 84 | default: 2 85 | validations: 86 | required: true 87 | - type: dropdown 88 | id: ansible-version 89 | attributes: 90 | label: ansible-version 91 | description: What is the version of Ansible on the controller (`ansible --version`)? 92 | multiple: false 93 | options: 94 | - v2.17.x 95 | - v2.16.x 96 | - v2.15.x 97 | - v2.14.x 98 | default: 3 99 | validations: 100 | required: true 101 | - type: dropdown 102 | id: zos-version 103 | attributes: 104 | label: z/OS version 105 | description: What is the version of z/OS on the managed node? Please review the supported dependencies in the release notes](https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/release_notes.html). 106 | multiple: false 107 | options: 108 | - v3.1 109 | - v2.5 110 | - v2.4 111 | default: 1 112 | validations: 113 | required: false 114 | - type: dropdown 115 | id: modules 116 | attributes: 117 | label: Ansible module 118 | description: Select which modules are being reported in this bug. You can select more than one. 119 | multiple: true 120 | options: 121 | - zos_apf 122 | - zos_archive 123 | - zos_backup_restore 124 | - zos_blockinfile 125 | - zos_copy 126 | - zos_data_set 127 | - zos_encode 128 | - zos_fetch 129 | - zos_find 130 | - zos_gather_facts 131 | - zos_job_output 132 | - zos_job_query 133 | - zos_job_submit 134 | - zos_lineinfile 135 | - zos_mount 136 | - zos_mvs_raw 137 | - zos_operator 138 | - zos_operator_action_query 139 | - zos_ping 140 | - zos_script 141 | - zos_tso_command 142 | - zos_unarchive 143 | - zos_volume_init 144 | - zos_zfs_resize 145 | validations: 146 | required: false 147 | - type: textarea 148 | id: issue-output 149 | attributes: 150 | label: Playbook verbosity output. 151 | description: Provide the command line output with debug and verbosity enabled. 152 | placeholder: | 153 | Insert the output using this form of the playbook command. 154 | - `ANSIBLE_DEBUG=1 ansible-playbook -i inventory your-playbook.yml -vvvv` 155 | validations: 156 | required: false 157 | - type: textarea 158 | id: ansible-cfg 159 | attributes: 160 | label: Ansible configuration. 161 | description: Show the current **ansible.cfg** settings. 162 | placeholder: | 163 | Insert for this command: `ansible-config view` 164 | render: YAML 165 | validations: 166 | required: false 167 | - type: textarea 168 | id: ansible-inventory 169 | attributes: 170 | label: Contents of the inventory 171 | description: Provide the contents of the inventory. 172 | render: YAML 173 | validations: 174 | required: false 175 | - type: textarea 176 | id: ansible-vars 177 | attributes: 178 | label: Contents of `group_vars` or `host_vars` 179 | description: Provide the contents of `group_vars` or `host_vars` 180 | render: YAML 181 | validations: 182 | required: false 183 | 184 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/collaboration_issue.yml: -------------------------------------------------------------------------------- 1 | name: Request a Collaboration 2 | description: Request collaboration with a member of this team. Complete all required fields. 3 | title: "[Collaboration] " 4 | labels: [Collaboration] 5 | assignees: 6 | - IBMAnsibleHelper 7 | body: 8 | - type: checkboxes 9 | id: existing-issue 10 | attributes: 11 | label: Is there an existing issue for this? 12 | description: Please search to see if an issue already exists for the bug you encountered. 13 | options: 14 | - label: There are no existing issues. 15 | required: true 16 | - type: checkboxes 17 | id: support-issue 18 | attributes: 19 | label: Support and service? 20 | description: Is support and service involved in this collaboration? 21 | options: 22 | - label: Yes, support and service is involved. 23 | required: false 24 | - label: No, support and service is involved. 25 | required: false 26 | - type: textarea 27 | id: issue-description 28 | attributes: 29 | label: Collaboration description 30 | description: Describe the collaboration issue. 31 | placeholder: | 32 | For example 33 | 1. Working with IBM Enterprise Python to resolve issue xyz. 34 | 2. Working with z/OS application team DFSMS to resolve xyz. 35 | 3. Assisting IBM support to resolve an ibm_zos_copy issue. 36 | validations: 37 | required: true 38 | - type: dropdown 39 | id: collection-version 40 | attributes: 41 | label: IBM z/OS Ansible core Version 42 | description: Which version of z/OS Ansible core collection are you using. If you are unsure, review the [documentation](https://ibm.github.io/z_ansible_collections_doc/faqs/faqs.html#how-do-i-update-a-collection-to-the-latest-version). 43 | multiple: false 44 | options: 45 | - v1.13.0 46 | - v1.13.0-beta.1 47 | - v1.12.0 48 | - v1.12.0-beta.1 49 | - v1.11.1 50 | - v1.11.0-beta.1 51 | - v1.10.0 52 | - v1.10.0-beta.1 53 | - v1.9.4 (default) 54 | - v1.8.0 55 | - v1.7.0 56 | - v1.6.0 57 | - v1.5.0 58 | default: 6 59 | validations: 60 | required: false 61 | - type: dropdown 62 | id: zoau-version 63 | attributes: 64 | label: IBM Z Open Automation Utilities 65 | description: Which version of ZOAU are you using? Please review the supported dependencies in the release notes](https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/release_notes.html). 66 | multiple: false 67 | options: 68 | - v1.3.4 69 | - v1.3.3 70 | - v1.3.2 71 | - v1.3.1 72 | - v1.3.0 73 | - v1.2.5 (default) 74 | - v1.2.4 75 | - v1.2.3 76 | - v1.2.2 77 | default: 5 78 | validations: 79 | required: false 80 | - type: dropdown 81 | id: python-version 82 | attributes: 83 | label: IBM Enterprise Python 84 | description: Which version of IBM Enterprise Python are you using? Please review the supported dependencies in the release notes](https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/release_notes.html). 85 | multiple: false 86 | options: 87 | - v3.13.x 88 | - v3.12.x 89 | - v3.11.x (default) 90 | - v3.10.x 91 | default: 2 92 | validations: 93 | required: false 94 | - type: dropdown 95 | id: ansible-version 96 | attributes: 97 | label: ansible-version 98 | description: What is the version of Ansible on the controller (`ansible --version`)? 99 | multiple: false 100 | options: 101 | - v2.17.x 102 | - v2.16.x (default) 103 | - v2.15.x 104 | - v2.14.x 105 | default: 1 106 | validations: 107 | required: false 108 | - type: dropdown 109 | id: zos-version 110 | attributes: 111 | label: z/OS version 112 | description: What is the version of z/OS on the managed node? Please review the supported dependencies in the release notes](https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/release_notes.html). 113 | multiple: false 114 | options: 115 | - v3.1 (unsupported) 116 | - v2.5 (default) 117 | - v2.4 118 | default: 1 119 | validations: 120 | required: false 121 | - type: dropdown 122 | id: modules 123 | attributes: 124 | label: Ansible module 125 | description: Select which modules are being reported in this bug. You can select more than one. 126 | multiple: true 127 | options: 128 | - zos_apf 129 | - zos_archive 130 | - zos_backup_restore 131 | - zos_blockinfile 132 | - zos_copy 133 | - zos_data_set 134 | - zos_encode 135 | - zos_fetch 136 | - zos_find 137 | - zos_gather_facts 138 | - zos_job_output 139 | - zos_job_query 140 | - zos_job_submit 141 | - zos_lineinfile 142 | - zos_mount 143 | - zos_mvs_raw 144 | - zos_operator 145 | - zos_operator_action_query 146 | - zos_ping 147 | - zos_script 148 | - zos_tso_command 149 | - zos_unarchive 150 | - zos_volume_init 151 | - zos_zfs_resize 152 | validations: 153 | required: false 154 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: GitHub Community Support 4 | url: https://github.com/ansible-collections/ibm_zos_core/discussions 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/doc_issue.yml: -------------------------------------------------------------------------------- 1 | name: Report a documentation issue 2 | description: Request that documentation be reviewed. Complete all required fields. 3 | title: "[Documentation] <title> " 4 | labels: [Documentation] 5 | assignees: 6 | - IBMAnsibleHelper 7 | body: 8 | - type: checkboxes 9 | id: existing-issue 10 | attributes: 11 | label: Is there an existing issue for this? 12 | description: Please search to see if an issue already exists for the bug you encountered. 13 | options: 14 | - label: There are no existing issues. 15 | required: true 16 | - type: textarea 17 | id: issue-description 18 | attributes: 19 | label: Documentation issue description 20 | description: Describe the documentation issue. 21 | placeholder: | 22 | Verbosity is encouraged, the more you share the better for us to understand. 23 | 1. Include links to the page you are referring to if applicable 24 | 2. Include reproduction steps if applicable 25 | 3. Include any additional information that will help us 26 | 4. Include screen captures of applicable 27 | 5. Include browser or shell if applicable 28 | validations: 29 | required: true 30 | - type: dropdown 31 | id: collection-version 32 | attributes: 33 | label: IBM z/OS Ansible core Version 34 | description: Which version of z/OS Ansible core collection are you using. If you are unsure, review the [documentation](https://ibm.github.io/z_ansible_collections_doc/faqs/faqs.html#how-do-i-update-a-collection-to-the-latest-version). 35 | multiple: false 36 | options: 37 | - v1.13.0 38 | - v1.13.0-beta.1 39 | - v1.12.0 40 | - v1.12.0-beta.1 41 | - v1.11.1 42 | - v1.11.0 43 | - v1.11.0-beta.1 44 | - v1.10.0 45 | - v1.10.0-beta.1 46 | - v1.9.4 (default) 47 | - v1.9.3 48 | - v1.9.2 49 | - v1.9.1 50 | - v1.9.0 51 | - v1.8.0 52 | - v1.7.0 53 | - v1.6.0 54 | - v1.5.0 55 | default: 6 56 | validations: 57 | required: false 58 | - type: dropdown 59 | id: modules 60 | attributes: 61 | label: Ansible module 62 | description: Select which modules are being reported in this bug. You can select more than one. 63 | multiple: true 64 | options: 65 | - zos_apf 66 | - zos_archive 67 | - zos_backup_restore 68 | - zos_blockinfile 69 | - zos_copy 70 | - zos_data_set 71 | - zos_encode 72 | - zos_fetch 73 | - zos_find 74 | - zos_gather_facts 75 | - zos_job_output 76 | - zos_job_query 77 | - zos_job_submit 78 | - zos_lineinfile 79 | - zos_mount 80 | - zos_mvs_raw 81 | - zos_operator 82 | - zos_operator_action_query 83 | - zos_ping 84 | - zos_script 85 | - zos_tso_command 86 | - zos_unarchive 87 | - zos_volume_init 88 | - zos_zfs_resize 89 | validations: 90 | required: false 91 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enabler_issue.yml: -------------------------------------------------------------------------------- 1 | name: Enabler task 2 | description: | 3 | Identify a development task that does not correspond to other git issue types, eg this could be a pipeline task. 4 | Complete all required fields. 5 | title: "[Enabler] <title> " 6 | labels: [Enabler] 7 | assignees: 8 | - IBMAnsibleHelper 9 | body: 10 | - type: checkboxes 11 | id: existing-issue 12 | attributes: 13 | label: Is there an existing issue for this? 14 | description: Please search to see if an issue already exists for the bug you encountered. 15 | options: 16 | - label: There are no existing issues. 17 | required: true 18 | - type: textarea 19 | id: issue-description 20 | attributes: 21 | label: Enabler description 22 | description: Describe the task. 23 | placeholder: Verbosity is encouraged, the more you share the better for us to understand. 24 | validations: 25 | required: true 26 | - type: dropdown 27 | id: modules 28 | attributes: 29 | label: Ansible module 30 | description: Select which modules are being reported in this bug. You can select more than one. 31 | multiple: true 32 | options: 33 | - zos_apf 34 | - zos_archive 35 | - zos_backup_restore 36 | - zos_blockinfile 37 | - zos_copy 38 | - zos_data_set 39 | - zos_encode 40 | - zos_fetch 41 | - zos_find 42 | - zos_gather_facts 43 | - zos_job_output 44 | - zos_job_query 45 | - zos_job_submit 46 | - zos_lineinfile 47 | - zos_mount 48 | - zos_mvs_raw 49 | - zos_operator 50 | - zos_operator_action_query 51 | - zos_ping 52 | - zos_script 53 | - zos_tso_command 54 | - zos_unarchive 55 | - zos_volume_init 56 | - zos_zfs_resize 57 | validations: 58 | required: false 59 | 60 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement_feature.issue.yml: -------------------------------------------------------------------------------- 1 | name: Request an enhancement or new feature 2 | description: Request a new feature or an enhancement. Complete all required fields. 3 | title: "[Enhancement] <title> " 4 | labels: [Enhancement] 5 | assignees: 6 | - IBMAnsibleHelper 7 | body: 8 | - type: checkboxes 9 | id: existing-issue 10 | attributes: 11 | label: Is there an existing issue for this? 12 | description: Please search to see if an issue already exists for the bug you encountered. 13 | options: 14 | - label: There are no existing issues. 15 | required: true 16 | - type: textarea 17 | id: issue-description 18 | attributes: 19 | label: Enhancement or feature description 20 | description: Describe the enhancement or feature you are requesting. 21 | placeholder: Verbosity is encouraged, the more you share the better for us to understand. 22 | validations: 23 | required: true 24 | - type: dropdown 25 | id: modules 26 | attributes: 27 | label: Ansible module 28 | description: Select which modules are being reported in this bug. You can select more than one. 29 | multiple: true 30 | options: 31 | - zos_apf 32 | - zos_archive 33 | - zos_backup_restore 34 | - zos_blockinfile 35 | - zos_copy 36 | - zos_data_set 37 | - zos_encode 38 | - zos_fetch 39 | - zos_find 40 | - zos_gather_facts 41 | - zos_job_output 42 | - zos_job_query 43 | - zos_job_submit 44 | - zos_lineinfile 45 | - zos_mount 46 | - zos_mvs_raw 47 | - zos_operator 48 | - zos_operator_action_query 49 | - zos_ping 50 | - zos_script 51 | - zos_tso_command 52 | - zos_unarchive 53 | - zos_volume_init 54 | - zos_zfs_resize 55 | validations: 56 | required: true 57 | 58 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/module_issue.yml: -------------------------------------------------------------------------------- 1 | name: Request a new module 2 | description: Request a new module be added to the collection. Complete all required fields. 3 | title: "[Module] Enter description " 4 | labels: [Module] 5 | assignees: 6 | - IBMAnsibleHelper 7 | body: 8 | - type: checkboxes 9 | id: existing-issue 10 | attributes: 11 | label: Is there an existing issue for this? 12 | description: Please search to see if an issue already exists for the bug you encountered. 13 | options: 14 | - label: There are no existing issues. 15 | required: true 16 | - type: textarea 17 | id: issue-description 18 | attributes: 19 | label: New module description 20 | description: Describe the new module you are requesting. 21 | placeholder: Verbosity is encouraged, the more you share the better for us to understand. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: user-story 26 | attributes: 27 | label: User story 28 | description: Write a user story with emphasis on the persona, for example sysadmin. 29 | placeholder: | 30 | Verbosity is encouraged, the more you share the better for us to understand. 31 | User stories take this form: 32 | - As a < type of user >, I want < some goal > so that < some reason >. 33 | Examples: 34 | - As a z/OS System Admin, I can grow zFS aggregates with Ansible so that my data sets don't fill up. 35 | - As a Junior developer, I want to be able to zip and unzip archives using Ansible, so that I don't have to perform operations elsewhere. 36 | validations: 37 | required: false 38 | -------------------------------------------------------------------------------- /.github/workflows/ac-ansible-test-sanity.yml: -------------------------------------------------------------------------------- 1 | name: Ansible sanity testing 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened, ready_for_review] 6 | branches: 7 | - dev 8 | - staging* 9 | paths-ignore: 10 | - '**.tar.gz' 11 | - 'pycache/**' 12 | - '.ansible-lint' 13 | - 'cache/**' 14 | - '.DS_Store' 15 | - '.git/**' 16 | - '.github/**' 17 | - '.gitignore' 18 | - '.python-version' 19 | - '.pytest_cache/**' 20 | - '.vscode/**' 21 | - 'Jenkinsfile' 22 | - 'ac' 23 | - 'ansible.cfg' 24 | - 'changelogs/**' 25 | - 'collections/**' 26 | - 'docs/**' 27 | - 'scripts/**' 28 | - 'test_config.yml' 29 | - 'tests/*.ini' 30 | - 'tests/*.py' 31 | - 'tests/.pytest_cache' 32 | - 'tests/pycache' 33 | - 'tests/functional' 34 | - 'tests/helpers' 35 | - 'tests/requirements.txt' 36 | - 'tests/unit' 37 | - 'tests/sanity/ignore-*' 38 | - 'venv*' 39 | 40 | jobs: 41 | ansible-sanity: 42 | if: github.event.pull_request.draft == false 43 | runs-on: ubuntu-latest 44 | env: 45 | branch: ${{ github.event.pull_request.head.ref }} 46 | 47 | steps: 48 | - name: Checkout repository 49 | uses: actions/checkout@v4 50 | 51 | - name: Set up Python 52 | uses: actions/setup-python@v5 53 | with: 54 | python-version: 3.12 55 | 56 | - name: Set up venv 57 | run: | 58 | python -m pip install --upgrade pip 59 | pip install virtualenv 60 | virtualenv venv 61 | 62 | - name: Install dependencies 63 | run: | 64 | source venv/bin/activate 65 | python -m pip install --upgrade pip 66 | pip install "ansible-core>=2.18,<2.19" 67 | 68 | - name: Run ac-sanity 69 | run: | 70 | source venv/bin/activate 71 | rm -rf ibm-ibm_zos_core-*.tar.gz 72 | ansible-galaxy collection build 73 | ansible-galaxy collection install -f ibm-ibm_zos_core-* 74 | cd ~/.ansible/collections/ansible_collections/ibm/ibm_zos_core && ansible-test sanity --python 3.12 --requirements 75 | -------------------------------------------------------------------------------- /.github/workflows/ac-bandit.yml: -------------------------------------------------------------------------------- 1 | name: Bandit Scan 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened, ready_for_review] 6 | branches: 7 | - dev 8 | - staging* 9 | paths: 10 | - 'plugins/**' 11 | 12 | jobs: 13 | bandit: 14 | if: github.event.pull_request.draft == false 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Set up Python 22 | uses: actions/setup-python@v5 23 | with: 24 | python-version: 3.12 25 | 26 | - name: Set up venv 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install virtualenv 30 | virtualenv venv 31 | 32 | - name: Install dependencies 33 | run: | 34 | source venv/bin/activate 35 | python -m pip install --upgrade pip 36 | pip install bandit 37 | 38 | - name: Run ac-bandit 39 | run: | 40 | source venv/bin/activate 41 | python3 -m bandit -r plugins/* -l 42 | -------------------------------------------------------------------------------- /.github/workflows/ac-galaxy-importer.yml: -------------------------------------------------------------------------------- 1 | name: Galaxy Importer Check 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened, ready_for_review] 6 | branches: 7 | - dev 8 | - staging* 9 | paths-ignore: 10 | - '**.tar.gz' 11 | - 'pycache/**' 12 | - '.ansible-lint' 13 | - 'cache/**' 14 | - '.DS_Store' 15 | - '.git/**' 16 | - '.github/**' 17 | - '.gitignore' 18 | - '.python-version' 19 | - '.pytest_cache/**' 20 | - '.vscode/**' 21 | - 'Jenkinsfile' 22 | - 'ac' 23 | - 'ansible.cfg' 24 | - 'changelogs/**' 25 | - 'collections/**' 26 | - 'docs/**' 27 | - 'scripts/**' 28 | - 'test_config.yml' 29 | - 'tests/*.ini' 30 | - 'tests/*.py' 31 | - 'tests/.pytest_cache' 32 | - 'tests/pycache' 33 | - 'tests/functional' 34 | - 'tests/helpers' 35 | - 'tests/requirements.txt' 36 | - 'tests/unit' 37 | - 'tests/sanity/ignore-*' 38 | - 'venv*' 39 | 40 | jobs: 41 | galaxy-importer: 42 | if: github.event.pull_request.draft == false 43 | runs-on: ubuntu-latest 44 | 45 | steps: 46 | - name: Checkout repository 47 | uses: actions/checkout@v4 48 | 49 | - name: Set up Python 50 | uses: actions/setup-python@v5 51 | with: 52 | python-version: 3.12 53 | 54 | - name: Set up venv 55 | run: | 56 | python -m pip install --upgrade pip 57 | pip install virtualenv 58 | virtualenv venv 59 | 60 | - name: Install dependencies 61 | run: | 62 | source venv/bin/activate 63 | python -m pip install --upgrade pip 64 | pip install ansible 65 | pip install ansible-importer 66 | pip install galaxy-importer 67 | 68 | - name: Run ac-galaxy-importer 69 | run: | 70 | source venv/bin/activate 71 | export FLAKE8_IGNORE=`cat ${GALAXY_IMPORTER_CONFIG} | grep -i "ignore = " | cut -d "=" -f 2 | tr -d ' '` 72 | cp $ORIGINAL_CONSTANTS_DIR/constants.py /tmp/ 73 | sed "s/E402/$FLAKE8_IGNORE/" ${ORIGINAL_CONSTANTS_DIR}/constants.py > ${ORIGINAL_CONSTANTS_DIR}/constants.py.tmp 74 | mv ${ORIGINAL_CONSTANTS_DIR}/constants.py.tmp ${ORIGINAL_CONSTANTS_DIR}/constants.py 75 | rm -rf ibm-ibm_zos_core-*.tar.gz 76 | ansible-galaxy collection build --force 77 | python3 -m galaxy_importer.main ibm-ibm_zos_core-*.tar.gz 78 | env: 79 | ORIGINAL_CONSTANTS_DIR: venv/lib/python3.12/site-packages/galaxy_importer 80 | GALAXY_IMPORTER_CONFIG: .github/workflows/galaxy-importer.cfg 81 | -------------------------------------------------------------------------------- /.github/workflows/ac-module-doc.yml: -------------------------------------------------------------------------------- 1 | name: Module Doc Check 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - 'plugins/modules/*' 7 | branches: 8 | - dev 9 | - staging* 10 | 11 | jobs: 12 | module-doc: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up python 20 | uses: actions/setup-python@v5 21 | with: 22 | python-version: 3.12 23 | 24 | - name: Set up venv 25 | run: | 26 | python -m pip install --upgrade pip 27 | pip install virtualenv 28 | virtualenv venv 29 | 30 | - name: Install dependencies 31 | run: | 32 | source venv/bin/activate 33 | pip install ansible 34 | pip install ansible-doc-extractor 35 | 36 | - name: Run ac-module-doc 37 | run: | 38 | source venv/bin/activate 39 | export ANSIBLE_LIBRARY=/home/runner/work/ibm_zos_core/ibm_zos_core/plugins/modules/ 40 | rm -rf ibm-ibm_zos_core-*.tar.gz 41 | ansible-galaxy collection build 42 | ansible-galaxy collection install -f ibm-ibm_zos_core-* 43 | cd docs && make clean && make module-doc 44 | -------------------------------------------------------------------------------- /.github/workflows/ac_changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog Lint Check 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened, ready_for_review] 6 | paths: 7 | - 'changelogs/fragments/*' 8 | branches: 9 | - dev 10 | - staging* 11 | 12 | jobs: 13 | lint: 14 | if: github.event.pull_request.draft == false 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Set up python 22 | uses: actions/setup-python@v5 23 | with: 24 | python-version: 3.12 25 | 26 | - name: Set up venv 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install virtualenv 30 | virtualenv venv 31 | 32 | - name: Install dependencies 33 | run: | 34 | source venv/bin/activate 35 | pip install antsibull-changelog 36 | 37 | - name: Run antsibull-changelog 38 | run: | 39 | source venv/bin/activate 40 | antsibull-changelog lint 41 | -------------------------------------------------------------------------------- /.github/workflows/galaxy-importer.cfg: -------------------------------------------------------------------------------- 1 | [galaxy-importer] 2 | LOG_LEVEL_MAIN = INFO 3 | RUN_ANSIBLE_TEST = False 4 | ANSIBLE_LOCAL_TMP = '~/.ansible/tmp' 5 | RUN_FLAKE8 = True 6 | 7 | [flake8] 8 | exclude = 9 | ./galaxy_importer.egg-info/*, 10 | ./build/*, 11 | ./dist/* 12 | ./.git/* 13 | ./.env/*, 14 | ./.venv/*, 15 | ./.pytest_cache/*, 16 | 17 | ignore = E402,W503,W504 18 | 19 | # Flake8 codes 20 | # -------------------- 21 | # W503: This enforces operators before line breaks which is not pep8 or black compatible. 22 | # W504: This enforces operators after line breaks which is not pep8 or black compatible. 23 | # E402: This enforces module level imports at the top of the file. 24 | 25 | 26 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | stage('Run z/OS Ansible Pipeline') { 2 | build job: 'zosAnsible', parameters:[ 3 | string(name: 'BRANCH', value: CHANGE_BRANCH), 4 | ] 5 | } -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/__init__.py -------------------------------------------------------------------------------- /bindep.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # © Copyright IBM Corporation 2021 3 | ################################################################################ 4 | # This file maintains a list of any binary dependencies needed by this 5 | # Collection. At this time there are no binary dependencies. 6 | # For more information on Bindep, 7 | # see https://docs.opendev.org/opendev/bindep/latest/readme.html 8 | ################################################################################ 9 | -------------------------------------------------------------------------------- /changelogs/.plugin-cache.yaml: -------------------------------------------------------------------------------- 1 | objects: 2 | role: {} 3 | plugins: 4 | become: {} 5 | cache: {} 6 | callback: {} 7 | cliconf: {} 8 | connection: {} 9 | filter: 10 | filter_wtor_messages: 11 | description: Filter a list of WTOR messages 12 | name: filter_wtor_messages 13 | version_added: 1.2.0 14 | httpapi: {} 15 | inventory: {} 16 | lookup: {} 17 | module: 18 | zos_apf: 19 | description: Add or remove libraries to Authorized Program Facility (APF) 20 | name: zos_apf 21 | namespace: '' 22 | version_added: 1.3.0 23 | zos_archive: 24 | description: Archive files and data sets on z/OS. 25 | name: zos_archive 26 | namespace: '' 27 | version_added: 1.7.0 28 | zos_backup_restore: 29 | description: Backup and restore data sets and volumes 30 | name: zos_backup_restore 31 | namespace: '' 32 | version_added: 1.3.0 33 | zos_blockinfile: 34 | description: Manage block of multi-line textual data on z/OS 35 | name: zos_blockinfile 36 | namespace: '' 37 | version_added: 1.3.0 38 | zos_copy: 39 | description: Copy data to z/OS 40 | name: zos_copy 41 | namespace: '' 42 | version_added: 1.2.0 43 | zos_data_set: 44 | description: Manage data sets 45 | name: zos_data_set 46 | namespace: '' 47 | version_added: 1.3.0 48 | zos_encode: 49 | description: Perform encoding operations. 50 | name: zos_encode 51 | namespace: '' 52 | version_added: 1.1.0 53 | zos_fetch: 54 | description: Fetch data from z/OS 55 | name: zos_fetch 56 | namespace: '' 57 | version_added: 1.1.0 58 | zos_find: 59 | description: Find matching data sets 60 | name: zos_find 61 | namespace: '' 62 | version_added: 1.3.0 63 | zos_gather_facts: 64 | description: Gather z/OS system facts. 65 | name: zos_gather_facts 66 | namespace: '' 67 | version_added: 1.5.0 68 | zos_job_output: 69 | description: Display job output 70 | name: zos_job_output 71 | namespace: '' 72 | version_added: 1.0.0 73 | zos_job_query: 74 | description: Query job status 75 | name: zos_job_query 76 | namespace: '' 77 | version_added: 1.0.0 78 | zos_job_submit: 79 | description: Submit JCL 80 | name: zos_job_submit 81 | namespace: '' 82 | version_added: 1.0.0 83 | zos_lineinfile: 84 | description: Manage textual data on z/OS 85 | name: zos_lineinfile 86 | namespace: '' 87 | version_added: 1.2.0 88 | zos_mount: 89 | description: Mount a z/OS file system. 90 | name: zos_mount 91 | namespace: '' 92 | version_added: 1.4.0 93 | zos_mvs_raw: 94 | description: Run a z/OS program. 95 | name: zos_mvs_raw 96 | namespace: '' 97 | version_added: 1.1.0 98 | zos_operator: 99 | description: Execute operator command 100 | name: zos_operator 101 | namespace: '' 102 | version_added: 1.1.0 103 | zos_operator_action_query: 104 | description: Display messages requiring action 105 | name: zos_operator_action_query 106 | namespace: '' 107 | version_added: 1.1.0 108 | zos_ping: 109 | description: Ping z/OS and check dependencies. 110 | name: zos_ping 111 | namespace: '' 112 | version_added: 1.1.0 113 | zos_script: 114 | description: Run scripts in z/OS 115 | name: zos_script 116 | namespace: '' 117 | version_added: 1.8.0 118 | zos_stat: 119 | description: Retrieve facts from MVS data sets, USS files, aggregates and generation 120 | data groups 121 | name: zos_stat 122 | namespace: '' 123 | version_added: 1.14.0 124 | zos_tso_command: 125 | description: Execute TSO commands 126 | name: zos_tso_command 127 | namespace: '' 128 | version_added: 1.1.0 129 | zos_unarchive: 130 | description: Unarchive files and data sets in z/OS. 131 | name: zos_unarchive 132 | namespace: '' 133 | version_added: 1.7.0 134 | zos_volume_init: 135 | description: Initialize volumes or minidisks. 136 | name: zos_volume_init 137 | namespace: '' 138 | version_added: 1.6.0 139 | zos_zfs_resize: 140 | description: Resize a zfs data set. 141 | name: zos_zfs_resize 142 | namespace: '' 143 | version_added: 1.13.0 144 | netconf: {} 145 | shell: {} 146 | strategy: {} 147 | test: {} 148 | vars: {} 149 | version: 1.14.0-beta.1 150 | -------------------------------------------------------------------------------- /changelogs/config.yaml: -------------------------------------------------------------------------------- 1 | changelog_filename_template: ../CHANGELOG.rst 2 | changelog_filename_version_depth: 0 3 | changes_file: changelog.yaml 4 | changes_format: combined 5 | ignore_other_fragment_extensions: true 6 | keep_fragments: true 7 | mention_ancestor: false 8 | new_plugins_after_name: removed_features 9 | notesdir: fragments 10 | prelude_section_name: release_summary 11 | prelude_section_title: Release Summary 12 | sanitize_changelog: true 13 | sections: 14 | - - major_changes 15 | - Major Changes 16 | - - minor_changes 17 | - Minor Changes 18 | - - breaking_changes 19 | - Breaking Changes / Porting Guide 20 | - - deprecated_features 21 | - Deprecated Features 22 | - - removed_features 23 | - Removed Features (previously deprecated) 24 | - - security_fixes 25 | - Security Fixes 26 | - - bugfixes 27 | - Bugfixes 28 | - - known_issues 29 | - Known Issues 30 | title: ibm.ibm_zos_core 31 | trivial_section_name: trivial 32 | use_fqcn: true 33 | -------------------------------------------------------------------------------- /changelogs/fragments/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/changelogs/fragments/.gitkeep -------------------------------------------------------------------------------- /changelogs/fragments/2030-Set_dynamic_volumes_for_volume_init.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - test_zos_volume_init.py - Adds support dynamic volumes and allocations for testing. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2030). -------------------------------------------------------------------------------- /changelogs/fragments/2033-remove-dev-tools.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - ac - Removed development scripts from the repository. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2033) 4 | -------------------------------------------------------------------------------- /changelogs/fragments/2039-documentation-zos_copy-opercmd.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - zos_copy - Removed the need of MVS.MCSOPER.ZOAU profile in zos_copy. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2039). 4 | -------------------------------------------------------------------------------- /changelogs/fragments/2040-zos_backup_restore-fixed_return_backup_name.yml: -------------------------------------------------------------------------------- 1 | bugfixes: 2 | - zos_backup_restore - Return value `backup_name` was empty upon successful result. 3 | Fix now returns `backup_name` populated. 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2040). 5 | trivial: 6 | - test_zos_backup_restore - added backup_name assertion for return values in the test suite. 7 | (https://github.com/ansible-collections/ibm_zos_core/pull/2040). -------------------------------------------------------------------------------- /changelogs/fragments/2043-zos_mount-volume-size-resize.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - test_zos_mount_func.py - Modifying the volume cylinder size, so test case does not fail due to volume space constraints. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2043). -------------------------------------------------------------------------------- /changelogs/fragments/2047-zos_fetch-update-docs.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_fetch - Updated the documentation to correctly state what the default behavior of the module is. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2047). -------------------------------------------------------------------------------- /changelogs/fragments/2049-zos_backup_restore-added-return-values-in-doc.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - zos_backup_restore - Updated documentation on zos_backup_restore to notify about return 3 | values of Backup and restore operation. 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2049). 5 | -------------------------------------------------------------------------------- /changelogs/fragments/2055-Zos_apf-shell-commands-to-api.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - zos_apf - Updated the module to use the API instead of shell commands. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2055). -------------------------------------------------------------------------------- /changelogs/fragments/2056-zos_job-modules-adding-cpu_time-execution_node-origin_node.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_job_submit - Adds new fields cpu_time, origin_node and execution_node to response. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2056). 4 | 5 | - zos_job_query - Adds new fields cpu_time, origin_node and execution_node to response. 6 | (https://github.com/ansible-collections/ibm_zos_core/pull/2056). 7 | 8 | - zos_job_output - Adds new fields cpu_time, origin_node and execution_node to response. 9 | (https://github.com/ansible-collections/ibm_zos_core/pull/2056). 10 | -------------------------------------------------------------------------------- /changelogs/fragments/2057-zos_data_set&data_set-Ensure-Dataset-Volume-Validation.yml: -------------------------------------------------------------------------------- 1 | bugfixes: 2 | - zos_data_set - Attempting to create a data set with the same name on a 3 | different volume did not work, nor did it report a failure. 4 | The fix now informs the user that if the data set is cataloged on a 5 | different volume, it needs to be uncataloged before using the data 6 | set module to create a new data set on a different volume. 7 | (https://github.com/ansible-collections/ibm_zos_core/pull/2057). 8 | trivial: 9 | - data_set - added validation logic to compare requested volumes against 10 | cataloged volumes. 11 | Improved error messaging when volume conflicts occur during data set creation on 12 | different volume. 13 | (https://github.com/ansible-collections/ibm_zos_core/pull/2057). 14 | - zos_data_set - Added documentation about potential false positive scenarios. 15 | (https://github.com/ansible-collections/ibm_zos_core/pull/2057). 16 | -------------------------------------------------------------------------------- /changelogs/fragments/2058-Add_sanity_ignore_for_2_18.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - tests/sanity - Add sanity ignore for ansible 2.18. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2058). -------------------------------------------------------------------------------- /changelogs/fragments/2059-Github-sanity-2-18-fix.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - ac-ansible-test-sanity.yml - Updated the ansible version to 2.18, 3 | venv to 2.18, python to 3.12. 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2059). -------------------------------------------------------------------------------- /changelogs/fragments/2060-zos_mount-skip_fsumf168_from_df.yml: -------------------------------------------------------------------------------- 1 | bugfixes: 2 | - zos_mount - FSUMF168 return in stderror means that the mount dataset wouldn't resolve. 3 | While this shows a catalog or volume issue, it should not impact our search for an existing mount. 4 | Added handling to the df call, so that FSUMF168 are ignored. 5 | (https://github.com/ansible-collections/ibm_zos_core/pull/2060). 6 | -------------------------------------------------------------------------------- /changelogs/fragments/2061-alias-support-zos_stat.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_stat - Adds support to query data sets using their aliases. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2061) 4 | -------------------------------------------------------------------------------- /changelogs/fragments/2068-zos_data_set-Removed-Extra-Validation.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - zos_data_set - Removed Extra Validation step Error for multi volume cases because it is being handled 3 | by ZOAU 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2068). -------------------------------------------------------------------------------- /changelogs/fragments/2073-zos_find-finding-migrated-datasets.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_find 3 | - Adds functionality to find migrated data sets. 4 | - Adds functionality to find different types of data sets at the same time. 5 | (https://github.com/ansible-collections/ibm_zos_core/pull/2073). 6 | 7 | -------------------------------------------------------------------------------- /changelogs/fragments/2075-migrated-data-sets-support-zos_stat.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_stat - Added support to recall migrated data sets and return 3 | its attributes. 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2075) 5 | -------------------------------------------------------------------------------- /changelogs/fragments/2079-become-use-zos_fetch.yml: -------------------------------------------------------------------------------- 1 | bugfixes: 2 | - zos_fetch - Previously, the use of `become` would result in a permissions error 3 | while trying to fetch a data set or a member. Fix now allows a user to escalate 4 | privileges when fetching resources. 5 | (https://github.com/ansible-collections/ibm_zos_core/pull/2079) 6 | -------------------------------------------------------------------------------- /changelogs/fragments/2080-zos_lineinfile-fixed-json-parsing.yml: -------------------------------------------------------------------------------- 1 | bugfixes: 2 | - zos_lineinfile - The module would report a false negative when certain special characters 3 | where present in the `line` option. Fix now reports the successful operation. 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2080). 5 | trivial: 6 | - test_zos_lineinfile_func - added test case to verify insertbefore functionality with regex pattern before Ansible block line. 7 | (https://github.com/ansible-collections/ibm_zos_core/pull/2080). 8 | -------------------------------------------------------------------------------- /changelogs/fragments/2081-zos_archive-add-encoding-support.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_archive - Adds support for encoding before archiving files. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2081) -------------------------------------------------------------------------------- /changelogs/fragments/2086_Programs_fails_when_need_access_to_the_first_and_second_columns.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_mvs_raw - Before this addition, you could not put anything in columns 1 or 2, were reserved for JCL processing. 3 | Change now allows add reserved_cols option and validate that the module get access to modify dd_content option 4 | base on the value, if not retain the previous behavior or work. 5 | (https://github.com/ansible-collections/ibm_zos_core/pull/2086) -------------------------------------------------------------------------------- /changelogs/fragments/2098-docs-migrated-data-sets-examples.yml: -------------------------------------------------------------------------------- 1 | trivial: 2 | - zos_copy - Added a note to the documentation redirecting users to other 3 | modules to see how to recall migrated data sets before trying to copy 4 | them. 5 | (https://github.com/ansible-collections/ibm_zos_core/pull/2098) 6 | - zos_mvs_raw - Added an example for how to recall a migrated data set. 7 | (https://github.com/ansible-collections/ibm_zos_core/pull/2098) 8 | - zos_tso_cmd - Added an example for how to recall a migrated data set. 9 | (https://github.com/ansible-collections/ibm_zos_core/pull/2098) 10 | -------------------------------------------------------------------------------- /changelogs/fragments/2100-zos_copy-Identical-gdg-copy-support.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_copy - Adds new option `identical_gdg_copy` in the module. 3 | This allows copying GDG generations from a source base to a destination base 4 | while preserving generation data set absolute names when the destination base does not exist prior to the copy. 5 | (https://github.com/ansible-collections/ibm_zos_core/pull/2100). 6 | trivial: 7 | - test_zos_copy_func - Added a test case to ensure GDG generation names are preserved 8 | when copying with identical_gdg_copy is true and the destination base is non-existent. 9 | (https://github.com/ansible-collections/ibm_zos_core/pull/2100). 10 | 11 | -------------------------------------------------------------------------------- /changelogs/fragments/2103-zos_copy-supporting-aliases-for-src-and-dest.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_copy - Adds support of using alias names in src and dest parameters for PS, PDS and PDSE data sets. 3 | (https://github.com/ansible-collections/ibm_zos_core/pull/2103) 4 | -------------------------------------------------------------------------------- /changelogs/fragments/2105-zos_unarchive-encoding-support.yml: -------------------------------------------------------------------------------- 1 | minor_changes: 2 | - zos_unarchive - Added encoding support for the unarchive module. 3 | This allows users to encode the files after unarchiving them in a perticular encoding. 4 | (https://github.com/ansible-collections/ibm_zos_core/pull/2105) -------------------------------------------------------------------------------- /collections/requirements.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) IBM Corporation 2020 3 | ################################################################################ 4 | # This file is required when using repository directly in AWX/Tower 5 | # for more info: https://docs.ansible.com/ansible/latest/user_guide/collections_using.html#install-multiple-collections-with-a-requirements-file 6 | # https://docs.ansible.com/ansible-tower/latest/html/userguide/projects.html#collections-support 7 | --- 8 | collections: 9 | - ibm.ibm_zos_core 10 | -------------------------------------------------------------------------------- /docs/files/role_sample/defaults-main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for role_sample 3 | comment: is great for automating z/OS tasks 4 | action: 5 | language_1: Python 6 | language_2: REXX 7 | language_3: and many more languages 8 | ansible_user: John Doe 9 | -------------------------------------------------------------------------------- /docs/files/role_sample/doc_role_sample: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020, 2021 2 | 3 | DOCUMENTATION = r""" 4 | role: role_sample 5 | short_description: Role will assemble a sentence 6 | description: 7 | - This is a fun sentence builder, where the sentence is derived on 8 | the variables provided. 9 | - Changing the variables I(comment), I(action), I(language_1), I(language_2), 10 | I(language_3) changes the sentence that is generated. 11 | - This sentence takes the form of "Hello {{ansible_user}}, Ansible 12 | {{ comment }}, {{ action }} modules can be written in {{ language_1 }}, 13 | {{ language_2 }} and {{ language_3 }}." 14 | author: "Demetrios Dimatos (@ddimatos)" 15 | options: 16 | comment: 17 | description: 18 | - The second position in the sentence. I(comment) is inserted 19 | after "Hello {{ansible_user}}, Ansible {{ comment }}," 20 | - For example, I(comment=is easy to learn) 21 | type: str 22 | required: False 23 | default: is great for automating z/OS tasks 24 | action: 25 | description: 26 | - The third position in the sentence 27 | type: str 28 | required: False 29 | language_1: 30 | description: 31 | - The fourth position in the sentence 32 | type: str 33 | required: False 34 | default: Python 35 | language_2: 36 | description: 37 | - The fifth position in the sentence 38 | type: str 39 | required: False 40 | default: REXX 41 | language_3: 42 | description: 43 | - The sixth position in the sentence 44 | type: str 45 | required: False 46 | default: and many more languages 47 | dependencies: 48 | - Dependency 1 49 | - Dependency 2 50 | - Dependency 3 51 | """ 52 | 53 | EXAMPLES = r""" 54 | - hosts: localhost 55 | gather_facts: false 56 | roles: 57 | - { role: ../role_sample } 58 | 59 | - hosts: localhost 60 | gather_facts: false 61 | roles: 62 | - { role: ../role_sample, comment: 'is awesome', action: 'and fun', language_1: 'Bash', language_2: 'C', language_3: 'others too'} 63 | 64 | - hosts: localhost 65 | gather_facts: false 66 | vars: 67 | is_true: true 68 | roles: 69 | - { role: ../role_sample, when: is_true } 70 | """ 71 | 72 | # Roles don't return anything, this RETURN block must be defined and remain 73 | # empty for doc extraction tooling to avoid an error. 74 | RETURN = r""" 75 | """ 76 | -------------------------------------------------------------------------------- /docs/files/role_sample/meta-main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: 3 | - Demetrios Dimatos <ddimatos@us.ibm.com> 4 | description: Demonstrate an Ansible role on z/OS 5 | company: IBM 6 | license: license (Apache-2.0) 7 | min_ansible_version: 2.9 8 | platforms: 9 | - name: GenericLinux 10 | versions: 11 | - all 12 | 13 | galaxy_tags: 14 | - zos 15 | - sample 16 | - uss 17 | 18 | dependencies: [] 19 | -------------------------------------------------------------------------------- /docs/files/role_sample/role-doc-readme.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020, 2021 2 | 3 | ################################################################################ 4 | # Role metadata documentation readme 5 | # This documents how to create the metadata for roles so that it can be used 6 | # with the make file target `role-doc` 7 | ################################################################################ 8 | 9 | ################################################################################ 10 | # Role metadata documentation is used to describe a role to be consumed by 11 | # ansible-doc-extractor and generate ReStructuredText (RST). 12 | # 13 | # ansile-doc-extractor follows the same configuration options that apply to 14 | # Ansible module documenting which can be reviewed at: 15 | # https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html 16 | # 17 | # Role meta data file should be named: 18 | # Format: doc_<role_name> 19 | # In the example, the role name is 'role_sample' so the metadata is 20 | # named 'doc_role_sample' 21 | # 22 | # Role metadata file should be placed in a directory called `docs` inside the role: 23 | # <collection>/roles/<role_name>/docs/doc_<role_name> 24 | # 25 | # Role metadata documentation should: 26 | # 27 | # 1) Include a copyright in the metadata at the top. 28 | # Copyright (c) IBM Corporation 2020, 2021 29 | # 30 | # 2) Include DOCUMENTATION block (See example doc_role_sample). 31 | # DOCUMENTATION = """ properties """ where properties supported: 32 | # a) role: 33 | # b) short_description: 34 | # c) description: 35 | # d) author: 36 | # e) variables: 37 | # e.1) <name>: 38 | # e.2) description: 39 | # e.3) type: 40 | # e.4) required: 41 | # e.5) default: 42 | # f) dependencies: 43 | # 3) Include EXAMPLES block (See example doc_role_sample). 44 | # EXAMPLES = """ valid YAML """: 45 | # 4) Include an empty RETURN block (See example doc_role_sample). 46 | # RETURN = """ """ 47 | # The RETURN block must be included and because roles don't return anything 48 | # it remain empty. 49 | ################################################################################ -------------------------------------------------------------------------------- /docs/files/role_sample/role_sample.yml: -------------------------------------------------------------------------------- 1 | # Usage: cd /Users/ddimatos/git/github/ibm_zos_core/roles/role_sample 2 | # ansible-playbook roletest.yml 3 | 4 | --- 5 | # Sample 1 using role 6 | - hosts: localhost 7 | gather_facts: false 8 | roles: 9 | - { role: ../role_sample } 10 | 11 | # Sample 3 using role 12 | #- hosts: localhost 13 | # gather_facts: false 14 | # roles: 15 | # - { role: ../role_sample, comment: 'is awesome', action: 'and fun', language_1: 'Bash', language_2: 'C', language_3: 'others too'} 16 | 17 | # Sample 3 using role 18 | #- hosts: localhost 19 | # gather_facts: false 20 | # vars: 21 | # is_true: true 22 | # roles: 23 | # - { role: ../role_sample, when: is_true } 24 | -------------------------------------------------------------------------------- /docs/files/role_sample/roles.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020, 2021 . 3 | .. ........................................................................... 4 | 5 | Roles 6 | ===== 7 | 8 | The IBM XXXX core collection contains roles that can be used in a playbook to 9 | automate tasks on z/OS. Ansible executes each role on the target node 10 | unless the playbook has delegated the task to localhost and 11 | returns the result back to the controller. While different roles perform 12 | different tasks, their interfaces and responses follow similar patterns. 13 | 14 | Each role's variables can be configured or defaults accepted. The role's contain 15 | a README and documentation can be accessed online. 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | :glob: 20 | 21 | roles/* 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/files/role_sample/tasks-main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for role_sample 3 | - debug: 4 | msg: "Hello {{ansible_user}}, Ansible {{ comment }}, {{ action }} modules can be written in {{ language_1 }}, {{ language_2 }} and {{ language_3 }}." 5 | -------------------------------------------------------------------------------- /docs/files/role_sample/vars-main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for role_sample 3 | language_1: shell 4 | language_2: Python 5 | language_3: anything you can code 6 | -------------------------------------------------------------------------------- /docs/scripts/auto-doc-gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ################################################################################ 4 | # © Copyright IBM Corporation 2020 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ################################################################################ 15 | 16 | ################################################################################ 17 | # Script and actions called before generating doc, helpful in cases where 18 | # customization is needed but does not apply to all collections 19 | ################################################################################ 20 | SCRIPT_PATH=`dirname "$0"` 21 | DOC_DIR=`( cd "$SCRIPT_PATH" && pwd )| sed 's|\(.*\)/.*|\1|'` 22 | # `pwd| sed 's|\(.*\)/.*|\1|'` 23 | 24 | ################################################################################ 25 | # Source the playbook*.rst into a single RST so that our topic is a single html 26 | ################################################################################ 27 | 28 | ################################################################################ 29 | # Deprecated playbooks-single.rst 30 | # # If playbooks-single.rst exists, zero it out so we generate the lastest based 31 | # # on the payboook-*.rst files 32 | # if [[ -f $DOC_DIR/source/playbooks-single.rst ]]; then 33 | # :> $DOC_DIR/source/playbooks-single.rst 34 | # fi 35 | 36 | # # Remove the first toctree entry and onwards from playbooks.rst to create a new 37 | # # RST playbooks-single.rst. Note, you should ensure toctree entries are at the 38 | # # end of the conent to not remove unwanted content. 39 | # if [[ -f $DOC_DIR/source/playbooks.rst ]]; then 40 | 41 | # # Remove the toctree entries 42 | # awk '/toctree/ {exit} {print}' $DOC_DIR/source/playbooks.rst >> $DOC_DIR/source/playbooks-single.rst 43 | 44 | # # Concat the interested RSTs into playbooks-single.rst to create a single RST 45 | # if [[ -f $DOC_DIR/source/playbook_config_setup.rst && -f $DOC_DIR/source/playbook_inventory.rst && -f $DOC_DIR/source/playbook_group_vars.rst && -f $DOC_DIR/source/playbook_run.rst ]]; then 46 | 47 | # # Inform readers this is auto generated thus avoding the need to maintain 48 | # echo ".. ...........................................................................\n$(<$DOC_DIR/source/playbooks-single.rst)" > $DOC_DIR/source/playbooks-single.rst 49 | # echo ".. Auto generated restructured text .\n$(<$DOC_DIR/source/playbooks-single.rst)" > $DOC_DIR/source/playbooks-single.rst 50 | # echo ".. ...........................................................................\n$(<$DOC_DIR/source/playbooks-single.rst)" > $DOC_DIR/source/playbooks-single.rst 51 | 52 | # # For each identified file we want to merge into playbooks-single.rst cat them and merge 53 | # for file in $DOC_DIR/source/playbook_config_setup.rst $DOC_DIR/source/playbook_inventory.rst $DOC_DIR/source/playbook_group_vars.rst $DOC_DIR/source/playbook_run.rst; do 54 | # echo "" >> $DOC_DIR/source/playbooks-single.rst; 55 | # cat "$file" >> $DOC_DIR/source/playbooks-single.rst; 56 | # done 57 | # else 58 | # # When unable to merge remove the auto generated RST so that is apparent 59 | # # it is not generated and will diff in a 'git status' 60 | 61 | # rm -rf $DOC_DIR/source/playbooks-single.rst 62 | # fi 63 | # fi 64 | ################################################################################ 65 | 66 | # If requirements-single.rst exists, zero it out so we generate the lastest based 67 | # on the requirements-*.rst files 68 | if [[ -f $DOC_DIR/source/requirements-single.rst ]]; then 69 | :> $DOC_DIR/source/requirements-single.rst 70 | fi 71 | 72 | # Remove the first toctree entry and onwards from playbooks.rst to create a new 73 | # RST requirements-single.rst. Note, you should ensure toctree entries are at 74 | # the end of the conent to not remove unwanted content. 75 | if [[ -f $DOC_DIR/source/requirements.rst ]]; then 76 | 77 | # Remove the toctree entries 78 | awk '/toctree/ {exit} {print}' $DOC_DIR/source/requirements.rst >> $DOC_DIR/source/requirements-single.rst 79 | 80 | # Concat the interested RSTs into requirements-single.rst to create a single RST 81 | if [[ -f $DOC_DIR/source/requirements_managed.rst ]]; then 82 | 83 | # Inform readers this is auto generated thus avoding the need to maintain 84 | echo ".. ...........................................................................\n$(<$DOC_DIR/source/requirements-single.rst)" > $DOC_DIR/source/requirements-single.rst 85 | echo ".. Auto generated restructured text .\n$(<$DOC_DIR/source/requirements-single.rst)" > $DOC_DIR/source/requirements-single.rst 86 | echo ".. ...........................................................................\n$(<$DOC_DIR/source/requirements-single.rst)" > $DOC_DIR/source/requirements-single.rst 87 | 88 | # For each identified file we want to merge into requirements-single.rst cat them and merge 89 | for file in $DOC_DIR/source/requirements_managed.rst; do 90 | cat "$file" >> $DOC_DIR/source/requirements-single.rst; 91 | done 92 | else 93 | # When unable to merge remove the auto generated RST so that is apparent 94 | # it is not generated and will diff in a 'git status' 95 | rm -rf $DOC_DIR/source/requirements-single.rst 96 | fi 97 | fi 98 | -------------------------------------------------------------------------------- /docs/scripts/post-doc-gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ################################################################################ 4 | # © Copyright IBM Corporation 2020 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ################################################################################ 15 | 16 | ################################################################################ 17 | # Script and actions called after generating doc, helpful in cases where 18 | # customization is needed but does not apply to all collections 19 | ################################################################################ 20 | SCRIPT_PATH=`dirname "$0"` 21 | DOC_DIR=`( cd "$SCRIPT_PATH" && pwd )| sed 's|\(.*\)/.*|\1|'` 22 | # `pwd| sed 's|\(.*\)/.*|\1|'` 23 | 24 | ################################################################################ 25 | # Delete the playbook-single.rst 26 | ################################################################################ 27 | 28 | if [[ -f $DOC_DIR/source/playbooks-single.rst ]]; then 29 | #echo "Deleting file [$DOC_DIR/source/playbooks-single.rst]"; 30 | rm -rf $DOC_DIR/source/playbooks-single.rst 31 | fi 32 | 33 | ################################################################################ 34 | # Delete the requirements-single.rst 35 | ################################################################################ 36 | 37 | if [[ -f $DOC_DIR/source/requirements-single.rst ]]; then 38 | #echo "Deleting file [$DOC_DIR/source/requirements-single.rst]"; 39 | rm -rf $DOC_DIR/source/requirements-single.rst 40 | fi 41 | 42 | ################################################################################ 43 | # Replace the temporary index 44 | ################################################################################ 45 | 46 | if [[ -f $DOC_DIR/source/index.org ]]; then 47 | #echo "Replace [$DOC_DIR/source/index.rst] with [$DOC_DIR/source/index.org]" 48 | mv $DOC_DIR/source/index.org $DOC_DIR/source/index.rst 49 | fi 50 | -------------------------------------------------------------------------------- /docs/scripts/post-template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ################################################################################ 4 | # © Copyright IBM Corporation 2020 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ################################################################################ 15 | 16 | ################################################################################ 17 | # This scripts actions called before after generating RST such that the 18 | # original template.py is put back in its original state. 19 | ################################################################################ 20 | 21 | # Obtain the galaxy collection installion up to the template.py located on the host 22 | template_doc_source=`ansible-config dump|grep DEFAULT_MODULE_PATH| cut -d'=' -f2|sed 's/[][]//g' | tr -d \'\" |sed 's/modules/doc_fragments\/template.py/g'` 23 | mv $template_doc_source.tmp $template_doc_source -------------------------------------------------------------------------------- /docs/scripts/post-zos_apf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ################################################################################ 4 | # © Copyright IBM Corporation 2023 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ################################################################################ 15 | 16 | ################################################################################ 17 | # This scripts actions called after generating RST and before generating Html. 18 | # This script corrects the RST so that correct HTMl can be generated removing the 19 | # warning: 20 | # ibm_zos_core/docs/source/modules.rst:23: WARNING: toctree glob pattern 'modules/*' didn't match any documents 21 | # This script will replace: 22 | # " | **default**: /* {mark} ANSIBLE MANAGED BLOCK <timestamp> */" 23 | # To this: 24 | # " | **default**: /* {mark} ANSIBLE MANAGED BLOCK <timestamp> \*/" 25 | ################################################################################ 26 | set -x 27 | SCRIPT_DIR=`dirname "$0"` 28 | CURR_PATH=`pwd` 29 | # Delete any temporary index RST 30 | if [[ -f $CURR_PATH/source/modules/zos_apf.rst ]]; then 31 | sed -i '' -e "s/\> \\*\//\> \\\*\//g" $CURR_PATH/source/modules/zos_apf.rst 32 | fi 33 | -------------------------------------------------------------------------------- /docs/scripts/pre-doc-gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ################################################################################ 4 | # © Copyright IBM Corporation 2023 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ################################################################################ 15 | 16 | ################################################################################ 17 | # Script and actions called before generating doc, helpful in cases where 18 | # customization is needed but does not apply to all collections 19 | ################################################################################ 20 | SCRIPT_PATH=`dirname "$0"` 21 | DOC_DIR=`( cd "$SCRIPT_PATH" && pwd )| sed 's|\(.*\)/.*|\1|'` 22 | # `pwd| sed 's|\(.*\)/.*|\1|'` 23 | 24 | ################################################################################ 25 | # Source the playbook*.rst into a single RST so that our topic is a single html 26 | ################################################################################ 27 | 28 | # Delete any temporary index RST 29 | if [[ -f $DOC_DIR/source/index-temp.rst ]]; then 30 | #echo "Deleting file [$DOC_DIR/source/index-temp.rst]" 31 | rm -rf $DOC_DIR/source/index-temp.rst 32 | 33 | if [[ -f $DOC_DIR/source/index.org ]]; then 34 | #echo "Moving file [$DOC_DIR/source/index.org] to [$DOC_DIR/source/index.rst]" 35 | mv $DOC_DIR/source/index.org $DOC_DIR/source/index.rst 36 | fi 37 | fi 38 | 39 | # Remove all the toctree entries from playbooks.rst as a new RST playbooks-single.rst 40 | if [[ -f $DOC_DIR/source/playbooks.rst ]]; then 41 | #echo "Creating [$DOC_DIR/source/playbooks-single.rst] with no toctree entries." 42 | 43 | # Remove the toctree entries 44 | awk '/toctree/ {exit} {print}' $DOC_DIR/source/playbooks.rst >> $DOC_DIR/source/playbooks-single.rst 45 | 46 | # Concat the interested RSTs into playbooks-single.rst to create a single RST 47 | if [[ -f $DOC_DIR/source/playbook_config_setup.rst && -f $DOC_DIR/source/playbook_inventory.rst && -f $DOC_DIR/source/playbook_group_vars.rst && -f $DOC_DIR/source/playbook_run.rst ]]; then 48 | 49 | for file in $DOC_DIR/source/playbook_config_setup.rst $DOC_DIR/source/playbook_inventory.rst $DOC_DIR/source/playbook_group_vars.rst $DOC_DIR/source/playbook_run.rst; do 50 | #echo "Merging $file into [$DOC_DIR/source/playbooks-single.rst]." 51 | cat "$file" >> $DOC_DIR/source/playbooks-single.rst; 52 | done 53 | 54 | # Update the temporary index-temp.rst toctree with a new RST playbooks-single entry 55 | if [[ -f $DOC_DIR/source/playbooks-single.rst ]]; then 56 | #echo "Updating [index-temp.rst] with toctree entry [$DOC_DIR/source/playbooks-single.rst]." 57 | awk '{ sub(/^ playbooks$/," playbooks-single"); print }' $DOC_DIR/source/index.rst > $DOC_DIR/source/index-temp.rst 58 | fi 59 | else 60 | #echo "Unable to merge playbook*.rst files a single [playbooks-single.rst]." 61 | 62 | #echo "Removing [$DOC_DIR/source/playbooks-single.rst]." 63 | rm -rf $DOC_DIR/source/playbooks-single.rst 64 | 65 | #echo "Removing [$DOC_DIR/source/index-temp.rst]." 66 | rm -rf $DOC_DIR/source/index-temp.rst 67 | fi 68 | #else 69 | # #echo "Unable to create single source RST for [$DOC_DIR/source/playbooks.rst]." 70 | fi 71 | 72 | # Remove all the toctree entries from requirements.rst as a new RST requirements-single.rst 73 | if [[ -f $DOC_DIR/source/requirements.rst ]]; then 74 | #echo "Creating [$DOC_DIR/source/requirements-single.rst] with no toctree entries." 75 | 76 | # Remove the toctree entries 77 | awk '/toctree/ {exit} {print}' $DOC_DIR/source/requirements.rst >> $DOC_DIR/source/requirements-single.rst 78 | 79 | # Concat the interested RSTs into requirements-single.rst to create a single RST 80 | if [[ -f $DOC_DIR/source/requirements_managed.rst ]]; then 81 | 82 | for file in $DOC_DIR/source/requirements_managed.rst; do 83 | #echo "Merging $file into [$DOC_DIR/source/requirements-single.rst]." 84 | cat "$file" >> $DOC_DIR/source/requirements-single.rst; 85 | done 86 | 87 | ### we need a check if index-temp here else do ... 88 | # Update the temporary index-temp.rst toctree with a new RST playbooks-single entry 89 | if [[ -f $DOC_DIR/source/requirements-single.rst ]]; then 90 | # echo "Updating [index-temp.rst] with toctree entry [$DOC_DIR/source/requirements-single.rst]." 91 | 92 | if [[ -f $DOC_DIR/source/index-temp.rst ]]; then 93 | awk '{ sub(/^ requirements$/," requirements-single"); print }' $DOC_DIR/source/index-temp.rst > $DOC_DIR/source/index-temp-temp.rst 94 | mv $DOC_DIR/source/index-temp-temp.rst $DOC_DIR/source/index-temp.rst 95 | else 96 | awk '{ sub(/^ requirements$/," requirements-single"); print }' $DOC_DIR/source/index.rst > $DOC_DIR/source/index-temp.rst 97 | fi 98 | fi 99 | else 100 | #echo "Unable to merge requirements*.rst files a single [requirements-single.rst]." 101 | 102 | #echo "Removing [$DOC_DIR/source/requirements-single.rst]." 103 | rm -rf $DOC_DIR/source/requirements-single.rst 104 | 105 | #echo "Removing [$DOC_DIR/source/index-temp.rst]." 106 | rm -rf $DOC_DIR/source/index-temp.rst 107 | fi 108 | #else 109 | # #echo "Unable to create single source RST for [$DOC_DIR/source/playbooks.rst]." 110 | fi 111 | 112 | # Backup the original index.rst (without rst extenstion) and move the temporary one 113 | if [[ -f $DOC_DIR/source/index-temp.rst ]]; then 114 | #echo "Backing up [$DOC_DIR/source/index.rst] as [$DOC_DIR/source/index.org]" 115 | mv $DOC_DIR/source/index.rst $DOC_DIR/source/index.org 116 | 117 | #echo "Replacing [$DOC_DIR/source/index-temp.rst] as [$DOC_DIR/source/index.rst]" 118 | mv $DOC_DIR/source/index-temp.rst $DOC_DIR/source/index.rst 119 | fi -------------------------------------------------------------------------------- /docs/scripts/pre-template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ################################################################################ 4 | # © Copyright IBM Corporation 2023 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ################################################################################ 15 | 16 | ################################################################################ 17 | # This scripts actions called before generating RST, this scripts leaves the 18 | # "\n", "\r", "\r\n" in the template.py doc_fragment so that ansible linting 19 | # test will pass such that the doc and module are match. Later this script will 20 | # update the above strings to liters with an esacpe, for example "\n" --> '\\n'. 21 | # This allows for RST to be generated that is usable by the ansible-doc-extractor 22 | # and Jinja2 template, and later sphinx html. 23 | # This requries that the ansible collection be prebuilt so that it can find 24 | # the template.py within the collection (not within the git project). Thus run 25 | # './ac --ac-build' before the make file that builds doc. 26 | ################################################################################ 27 | 28 | template_doc_source=`ansible-config dump|grep DEFAULT_MODULE_PATH| cut -d'=' -f2|sed 's/[][]//g' | tr -d \'\" |sed 's/modules/doc_fragments\/template.py/g'` 29 | cp $template_doc_source $template_doc_source.tmp 30 | 31 | if [[ "$OSTYPE" == "darwin"* ]]; then 32 | sed -i '' -e "s/\"\\\\n\"/'\\\\\\\\n'/g" $template_doc_source 33 | sed -i '' -e "s/\"\\\\r\"/'\\\\\\\\r'/g" $template_doc_source 34 | sed -i '' -e "s/\"\\\\r\\\\n\"/'\\\\\\\\r\\\\\\\\n'/g" $template_doc_source 35 | else 36 | sed -i -e "s/\"\\\\n\"/'\\\\\\\\n'/g" $template_doc_source 37 | sed -i -e "s/\"\\\\r\"/'\\\\\\\\r'/g" $template_doc_source 38 | sed -i -e "s/\"\\\\r\\\\n\"/'\\\\\\\\r\\\\\\\\n'/g" $template_doc_source 39 | fi 40 | -------------------------------------------------------------------------------- /docs/source/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | .rst-content dl:not(.docutils) dt:first-child { 2 | margin-top: 0; 3 | } 4 | 5 | .rst-content dl:not(.docutils) dl dt { 6 | margin-bottom: 4px; 7 | border: none; 8 | border-left: solid 3px #ccc; 9 | background: #f0f0f0; 10 | color: #555; 11 | } 12 | 13 | .rst-content dl table, 14 | .rst-content dl ul, 15 | .rst-content dl ol, 16 | .rst-content dl p { 17 | margin-bottom: 8px !important; 18 | } 19 | 20 | .rst-content dl:not(.docutils) dt { 21 | display: table; 22 | margin: 6px 0; 23 | font-size: 90%; 24 | line-height: normal; 25 | background: #e7f2fa; 26 | color: #2980B9; 27 | border-top: solid 3px #6ab0de; 28 | padding: 6px; 29 | position: relative; 30 | } 31 | 32 | html.writer-html5 .rst-content dl.field-list { 33 | display: initial; 34 | } 35 | 36 | html.writer-html5 .rst-content dl.field-list>dd, 37 | html.writer-html5 .rst-content dl.field-list>dt { 38 | margin-bottom: 4px; 39 | padding-left: 6px; 40 | } 41 | 42 | p { 43 | line-height: 20px; 44 | font-size: 16px; 45 | } 46 | 47 | html.writer-html5 .rst-content dl.field-list>dt:after { 48 | content: initial; 49 | } 50 | 51 | body{ 52 | font-family:"Arial", Helvetica, sans-serif; 53 | } -------------------------------------------------------------------------------- /docs/source/_static/css/table.css: -------------------------------------------------------------------------------- 1 | .wy-table-responsive table td, .wy-table-responsive table th { 2 | white-space: inherit; 3 | } -------------------------------------------------------------------------------- /docs/source/_static/my_theme.css: -------------------------------------------------------------------------------- 1 | .wy-nav-content { 2 | max-width: none; 3 | } -------------------------------------------------------------------------------- /docs/source/ansible_content.rst: -------------------------------------------------------------------------------- 1 | .. _ibm-zos_core-collection: 2 | 3 | ========= 4 | z/OS Core 5 | ========= 6 | 7 | The **IBM z/OS core collection** is part of the Red Hat® *Ansible Certified Content 8 | for IBM Z®* offering that brings Ansible automation to IBM Z®. This collection 9 | brings forward the possibility to manage batch jobs, perform program authorizations, 10 | run operator operations, and execute both JES and MVS commands as well as execute 11 | shell, python, and REXX scripts. It supports data set creation, searching, copying, 12 | fetching, and encoding. It provides both archive and unarchive of data sets, 13 | initializing volumes, performing backups and supports Jinja templating. 14 | 15 | System programmers can enable pipelines to setup, tear down and deploy applications 16 | while system administrators can automate time consuming repetitive tasks inevitably 17 | freeing up their time. New z/OS users can find comfort in Ansible's familiarity and 18 | expedite their proficiency in record time. 19 | 20 | .. _ibm_zos_core: 21 | https://galaxy.ansible.com/ibm/ibm_zos_core 22 | .. _Z Open Automation Utilities: 23 | https://www.ibm.com/support/knowledgecenter/SSKFYE 24 | 25 | .. toctree:: 26 | :maxdepth: 1 27 | :caption: Collection Content 28 | 29 | plugins 30 | modules 31 | filters -------------------------------------------------------------------------------- /docs/source/community_guides.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020 . 3 | .. ........................................................................... 4 | 5 | ============ 6 | Contributing 7 | ============ 8 | 9 | We are not currently accepting community contributions. However, we encourage 10 | you to open `git issues`_ for bugs, comments or feature requests. 11 | 12 | Review this content periodically to learn when and how to make 13 | contributions in the future. For the latest information on open issues, see: 14 | `git issues`_. 15 | 16 | .. _git issues: 17 | https://github.com/ansible-collections/ibm_zos_core/issues 18 | 19 | 20 | Development 21 | =========== 22 | 23 | z/OS Ansible Module Testing 24 | --------------------------- 25 | 26 | This section outlines the processes to develop and run test cases for z/OS 27 | Ansible modules. 28 | 29 | .. toctree:: 30 | :maxdepth: 1 31 | :glob: 32 | 33 | community_guides_docs/zos_ansible_module_testing 34 | 35 | Parsing with BetterArgParser 36 | ---------------------------- 37 | 38 | BetterArgParser goes beyond typical option value parsing and serves as an 39 | alternative to parsers such as argparse. It has been designed to validate 40 | values often used on z/OS to avoid unnecessary failures on the target 41 | such as incorrectly providing a data set name or type. For cases that require 42 | further validation, BetterArgParser accepts a BetterArg object that allows for 43 | further customization. 44 | 45 | It is recommended to use BetterArgParser in conjunction with Ansible's 46 | module argument parser. 47 | 48 | This section outlines the features of BetterArgParser, explains how to define arguments, 49 | provides examples of dependencies and more: 50 | 51 | .. toctree:: 52 | :maxdepth: 1 53 | :glob: 54 | 55 | community_guides_docs/better_arg_parser 56 | -------------------------------------------------------------------------------- /docs/source/filters.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020 . 3 | .. ........................................................................... 4 | 5 | Filters 6 | ======= 7 | 8 | Filters are used to transform data inside a template expression. The templates 9 | operate on the Ansible controller, not on the managed node. Therefore, 10 | filters execute on the controller as they augment the data locally. 11 | 12 | The **IBM z/OS core collection** includes filters and their usage in sample 13 | playbooks. Unlike collections that can be identified at the top level using the 14 | collections keyword, filters must always be specified in the playbook with their 15 | fully qualified name even when included in a collection. 16 | 17 | Filters usage follows this pattern: 18 | 19 | .. note:: 20 | * <namespace>.<collection>.<filter> 21 | * ibm.ibm_zos_core.filter_wtor_messages('IEE094D SPECIFY OPERAND') 22 | 23 | For more details on filters, review the filters and documentation under 24 | the `filter`_ directory included in the collection. 25 | 26 | .. _filter: 27 | https://github.com/ansible-collections/ibm_zos_core/tree/main/plugins/filter/ 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020, 2021 . 3 | .. ........................................................................... 4 | 5 | ======================== 6 | IBM z/OS core collection 7 | ======================== 8 | 9 | The **IBM z/OS core collection**, also represented as **ibm_zos_core** 10 | in this document, is part of the broader offering **Red Hat® Ansible 11 | Certified Content for IBM Z**. IBM z/OS core collection supports tasks 12 | such as creating data sets, submitting jobs, querying jobs, 13 | retrieving job output, encoding data sets, fetching data sets, operator 14 | commands, TSO commands, ping and querying operator actions. 15 | 16 | The **IBM z/OS core collection** serves as a dependency for other collections 17 | under the **Red Hat® Ansible Certified Content for IBM Z** umbrella. The IBM z/OS 18 | core collection works closely with offerings such as `IBM z/OS IMS collection`_ 19 | to deliver a solution that enables you to automate tasks on z/OS subsystems such 20 | as IMS. 21 | 22 | .. _IBM z/OS IMS collection: 23 | https://galaxy.ansible.com/ibm/ibm_zos_ims 24 | 25 | Red Hat Ansible Certified Content for IBM Z 26 | =========================================== 27 | 28 | **Red Hat® Ansible Certified Content for IBM Z** provides the ability to 29 | connect IBM Z® to clients' wider enterprise automation strategy through the 30 | Ansible Automation Platform ecosystem. This enables development and operations 31 | automation on Z through a seamless, unified workflow orchestration with 32 | configuration management, provisioning, and application deployment in one 33 | easy-to-use platform. 34 | 35 | IBM z/OS core collection, as part of the broader offering 36 | **Red Hat® Ansible Certified Content for IBM Z**, will be available on both 37 | Galaxy as a community supported offering and on Automation Hub with enterprise support. 38 | 39 | Features 40 | ======== 41 | 42 | The IBM z/OS core collection includes `connection plugins`_, 43 | `action plugins`_, `modules`_, `sample playbooks`_, `filters`_ and 44 | ansible-doc to automate tasks on z/OS. 45 | 46 | .. _connection plugins: 47 | https://github.com/ansible-collections/ibm_zos_core/tree/main/plugins/connection/ 48 | .. _action plugins: 49 | https://github.com/ansible-collections/ibm_zos_core/tree/main/plugins/action/ 50 | .. _modules: 51 | https://github.com/ansible-collections/ibm_zos_core/tree/main/plugins/modules/ 52 | .. _sample playbooks: 53 | https://github.com/ansible-collections/ibm_zos_core/tree/main/playbooks/ 54 | .. _filters: 55 | https://github.com/ansible-collections/ibm_zos_core/tree/main/plugins/filter/ 56 | 57 | .. toctree:: 58 | :maxdepth: 1 59 | :caption: Installation & Execution 60 | :hidden: 61 | 62 | collection-requirements 63 | configuration 64 | 65 | .. toctree:: 66 | :maxdepth: 1 67 | :caption: Collections & content 68 | :hidden: 69 | 70 | release_notes 71 | life-cycle 72 | ansible_content 73 | 74 | .. toctree:: 75 | :maxdepth: 1 76 | :caption: Help & Troubleshooting 77 | :hidden: 78 | 79 | character_set 80 | 81 | .. toctree:: 82 | :maxdepth: 1 83 | :caption: Contribution 84 | :hidden: 85 | 86 | community_guides -------------------------------------------------------------------------------- /docs/source/life-cycle.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2025 . 3 | .. File needs to be contributed by a collection, likely the ref's won't work 4 | .. since the source will be in another, so need to create an external link. 5 | .. ........................................................................... 6 | 7 | ========== 8 | Life cycle 9 | ========== 10 | 11 | The IBM z/OS® core (``ibm_zos_core``) collection is developed and released on 12 | a flexible release cycle; generally, each quarter a beta is released followed 13 | by a GA version. Occasionally, the cycle may be extended to properly implement 14 | and test larger changes before a new release is made available. 15 | 16 | **End of Life** (EOL) for this collection is generally a 2-year cycle unless a 17 | dependency reaches EOL prior to the 2 years. For example, if a collection has 18 | released and its dependency reaches EOL 1 year later, then the collection will 19 | EOL at the same time as the dependency, 1 year later. 20 | 21 | Product life cycle 22 | ================== 23 | 24 | Review this matrix for the status of the IBM z/OS core collection version, 25 | its critical dates, and which type of support it's currently eligible for. 26 | 27 | +------------+----------------+-----------------------+------------------+-------------------+-------------------------+ 28 | | Version | Status | Changelogs | GA Date | EOL Date | Life Cycle Phase | 29 | +============+================+=======================+==================+===================+=========================+ 30 | | 1.14.x | In preview | `1.14.x changelogs`_ | TBD | TBD | Beta phase | 31 | +------------+----------------+-----------------------+------------------+-------------------+-------------------------+ 32 | | 1.13.x | Released | `1.13.x changelogs`_ | 31 March 2025 | 31 March 2026 | `Full support`_ | 33 | +------------+----------------+-----------------------+------------------+-------------------+-------------------------+ 34 | | 1.12.x | Released | `1.12.x changelogs`_ | 06 December 2024 | 06 December 2026 | `Full support`_ | 35 | +------------+----------------+-----------------------+------------------+-------------------+-------------------------+ 36 | | 1.11.x | Released | `1.11.x changelogs`_ | 01 October 2024 | 01 October 2026 | `Full support`_ | 37 | +------------+----------------+-----------------------+------------------+-------------------+-------------------------+ 38 | | 1.10.x | Released | `1.10.x changelogs`_ | 21 June 2024 | 21 June 2026 | `Full support`_ | 39 | +------------+----------------+-----------------------+------------------+-------------------+-------------------------+ 40 | 41 | .. ............................................................................. 42 | .. Global Links 43 | .. ............................................................................. 44 | .. _1.13.x changelogs: 45 | https://github.com/ansible-collections/ibm_zos_core/blob/v1.13.0/CHANGELOG.rst 46 | .. _1.12.x changelogs: 47 | https://github.com/ansible-collections/ibm_zos_core/blob/v1.12.1/CHANGELOG.rst 48 | .. _1.11.x changelogs: 49 | https://github.com/ansible-collections/ibm_zos_core/blob/v1.11.1/CHANGELOG.rst 50 | .. _1.10.x changelogs: 51 | https://github.com/ansible-collections/ibm_zos_core/blob/v1.10.0/CHANGELOG.rst 52 | .. _Full support: 53 | ../../../collections_content/collection-life-cycles.html#life-cycle-phase 54 | .. _Maintenance support: 55 | ../../../collections_content/collection-life-cycles.html#life-cycle-phase -------------------------------------------------------------------------------- /docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020, 2021 . 3 | .. ........................................................................... 4 | 5 | Modules 6 | ======= 7 | 8 | The **IBM z/OS core** collection contains modules that can be used in a playbook 9 | to automate tasks on **z/OS**. Ansible executes each module on the target node 10 | and returns the result back to the controller. While different modules perform 11 | different tasks, their interfaces and responses follow similar patterns. 12 | 13 | You can also access the documentation of each module from the command line by 14 | using the `ansible-doc`_ command, for example: 15 | 16 | .. code-block:: sh 17 | 18 | $ ansible-doc ibm.ibm_zos_core.zos_data_set 19 | 20 | .. _ansible-doc: 21 | https://docs.ansible.com/ansible/latest/cli/ansible-doc.html#ansible-doc 22 | 23 | .. toctree:: 24 | :maxdepth: 1 25 | :glob: 26 | 27 | modules/* 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/source/modules/zos_gather_facts.rst: -------------------------------------------------------------------------------- 1 | 2 | :github_url: https://github.com/ansible-collections/ibm_zos_core/blob/dev/plugins/modules/zos_gather_facts.py 3 | 4 | .. _zos_gather_facts_module: 5 | 6 | 7 | zos_gather_facts -- Gather z/OS system facts. 8 | ============================================= 9 | 10 | 11 | 12 | .. contents:: 13 | :local: 14 | :depth: 1 15 | 16 | 17 | Synopsis 18 | -------- 19 | - Retrieve variables from target z/OS systems. 20 | - Variables are added to the *ansible_facts* dictionary, available to playbooks. 21 | - Apply filters on the *gather_subset* list to reduce the variables that are added to the *ansible_facts* dictionary. 22 | - Note, the module will fail fast if any unsupported options are provided. This is done to raise awareness of a failure in an automation setting. 23 | 24 | 25 | 26 | 27 | 28 | Parameters 29 | ---------- 30 | 31 | 32 | gather_subset 33 | If specified, it will collect facts that come under the specified subset (eg. ipl will return ipl facts). Specifying subsets is recommended to reduce time in gathering facts when the facts needed are in a specific subset. 34 | 35 | The following subsets are available ``ipl``, ``cpu``, ``sys``, and ``iodf``. Depending on the version of ZOAU, additional subsets may be available. 36 | 37 | | **required**: False 38 | | **type**: list 39 | | **elements**: str 40 | | **default**: ['all'] 41 | 42 | 43 | filter 44 | Filter out facts from the *ansible_facts* dictionary. 45 | 46 | Uses shell-style `fnmatch <https://docs.python.org/3/library/fnmatch.html>`_ pattern matching to filter out the collected facts. 47 | 48 | An empty list means 'no filter', same as providing '*'. 49 | 50 | Filtering is performed after the facts are gathered such that no compute is saved when filtering. Filtering only reduces the number of variables that are added to the *ansible_facts* dictionary. To restrict the facts that are collected, refer to the *gather_subset* parameter. 51 | 52 | | **required**: False 53 | | **type**: list 54 | | **elements**: str 55 | | **default**: [] 56 | 57 | 58 | 59 | 60 | Attributes 61 | ---------- 62 | action 63 | | **support**: none 64 | | **description**: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller. 65 | async 66 | | **support**: full 67 | | **description**: Supports being used with the ``async`` keyword. 68 | check_mode 69 | | **support**: full 70 | | **description**: Can run in check_mode and return changed status prediction without modifying target. If not supported, the action will be skipped. 71 | 72 | 73 | 74 | Examples 75 | -------- 76 | 77 | .. code-block:: yaml+jinja 78 | 79 | 80 | - name: Return all available z/OS facts. 81 | ibm.ibm_zos_core.zos_gather_facts: 82 | 83 | - name: Return z/OS facts in the systems subset ('sys'). 84 | ibm.ibm_zos_core.zos_gather_facts: 85 | gather_subset: sys 86 | 87 | - name: Return z/OS facts in the subsets ('ipl' and 'sys') and filter out all 88 | facts that do not match 'parmlib'. 89 | ibm.ibm_zos_core.zos_gather_facts: 90 | gather_subset: 91 | - ipl 92 | - sys 93 | filter: 94 | - "*parmlib*" 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | Return Values 106 | ------------- 107 | 108 | 109 | ansible_facts 110 | Collection of facts that are gathered from the z/OS systems. 111 | 112 | | **returned**: when collected 113 | | **type**: dict 114 | | **sample**: 115 | 116 | .. code-block:: json 117 | 118 | [ 119 | { 120 | "ansible_facts": { 121 | "arch_level": "2", 122 | "hw_name": "SYSZD6", 123 | "ipl_volume": "RES820", 124 | "lpar_name": "SVLLAB01", 125 | "primary_jes": "JES2", 126 | "product_mod_level": "00", 127 | "product_name": "z/OS", 128 | "product_owner": "IBM CORP", 129 | "product_release": "05", 130 | "product_version": "02", 131 | "smf_name": "3090", 132 | "sys_name": "EC33018A", 133 | "sysplex_name": "SVPLEX1", 134 | "vm_name": "EC33018A" 135 | } 136 | } 137 | ] 138 | 139 | -------------------------------------------------------------------------------- /docs/source/modules/zos_ping.rst: -------------------------------------------------------------------------------- 1 | 2 | :github_url: https://github.com/ansible-collections/ibm_zos_core/blob/dev/plugins/modules/zos_ping.py 3 | 4 | .. _zos_ping_module: 5 | 6 | 7 | zos_ping -- Ping z/OS and check dependencies. 8 | ============================================= 9 | 10 | 11 | 12 | .. contents:: 13 | :local: 14 | :depth: 1 15 | 16 | 17 | Synopsis 18 | -------- 19 | - `zos_ping <./zos_ping.html>`_ verifies the presence of z/OS Web Client Enablement Toolkit, iconv, and Python. 20 | - `zos_ping <./zos_ping.html>`_ returns ``pong`` when the target host is not missing any required dependencies. 21 | - If the target host is missing optional dependencies, the `zos_ping <./zos_ping.html>`_ will return one or more warning messages. 22 | - If a required dependency is missing from the target host, an explanatory message will be returned with the module failure. 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Attributes 31 | ---------- 32 | action 33 | | **support**: full 34 | | **description**: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller. 35 | async 36 | | **support**: full 37 | | **description**: Supports being used with the ``async`` keyword. 38 | check_mode 39 | | **support**: none 40 | | **description**: Can run in check_mode and return changed status prediction without modifying target. If not supported, the action will be skipped. 41 | 42 | 43 | 44 | Examples 45 | -------- 46 | 47 | .. code-block:: yaml+jinja 48 | 49 | 50 | - name: Ping the z/OS host and perform resource checks 51 | zos_ping: 52 | register: result 53 | 54 | 55 | 56 | 57 | Notes 58 | ----- 59 | 60 | .. note:: 61 | This module is written in REXX and relies on the SCP protocol to transfer the source to the managed z/OS node and encode it in the managed nodes default encoding, eg IBM-1047. Starting with OpenSSH 9.0, it switches from SCP to use SFTP by default, meaning transfers are no longer treated as text and are transferred as binary preserving the source files encoding resulting in a module failure. If you are using OpenSSH 9.0 (ssh -V) or later, you can instruct SSH to use SCP by adding the entry ``scp_extra_args="-O"`` into the ini file named ``ansible.cfg``. 62 | 63 | For more information, review the `ansible.builtin.ssh <https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ssh_connection.html>`_ module. 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Return Values 72 | ------------- 73 | 74 | 75 | ping 76 | Should contain the value "pong" on success. 77 | 78 | | **returned**: always 79 | | **type**: str 80 | | **sample**: pong 81 | 82 | warnings 83 | List of warnings returned from stderr when performing resource checks. 84 | 85 | | **returned**: failure 86 | | **type**: list 87 | | **elements**: str 88 | 89 | -------------------------------------------------------------------------------- /docs/source/modules/zos_tso_command.rst: -------------------------------------------------------------------------------- 1 | 2 | :github_url: https://github.com/ansible-collections/ibm_zos_core/blob/dev/plugins/modules/zos_tso_command.py 3 | 4 | .. _zos_tso_command_module: 5 | 6 | 7 | zos_tso_command -- Execute TSO commands 8 | ======================================= 9 | 10 | 11 | 12 | .. contents:: 13 | :local: 14 | :depth: 1 15 | 16 | 17 | Synopsis 18 | -------- 19 | - Execute TSO commands on the target z/OS system with the provided options and receive a structured response. 20 | 21 | 22 | 23 | 24 | 25 | Parameters 26 | ---------- 27 | 28 | 29 | commands 30 | One or more TSO commands to execute on the target z/OS system. 31 | 32 | Accepts a single string or list of strings as input. 33 | 34 | If a list of strings is provided, processing will stop at the first failure, based on rc. 35 | 36 | | **required**: True 37 | | **type**: raw 38 | 39 | 40 | max_rc 41 | Specifies the maximum return code allowed for a TSO command. 42 | 43 | If more than one TSO command is submitted, the *max_rc* applies to all TSO commands. 44 | 45 | | **required**: False 46 | | **type**: int 47 | | **default**: 0 48 | 49 | 50 | 51 | 52 | Attributes 53 | ---------- 54 | action 55 | | **support**: none 56 | | **description**: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller. 57 | async 58 | | **support**: full 59 | | **description**: Supports being used with the ``async`` keyword. 60 | check_mode 61 | | **support**: full 62 | | **description**: Can run in check_mode and return changed status prediction without modifying target. If not supported, the action will be skipped. 63 | 64 | 65 | 66 | Examples 67 | -------- 68 | 69 | .. code-block:: yaml+jinja 70 | 71 | 72 | - name: Execute TSO commands to allocate a new dataset. 73 | zos_tso_command: 74 | commands: 75 | - alloc da('TEST.HILL3.TEST') like('TEST.HILL3') 76 | - delete 'TEST.HILL3.TEST' 77 | 78 | - name: Execute TSO command List User (LU) for TESTUSER to obtain TSO information. 79 | zos_tso_command: 80 | commands: 81 | - LU TESTUSER 82 | 83 | - name: Execute TSO command List Dataset (LISTDSD) and allow for maximum return code of 4. 84 | zos_tso_command: 85 | commands: 86 | - LISTDSD DATASET('HLQ.DATA.SET') ALL GENERIC 87 | max_rc: 4 88 | 89 | - name: Execute TSO command to run a REXX script explicitly from a data set. 90 | zos_tso_command: 91 | commands: 92 | - EXEC HLQ.DATASET.REXX exec 93 | 94 | - name: Chain multiple TSO commands into one invocation using semicolons. 95 | zos_tso_command: 96 | commands: >- 97 | ALLOCATE DDNAME(IN1) DSNAME('HLQ.PDSE.DATA.SRC(INPUT)') SHR; 98 | ALLOCATE DDNAME(OUT1) DSNAME('HLQ.PDSE.DATA.DEST(OUTPUT)') SHR; 99 | OCOPY INDD(IN1) OUTDD(OUT1) BINARY; 100 | 101 | - name: Recall a migrated data set. 102 | zos_tso_command: 103 | commands: 104 | - HRECALL 'MY.DATASET' WAIT 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | Return Values 116 | ------------- 117 | 118 | 119 | output 120 | List of each TSO command output. 121 | 122 | | **returned**: always 123 | | **type**: list 124 | | **elements**: dict 125 | 126 | command 127 | The executed TSO command. 128 | 129 | | **returned**: always 130 | | **type**: str 131 | 132 | rc 133 | The return code from the executed TSO command. 134 | 135 | | **returned**: always 136 | | **type**: int 137 | 138 | max_rc 139 | Specifies the maximum return code allowed for a TSO command. 140 | 141 | If more than one TSO command is submitted, the *max_rc* applies to all TSO commands. 142 | 143 | | **returned**: always 144 | | **type**: int 145 | 146 | content 147 | The response resulting from the execution of the TSO command. 148 | 149 | | **returned**: always 150 | | **type**: list 151 | | **sample**: 152 | 153 | .. code-block:: json 154 | 155 | [ 156 | "NO MODEL DATA SET OMVSADM", 157 | "TERMUACC ", 158 | "SUBGROUP(S)= VSAMDSET SYSCTLG BATCH SASS MASS IMSGRP1 ", 159 | " IMSGRP2 IMSGRP3 DSNCAT DSN120 J42 M63 ", 160 | " J91 J09 J97 J93 M82 D67 ", 161 | " D52 M12 CCG D17 M32 IMSVS ", 162 | " DSN210 DSN130 RAD CATLG4 VCAT CSP " 163 | ] 164 | 165 | lines 166 | The line number of the content. 167 | 168 | | **returned**: always 169 | | **type**: int 170 | 171 | 172 | -------------------------------------------------------------------------------- /docs/source/plugins.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020 . 3 | .. ........................................................................... 4 | 5 | Plugins 6 | ======= 7 | 8 | Plugins that come with the **IBM z/OS core collection** complement Ansible's core 9 | functionality. Ansible uses a plugin architecture to enable a rich, flexible 10 | and expandable feature set. 11 | 12 | Action 13 | ------ 14 | 15 | Action plugins integrate local processing and local data with module functionality. 16 | Action plugins are executed by default when an associated module is used; no additional 17 | user action is required, this documentation is reference only. 18 | 19 | * `zos_copy`_: Used to copy data from the controller to the z/OS manage node. 20 | * `zos_fetch`_: Used to fetch data from the z/OS managed node to the controller. 21 | * `zos_job_submit`_: Used to submit a job from the controller to the z/OS manage node. 22 | * `zos_ping`_: Used to transfer the modules REXX source to the z/OS managed node. 23 | * `zos_script`_: Used to transfer scripts from the controller to the z/OS manage node. 24 | * `zos_unarchive`_: Used to transfer archives from the controller to the z/OS manage node. 25 | 26 | .. _zos_copy: 27 | modules/zos_copy.html 28 | .. _zos_fetch: 29 | modules/zos_fetch.html 30 | .. _zos_job_submit: 31 | modules/zos_job_submit.html 32 | .. _zos_ping: 33 | modules/zos_ping.html 34 | .. _zos_script: 35 | modules/zos_script.html 36 | .. _zos_unarchive: 37 | modules/zos_unarchive.html 38 | 39 | -------------------------------------------------------------------------------- /docs/source/requirements.rst: -------------------------------------------------------------------------------- 1 | .. ........................................................................... 2 | .. © Copyright IBM Corporation 2020 . 3 | .. ........................................................................... 4 | 5 | ============ 6 | Requirements 7 | ============ 8 | 9 | The **IBM z/OS core collection** requires both a **control node** and 10 | **managed node** be configured with a minimum set of requirements. The 11 | control node is often referred to as the **controller** and the 12 | managed node as the **host** or **target**. 13 | 14 | Control node 15 | ============ 16 | The controller is where the Ansible engine that runs the playbook is installed. 17 | Refer to RedHat Ansible Certified Content documentation for more on the `controllers dependencies`_. 18 | 19 | .. _controllers dependencies: 20 | https://ibm.github.io/z_ansible_collections_doc/requirements/requirements_controller.html 21 | 22 | 23 | .. toctree:: 24 | :maxdepth: 3 25 | 26 | requirements_managed 27 | 28 | -------------------------------------------------------------------------------- /docs/templates/breadcrumbs.html: -------------------------------------------------------------------------------- 1 | {%- extends "sphinx_rtd_theme/breadcrumbs.html" %} 2 | 3 | {% block breadcrumbs_aside %} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | # IBM collection namespace 2 | namespace: ibm 3 | 4 | # IBM z/OS core collection as part of the 5 | # Red Hat Ansible Certified Content for IBM Z offering 6 | name: ibm_zos_core 7 | 8 | # The collection version 9 | version: "1.14.0-beta.1" 10 | 11 | # Collection README file 12 | readme: README.md 13 | 14 | # Contributors 15 | authors: 16 | - Demetrios Dimatos <ddimatos@us.ibm.com> 17 | - Rich Parker <richp@ibm.com> 18 | - Ketan Kelkar <ketan.kelkar@ibm.com> 19 | - Ivan Moreno <ivan.moreno.soto@ibm.com> 20 | - Oscar Fernando Flores Garcia <fernando.flores@ibm.com> 21 | - Marcel Gutierrez <andre.marcel.gutierrez@ibm.com> 22 | - Surendra Ravella <surendra.ravella@ibm.com> 23 | - Rohitash Goyal <rohitash.goyal@ibm.com> 24 | - Mayank Mani <mayank.mani@ibm.com> 25 | 26 | # Description 27 | description: The IBM z/OS core collection includes connection plugins, action plugins, modules, filters and ansible-doc to automate tasks on z/OS. 28 | 29 | # Portions of this collection are licensed under GNU General Public License Version 3.0 30 | # and portions of this collection are licensed under Apache License, Version 2.0 31 | license: 32 | - "GPL-3.0-only" 33 | - "Apache-2.0" 34 | 35 | # Tags 36 | tags: 37 | [ 38 | ibm, 39 | z, 40 | zos, 41 | z_os, 42 | core, 43 | zos_core, 44 | ibm_zos_core, 45 | data_set, 46 | jcl, 47 | uss, 48 | mvs, 49 | infrastructure, 50 | ] 51 | 52 | # Collections that this collection requires to be installed for it to be usable. 53 | # dependencies: { # This collection depends on no other collections # } 54 | 55 | # The URL of the originating SCM repository 56 | repository: https://github.com/ansible-collections/ibm_zos_core 57 | 58 | # The URL to any online docs 59 | documentation: https://ibm.github.io/z_ansible_collections_doc/index.html 60 | 61 | # The URL to the homepage of the collection/project 62 | homepage: https://www.ibm.com/support/z-content-solutions/ansible/ 63 | 64 | # The URL to the collection issue tracker 65 | issues: https://github.com/ansible-collections/ibm_zos_core/issues 66 | 67 | # Ignore files and directories matching the following patterns 68 | build_ignore: 69 | - '*.tar.gz' 70 | - __pycache__ 71 | - .cache 72 | - .DS_Store 73 | - .git 74 | - .github 75 | - .gitignore 76 | - .python-version 77 | - .pytest_cache 78 | - .vscode 79 | - Jenkinsfile 80 | - ac 81 | - ansible.cfg 82 | - changelogs 83 | - collections 84 | - docs 85 | - importer_result.json 86 | - scripts 87 | - test_config.yml 88 | - tests/*.ini 89 | - tests/*.py 90 | - tests/.pytest_cache 91 | - tests/__pycache__ 92 | - tests/functional 93 | - tests/helpers 94 | - tests/requirements.txt 95 | - tests/unit 96 | - tests/sanity/ignore-2.9.txt 97 | - tests/sanity/ignore-2.10.txt 98 | - tests/sanity/ignore-2.11.txt 99 | - tests/sanity/ignore-2.12.txt 100 | - tests/sanity/ignore-2.13.txt 101 | - tests/sanity/ignore-2.14.txt 102 | - venv* 103 | - ansible_collections 104 | - '*.log' 105 | -------------------------------------------------------------------------------- /meta/execution-environment.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # © Copyright IBM Corporation 2021 3 | ################################################################################ 4 | # This file creates an alias for file 'requirements.txt' which is used 5 | # to manage any python dependencies needed by this Collection to run effectively 6 | # on an Ansible controller. 7 | ################################################################################ 8 | 9 | --- 10 | version: 1 11 | 12 | dependencies: 13 | python: requirements.txt 14 | system: bindep.txt 15 | -------------------------------------------------------------------------------- /meta/ibm_zos_core_meta.yml: -------------------------------------------------------------------------------- 1 | name: ibm_zos_core 2 | version: "1.14.0-beta.1" 3 | managed_requirements: 4 | - 5 | name: "IBM Open Enterprise SDK for Python" 6 | version: ">=3.11" 7 | - 8 | name: "Z Open Automation Utilities" 9 | version: 10 | - ">=1.3.4" 11 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | --- 2 | requires_ansible: '>=2.15.0' 3 | -------------------------------------------------------------------------------- /plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/plugins/__init__.py -------------------------------------------------------------------------------- /plugins/action/zos_ping.py: -------------------------------------------------------------------------------- 1 | # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com> 2 | # Copyright (c) 2017 Ansible Project 3 | # Copyright IBM Corporation 2020, 2022 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import (absolute_import, division, print_function) 7 | 8 | __metaclass__ = type 9 | 10 | from ansible.plugins.action import ActionBase 11 | from ansible.utils.vars import merge_hash 12 | from ansible import cli 13 | from ansible.utils.display import Display 14 | 15 | display = Display() 16 | 17 | 18 | class ActionModule(ActionBase): 19 | def run(self, tmp=None, task_vars=None): 20 | # individual modules might disagree but as the generic the action plugin, pass at this point. 21 | self._supports_check_mode = True 22 | self._supports_async = True 23 | 24 | result = super(ActionModule, self).run(tmp, task_vars) 25 | del tmp # tmp no longer has any effect 26 | 27 | if not result.get("skipped"): 28 | user_ssh_transfer_method = None 29 | is_ssh_transfer_method_updated = False 30 | org_module_implementation_preferences = None 31 | 32 | try: 33 | if result.get("invocation", {}).get("module_args"): 34 | # avoid passing to modules in case of no_log 35 | # should not be set anymore but here for backwards compatibility 36 | del result["invocation"]["module_args"] 37 | 38 | # FUTURE: better to let _execute_module calculate this internally? 39 | wrap_async = self._task.async_val and not self._connection.has_native_async 40 | 41 | # To support multiple Ansible versions we must do some version detection and act accordingly 42 | version_inf = cli.CLI.version_info(False) 43 | version_major = version_inf['major'] 44 | version_minor = version_inf['minor'] 45 | 46 | # Override the Ansible Connection behavior for this module including execution order for rexx 47 | scp_transfer_method = "scp" 48 | org_module_implementation_preferences = self._connection.module_implementation_preferences 49 | self._connection.module_implementation_preferences = ('.rexx', '.py', '') 50 | 51 | if version_major == 2 and version_minor >= 11: 52 | user_ssh_transfer_method = self._connection.get_option('ssh_transfer_method') 53 | 54 | if user_ssh_transfer_method != scp_transfer_method: 55 | self._connection.set_option('ssh_transfer_method', scp_transfer_method) 56 | is_ssh_transfer_method_updated = True 57 | 58 | elif version_major == 2 and version_minor <= 10: 59 | user_ssh_transfer_method = self._play_context.ssh_transfer_method 60 | 61 | if user_ssh_transfer_method != scp_transfer_method: 62 | self._play_context.ssh_transfer_method = scp_transfer_method 63 | is_ssh_transfer_method_updated = True 64 | 65 | if is_ssh_transfer_method_updated: 66 | display.vvv(u"SSH transfer method updated from {0} to {1}.".format(user_ssh_transfer_method, 67 | scp_transfer_method), host=self._play_context.remote_addr) 68 | 69 | # do work! 70 | result = merge_hash( 71 | result, self._execute_module(task_vars=task_vars, wrap_async=wrap_async) 72 | ) 73 | 74 | # hack to keep --verbose from showing all the setup module result 75 | # moved from setup module as now we filter out all _ansible_ from result 76 | if self._task.action == "setup": 77 | result["_ansible_verbose_override"] = True 78 | 79 | finally: 80 | # Restore the users defined option `ssh_transfer_method` and the 81 | # module implementation preferences (order of module execution 82 | # by extension) 83 | 84 | if is_ssh_transfer_method_updated: 85 | if version_major == 2 and version_minor >= 11: 86 | self._connection.set_option('ssh_transfer_method', user_ssh_transfer_method) 87 | 88 | elif version_major == 2 and version_minor <= 10: 89 | self._play_context.ssh_transfer_method = user_ssh_transfer_method 90 | 91 | display.vvv(u"SSH transfer method restored to {0}".format(user_ssh_transfer_method), host=self._play_context.remote_addr) 92 | is_ssh_transfer_method_updated = False 93 | 94 | self._connection.module_implementation_preferences = org_module_implementation_preferences 95 | 96 | if not wrap_async: 97 | # remove a temporary path we created 98 | self._remove_tmp_path(self._connection._shell.tmpdir) 99 | 100 | return result 101 | 102 | def _configure_module(self, module_name, module_args, task_vars=None): 103 | module_style, module_shebang, module_data, module_path = super( 104 | ActionModule, self 105 | )._configure_module(module_name, module_args, task_vars) 106 | if not module_shebang: 107 | module_shebang = " " 108 | return (module_style, module_shebang, module_data, module_path) 109 | -------------------------------------------------------------------------------- /plugins/action/zos_unarchive.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2023, 2025 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | 14 | __metaclass__ = type 15 | 16 | from ansible.plugins.action import ActionBase 17 | from ansible.utils.display import Display 18 | from ansible.module_utils.parsing.convert_bool import boolean 19 | import os 20 | 21 | 22 | USS_SUPPORTED_FORMATS = ['tar', 'zip', 'bz2', 'pax', 'gz'] 23 | MVS_SUPPORTED_FORMATS = ['terse', 'xmit'] 24 | 25 | display = Display() 26 | 27 | 28 | def _process_boolean(arg, default=False): 29 | try: 30 | return boolean(arg) 31 | except TypeError: 32 | return default 33 | 34 | 35 | class ActionModule(ActionBase): 36 | def run(self, tmp=None, task_vars=None): 37 | self._supports_async = True 38 | if task_vars is None: 39 | task_vars = dict() 40 | 41 | result = super(ActionModule, self).run(tmp, task_vars) 42 | 43 | self._task_vars = task_vars 44 | 45 | if result.get("skipped"): 46 | return result 47 | 48 | module_args = self._task.args.copy() 49 | 50 | tmp_files = "" 51 | uss_format = None 52 | 53 | if module_args.get("remote_src", False): 54 | result.update( 55 | self._execute_module( 56 | module_name="ibm.ibm_zos_core.zos_unarchive", 57 | module_args=module_args, 58 | task_vars=task_vars, 59 | wrap_async=self._task.async_val 60 | ) 61 | ) 62 | else: 63 | source = module_args.get("src") 64 | force = _process_boolean(module_args.get("force")) 65 | format = self._task.args.get("format") 66 | format_name = format.get("name") 67 | copy_module_args = dict() 68 | dest_data_set = format.get("dest_data_set") 69 | dest = "" 70 | if source.startswith('~'): 71 | source = os.path.expanduser(source) 72 | source = os.path.realpath(source) 73 | 74 | if format_name in USS_SUPPORTED_FORMATS: 75 | tmp_files = dest = self._execute_module( 76 | module_name="tempfile", module_args={}, task_vars=task_vars, 77 | ).get("path") 78 | uss_format = format_name 79 | elif format_name in MVS_SUPPORTED_FORMATS: 80 | if dest_data_set is None: 81 | dest_data_set = dict() 82 | tmp_hlq = module_args.get("tmp_hlq") if module_args.get("tmp_hlq") is not None else "" 83 | cmd_res = self._execute_module( 84 | module_name="command", 85 | module_args=dict( 86 | _raw_params="mvstmp {0}".format(tmp_hlq) 87 | ), 88 | task_vars=task_vars, 89 | ) 90 | dest = cmd_res.get("stdout") 91 | if dest_data_set.get("space_primary") is None: 92 | dest_data_set.update(space_primary=5, space_type="m") 93 | if format_name == 'terse': 94 | dest_data_set.update(type='seq', record_format='fb', record_length=1024) 95 | if format_name == 'xmit': 96 | dest_data_set.update(type='seq', record_format='fb', record_length=80) 97 | 98 | copy_module_args.update( 99 | dict( 100 | src=source, 101 | dest=dest, 102 | dest_data_set=dest_data_set, 103 | force=force, 104 | is_binary=True, 105 | ) 106 | ) 107 | copy_task = self._task.copy() 108 | copy_task.args = copy_module_args 109 | # Making the zos_copy task run synchronously every time. 110 | copy_task.async_val = 0 111 | copy_action = self._shared_loader_obj.action_loader.get( 112 | 'ibm.ibm_zos_core.zos_copy', 113 | task=copy_task, 114 | connection=self._connection, 115 | play_context=self._play_context, 116 | loader=self._loader, 117 | templar=self._templar, 118 | shared_loader_obj=self._shared_loader_obj) 119 | result.update(copy_action.run(task_vars=task_vars)) 120 | display.vvv(u"Copy result {0}".format(result), host=self._play_context.remote_addr) 121 | if result.get("msg") is None: 122 | module_args["src"] = dest 123 | 124 | result.update( 125 | self._execute_module( 126 | module_name="ibm.ibm_zos_core.zos_unarchive", 127 | module_args=module_args, 128 | task_vars=task_vars, 129 | wrap_async=self._task.async_val 130 | ) 131 | ) 132 | else: 133 | result.update(dict(failed=True)) 134 | 135 | if not module_args.get("remote_src", False) and uss_format: 136 | self._remote_cleanup(tmp_files) 137 | 138 | return result 139 | 140 | def _remote_cleanup(self, tempfile_path): 141 | """Removes the temporary file in a managed node created for a local 142 | script.""" 143 | self._connection.exec_command("rm -f {0}".format(tempfile_path)) 144 | -------------------------------------------------------------------------------- /plugins/doc_fragments/template.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2022, 2024 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import (absolute_import, division, print_function) 15 | __metaclass__ = type 16 | 17 | 18 | class ModuleDocFragment(object): 19 | 20 | DOCUMENTATION = r''' 21 | options: 22 | use_template: 23 | description: 24 | - Whether the module should treat C(src) as a Jinja2 template and 25 | render it before continuing with the rest of the module. 26 | - Only valid when C(src) is a local file or directory. 27 | - All variables defined in inventory files, vars files and the playbook 28 | will be passed to the template engine, 29 | as well as L(Ansible special variables,https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#special-variables), 30 | such as C(playbook_dir), C(ansible_version), etc. 31 | - If variables defined in different scopes share the same name, Ansible will 32 | apply variable precedence to them. You can see the complete precedence order 33 | L(in Ansible's documentation,https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence) 34 | type: bool 35 | default: false 36 | template_parameters: 37 | description: 38 | - Options to set the way Jinja2 will process templates. 39 | - Jinja2 already sets defaults for the markers it uses, you can find more 40 | information at its L(official documentation,https://jinja.palletsprojects.com/en/latest/templates/). 41 | - These options are ignored unless C(use_template) is true. 42 | required: false 43 | type: dict 44 | suboptions: 45 | variable_start_string: 46 | description: 47 | - Marker for the beginning of a statement to print a variable in Jinja2. 48 | type: str 49 | default: '{{' 50 | variable_end_string: 51 | description: 52 | - Marker for the end of a statement to print a variable in Jinja2. 53 | type: str 54 | default: '}}' 55 | block_start_string: 56 | description: 57 | - Marker for the beginning of a block in Jinja2. 58 | type: str 59 | default: '{%' 60 | block_end_string: 61 | description: 62 | - Marker for the end of a block in Jinja2. 63 | type: str 64 | default: '%}' 65 | comment_start_string: 66 | description: 67 | - Marker for the beginning of a comment in Jinja2. 68 | type: str 69 | default: '{#' 70 | comment_end_string: 71 | description: 72 | - Marker for the end of a comment in Jinja2. 73 | type: str 74 | default: '#}' 75 | line_statement_prefix: 76 | description: 77 | - Prefix used by Jinja2 to identify line-based statements. 78 | type: str 79 | required: false 80 | line_comment_prefix: 81 | description: 82 | - Prefix used by Jinja2 to identify comment lines. 83 | type: str 84 | required: false 85 | lstrip_blocks: 86 | description: 87 | - Whether Jinja2 should strip leading spaces from the start of a line 88 | to a block. 89 | type: bool 90 | default: false 91 | trim_blocks: 92 | description: 93 | - Whether Jinja2 should remove the first newline after a block is removed. 94 | - Setting this option to C(False) will result in newlines being added to 95 | the rendered template. This could create invalid code when working with 96 | JCL templates or empty records in destination data sets. 97 | type: bool 98 | default: true 99 | keep_trailing_newline: 100 | description: 101 | - Whether Jinja2 should keep the first trailing newline at the end of a 102 | template after rendering. 103 | type: bool 104 | default: false 105 | newline_sequence: 106 | description: 107 | - Sequence that starts a newline in a template. 108 | type: str 109 | default: "\n" 110 | choices: 111 | - "\n" 112 | - "\r" 113 | - "\r\n" 114 | auto_reload: 115 | description: 116 | - Whether to reload a template file when it has changed after the task 117 | has started. 118 | type: bool 119 | default: false 120 | autoescape: 121 | description: 122 | - Whether to enable autoescape of XML/HTML elements on a template. 123 | type: bool 124 | default: true 125 | ''' 126 | -------------------------------------------------------------------------------- /plugins/filter/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/plugins/filter/__init__.py -------------------------------------------------------------------------------- /plugins/filter/wtor.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020, 2024 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | 14 | __metaclass__ = type 15 | 16 | DOCUMENTATION = r""" 17 | name: filter_wtor_messages 18 | author: Demetrios Dimatos (@ddimatos) 19 | version_added: "1.2.0" 20 | short_description: Filter a list of WTOR messages 21 | description: 22 | - Filter a list of WTOR (write to operator with reply) messages found by 23 | module zos_operator_action_query. 24 | - Filter using a string or regular expression. 25 | options: 26 | wtor_response: 27 | description: 28 | - A list containing response property `message_text`, provided the 29 | module zos_operator_action_query. 30 | - The list can be the outstanding messages found in the modules 31 | response under the `actions` property or the entire module 32 | response. 33 | type: list 34 | required: true 35 | text: 36 | description: 37 | - String of text to match or a regular expression to use as filter criteria. 38 | type: str 39 | required: true 40 | ingore_case: 41 | description: 42 | - Should the filter enable case sensitivity when performing a match. 43 | type: bool 44 | required: false 45 | default: false 46 | """ 47 | 48 | EXAMPLES = r""" 49 | - name: Filter actionable messages that match 'IEE094D SPECIFY OPERAND' and if so, set is_specify_operand = true. 50 | set_fact: 51 | is_specify_operand: "{{ result | ibm.ibm_zos_core.filter_wtor_messages('IEE094D SPECIFY OPERAND') }}" 52 | when: result is defined and not result.failed 53 | 54 | - name: Evaluate if there are any existing dump messages matching 'IEE094D SPECIFY OPERAND' 55 | assert: 56 | that: 57 | - is_specify_operand is defined 58 | - bool_zos_operator_action_continue 59 | success_msg: "Found 'IEE094D SPECIFY OPERAND' message." 60 | fail_msg: "Did not find 'IEE094D SPECIFY OPERAND' message." 61 | """ 62 | 63 | RETURN = r""" 64 | _value: 65 | description: A list containing dictionaries matching the WTOR. 66 | type: list 67 | elements: dict 68 | """ 69 | 70 | import re 71 | 72 | 73 | def filter_wtor_messages(wtor_response, text, ingore_case=False): 74 | """Filter a list of WTOR messages based on message text. 75 | 76 | Arguments: 77 | wtor_response {Union[dict, list[dict]]} -- The list structure in "actions" list returned by 78 | zos_operator_action_query or the entire return object from zos_operator_action_query. 79 | text {str} -- String of text or regular expression to use as filter criteria. 80 | 81 | Keyword Arguments: 82 | ingore_case {bool} -- Should search be case insensitive (default: {False}) 83 | 84 | Returns: 85 | list[dict] -- A list containing any WTOR objects matching search criteria 86 | """ 87 | wtors = [] 88 | if isinstance(wtor_response, dict): 89 | wtors = wtor_response.get("actions") 90 | elif isinstance(wtor_response, list): 91 | wtors = wtor_response 92 | found = [] 93 | for wtor in wtors: 94 | result = None 95 | if ingore_case: 96 | result = re.search(text, wtor.get("message_text", ""), re.IGNORECASE) 97 | else: 98 | result = re.search(text, wtor.get("message_text", "")) 99 | if result: 100 | found.append(wtor) 101 | return found 102 | 103 | 104 | class FilterModule(object): 105 | """ Jinja2 filters for use with WTOR response objects returned by zos_operator_action_query module. """ 106 | 107 | def filters(self): 108 | filters = { 109 | "filter_wtor_messages": filter_wtor_messages, 110 | } 111 | return filters 112 | -------------------------------------------------------------------------------- /plugins/module_utils/ansible_module.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | 14 | __metaclass__ = type 15 | 16 | from ansible.module_utils.basic import AnsibleModule 17 | 18 | 19 | class AnsibleModuleHelper(AnsibleModule): 20 | """Wrapper for AnsibleModule object that 21 | allows us to use AnsibleModule methods like 22 | run_command() without specifying a valid argument 23 | spec. 24 | """ 25 | 26 | def fail_json(self, **kwargs): 27 | if "Unsupported parameters for" in kwargs.get("msg", ""): 28 | return 29 | else: 30 | super().fail_json(**kwargs) 31 | -------------------------------------------------------------------------------- /plugins/module_utils/file.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020, 2024 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | 13 | from __future__ import absolute_import, division, print_function 14 | 15 | __metaclass__ = type 16 | 17 | import os 18 | from stat import S_IREAD, S_IWRITE, ST_MODE 19 | 20 | 21 | def _get_dir_mode(path): 22 | """Get the mode of an existing directory. 23 | Defaults to 0600 if directory not found. 24 | 25 | Parameters 26 | ---------- 27 | path : str 28 | The absolute path to retrieve directory mode from. 29 | 30 | Returns 31 | ------- 32 | int 33 | The mode of the directory. 34 | """ 35 | mask = S_IREAD | S_IWRITE 36 | if os.path.isdir(path): 37 | mask = os.stat(path)[ST_MODE] 38 | elif os.path.isdir(os.path.dirname(path)): 39 | mask = os.stat(os.path.dirname(path))[ST_MODE] 40 | return mask 41 | 42 | 43 | def make_dirs(path, mode_from=None): 44 | """Create missing directories for path. 45 | If path does not end in "/", assumes end of path is 46 | a file. 47 | 48 | Parameters 49 | ---------- 50 | path : str 51 | The path to ensure subdirectories are created for. 52 | 53 | Keyword Parameters 54 | ------------------ 55 | mode_from : str 56 | Path to existing dir to retrieve the mode from. 57 | Mode will be used for new directories. (default: {None}) 58 | """ 59 | mode = _get_dir_mode(mode_from) if mode_from is not None else S_IREAD | S_IWRITE 60 | if path[-1] == "/": 61 | os.makedirs(path, mode=mode, exist_ok=True) 62 | else: 63 | os.makedirs(os.path.dirname(path), mode=mode, exist_ok=True) 64 | return 65 | -------------------------------------------------------------------------------- /plugins/module_utils/import_handler.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020, 2024 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | 14 | __metaclass__ = type 15 | 16 | 17 | class MissingZOAUImport(object): 18 | """Error when importing ZOAU. 19 | """ 20 | def __getattr__(self, name): 21 | def method(*args, **kwargs): 22 | """Raises ImportError as a result of a failed ZOAU import. 23 | 24 | Parameters 25 | ---------- 26 | *args : dict 27 | Arguments ordered in a dictionary. 28 | **kwargs : dict 29 | Arguments ordered in a dictionary. 30 | 31 | Raises 32 | ------ 33 | ImportError 34 | Unable to import a module or library. 35 | """ 36 | raise ImportError( 37 | ( 38 | "ZOAU is not properly configured for Ansible. Unable to import zoautil_py. " 39 | "Ensure environment variables are properly configured in Ansible for use with ZOAU." 40 | ) 41 | ) 42 | return method 43 | 44 | 45 | class ZOAUImportError(object): 46 | def __init__(self, exception_traceback): 47 | """This class serves as a wrapper for any kind of error when importing 48 | ZOAU. Since ZOAU is used by both modules and module_utils, we need a way 49 | to alert the user when they're trying to use a function that couldn't be 50 | imported properly. If we only had to deal with this in modules, we could 51 | just validate that imports worked at the start of their main functions, 52 | but on utils, we don't have an entry point where we can validate this. 53 | Just raising an exception when trying the import would be better, but that 54 | introduces a failure on Ansible sanity tests, so we can't do it. 55 | 56 | Instead, we'll replace what would've been a ZOAU library with this class, 57 | and the moment ANY method gets called, we finally raise an exception. 58 | When creating a new instance of this class, we save the traceback 59 | from the original exception so that users have more context when their 60 | task/code fails. The expected traceback is a string representation of 61 | it, not an actual traceback object. By importing `traceback` from the 62 | standard library and calling `traceback.format_exc()` we can 63 | get this string. 64 | 65 | Parameters 66 | ---------- 67 | exception_traceback : str 68 | The formatted traceback of the exception. 69 | 70 | Attributes 71 | ---------- 72 | exception_traceback : str 73 | The formatted traceback of the exception. 74 | """ 75 | self.traceback = exception_traceback 76 | 77 | def __getattr__(self, name): 78 | """This code is virtually the same from `MissingZOAUImport`. What we 79 | do here is hijack all calls to any method from a missing ZOAU library 80 | and instead return a method that will alert the user that there was 81 | an error while importing ZOAU. 82 | """ 83 | """Raises ImportError as a result of a failed ZOAU import. 84 | 85 | Parameters 86 | ---------- 87 | name : str 88 | Value of object not properly imported. 89 | 90 | Raises 91 | ------ 92 | ImportError 93 | Unable to import a module or library. 94 | """ 95 | raise ImportError( 96 | ( 97 | "ZOAU is not properly configured for Ansible. Unable to import zoautil_py. " 98 | "Ensure environment variables are properly configured in Ansible for use with ZOAU. " 99 | "Complete traceback: {0}".format(self.traceback) 100 | ) 101 | ) 102 | 103 | 104 | class MissingImport(object): 105 | def __init__(self, import_name=""): 106 | """Error when it is unable to import a module due to it being missing. 107 | 108 | Parameters 109 | ---------- 110 | import_name : str 111 | The name of the module to import. 112 | 113 | Attributes 114 | ---------- 115 | import_name : str 116 | The name of the module to import. 117 | """ 118 | self.import_name = import_name 119 | 120 | def __getattr__(self, name): 121 | """Raises ImportError as a result of trying to import a missing module. 122 | 123 | Parameter 124 | --------- 125 | name : str 126 | Value of object not properly imported. 127 | 128 | Raises 129 | ------ 130 | ImportError 131 | Unable to import a module or library. 132 | """ 133 | raise ImportError("Import {0} was not available.".format(self.import_name)) 134 | -------------------------------------------------------------------------------- /plugins/module_utils/system.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2020, 2024 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | __metaclass__ = type 14 | 15 | from platform import platform 16 | from os import name as OS_NAME 17 | from sys import platform as SYS_PLATFORM 18 | # from subprocess import Popen, PIPE 19 | # from ansible.module_utils.six import binary_type, text_type, PY2, PY3 20 | # from ansible.module_utils._text import to_text, to_bytes 21 | # from ansible.module_utils.common.text.converters import to_bytes, to_text 22 | # from shlex import split 23 | 24 | 25 | NIX_PLATFORMS = frozenset({ 26 | "linux", 27 | "linux2", 28 | "darwin", 29 | "freebsd", 30 | "openbsd", 31 | "sunos", 32 | "netbsd" 33 | }) 34 | 35 | 36 | def is_posix(): 37 | """Determine if the system is POSIX certified or compliant. 38 | 39 | Returns 40 | ------- 41 | bool 42 | Whether the system is POSIX. 43 | """ 44 | return OS_NAME == "posix" 45 | 46 | 47 | def is_nix(): 48 | """Determine if the system is a variant of Unix, supported by Python. 49 | 50 | Returns 51 | ------- 52 | bool 53 | Whether the system is Unix-based. 54 | """ 55 | if not is_posix(): 56 | return False 57 | system_platform = platform().lower() 58 | for p_name in NIX_PLATFORMS: 59 | if p_name in system_platform: 60 | return True 61 | return False 62 | 63 | 64 | def is_win(): 65 | """Determine if the system is a Windows platform. 66 | 67 | Returns 68 | ------- 69 | bool 70 | Whether the system is Windows. 71 | """ 72 | return "win32" in platform().lower() or OS_NAME == "nt" 73 | 74 | 75 | def is_zos(): 76 | """Determine if the system is a z/OS distribution. 77 | 78 | Returns 79 | ------- 80 | bool 81 | Whether the system is z/OS. 82 | """ 83 | is_zos_unix = is_posix() and not is_nix() 84 | return is_zos_unix and SYS_PLATFORM == "zos" 85 | 86 | 87 | # def run_command(args, stdin=None, **kwargs): 88 | # """ Execute a shell command on the current system. This function should only 89 | # be used when AnsibleModule.run_command() is not available. This function 90 | # essentially serves as a wrapper for Python subprocess.Popen and supports all 91 | # of the arguments supported by Popen. 92 | 93 | # Required arguments: 94 | # args: args should be a sequence of program arguments or else a single 95 | # string or path-like object. By default, the program to execute is the 96 | # first item in args if args is a sequence. It is recommended to pass 97 | # args as a sequence. 98 | 99 | # Refer to the following link for a more detailed description of this 100 | # parameter and other parameters. 101 | # https://docs.python.org/3/library/subprocess.html#subprocess.Popen 102 | 103 | # Returns: 104 | # tuple[int, str, str]: The return code, stdout and stderr produced after 105 | # executing the command. 106 | # """ 107 | # rc = out = err = None 108 | # if not isinstance(args, (list, binary_type, text_type)): 109 | # rc = -1 110 | # err = "'args' must be list or string" 111 | # return rc, out, err 112 | 113 | # if isinstance(args, (text_type, str)): 114 | # if PY2: 115 | # args = to_bytes(args, errors='surrogate_or_strict') 116 | # elif PY3: 117 | # args = to_text(args, errors='surrogateescape') 118 | # args = split(args) 119 | 120 | # kwargs.update( 121 | # dict( 122 | # stdin=PIPE if stdin else None, 123 | # stderr=PIPE, 124 | # stdout=PIPE 125 | # ) 126 | # ) 127 | # try: 128 | # cmd = Popen(args, **kwargs) 129 | # except TypeError as proc_err: 130 | # rc = -1 131 | # err = str(proc_err) 132 | # return rc, out, err 133 | 134 | # out, err = tuple(map(to_text, cmd.communicate())) 135 | # rc = cmd.returncode 136 | # return rc, out, err 137 | -------------------------------------------------------------------------------- /plugins/module_utils/validation.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2023, 2024 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | 14 | __metaclass__ = type 15 | 16 | """ 17 | Class implemented for common validations that are not specific to z/OS but rather system or 18 | security related. 19 | 20 | """ 21 | import os 22 | 23 | 24 | def validate_safe_path(path): 25 | """This function is implemented to validate against path traversal attack 26 | when using os.path.join function. 27 | 28 | In this action plugin, path is on the controller. 29 | 30 | Parameters 31 | ---------- 32 | path : str 33 | A file's path. 34 | 35 | Returns 36 | ------- 37 | str 38 | The introduced path. 39 | 40 | Raises 41 | ------ 42 | DirectoryTraversalError 43 | User does not have access to a directory. 44 | """ 45 | if not os.path.isabs(path): 46 | real_path = os.path.realpath(path) 47 | if not os.path.exists(real_path) and not real_path.endswith(os.sep): 48 | # if path doesn't exist and does not contain separator then is likely a member. 49 | return path 50 | if not os.access(path=real_path, mode=os.F_OK): 51 | raise DirectoryTraversalError(real_path) 52 | return path 53 | 54 | 55 | class DirectoryTraversalError(Exception): 56 | """User does not have access to a directory. 57 | 58 | Parameters 59 | ---------- 60 | path : str 61 | Directory path. 62 | 63 | Attributes 64 | ---------- 65 | msg : str 66 | Human readable string describing the exception. 67 | """ 68 | def __init__(self, path): 69 | self.msg = "Detected directory traversal, user does not have access to {0}".format(path) 70 | super().__init__(self.msg) 71 | -------------------------------------------------------------------------------- /plugins/module_utils/zfsadm.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2025 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # Unless required by applicable law or agreed to in writing, software 7 | # distributed under the License is distributed on an "AS IS" BASIS, 8 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | # See the License for the specific language governing permissions and 10 | # limitations under the License. 11 | 12 | from __future__ import absolute_import, division, print_function 13 | __metaclass__ = type 14 | 15 | 16 | class zfsadm: 17 | """Provides an interface to execute zfsadm commands. 18 | """ 19 | def __init__(self, aggregate_name, module): 20 | """Initialize a class with its zfs dataset and allow modules to be executed. 21 | Parameters 22 | ---------- 23 | aggregate_name : str 24 | Name of the zfs dataset. 25 | module : object 26 | Ansible object to execute commands. 27 | """ 28 | self.aggregate_name = aggregate_name.upper() 29 | self.module = module 30 | 31 | def execute_resizing(self, operation, size, noai, verbose): 32 | """Execute a grow or shrink operation on a zfs dataset. 33 | 34 | Parameters 35 | ---------- 36 | operation : str 37 | Whether the operation to execute is grow or shrink 38 | size : int 39 | Size to be assigned to the zfs 40 | noai : str 41 | Value for the no auto increase (noai) option when shrinking a dataset 42 | verbose : str 43 | Value for zfsadm's trace option specifying the output file for the command 44 | 45 | Returns 46 | ------- 47 | rc : int 48 | The RC of the command executed. 49 | stdout : str 50 | The stdout of the executed command. 51 | stderr : str 52 | The stderr of the executed command. 53 | cmd_str : str 54 | The full command that was executed. 55 | """ 56 | if operation != "grow": 57 | if operation != "shrink": 58 | self.module.fail_json(msg=f"There is no operator {operation}") 59 | 60 | cmd = f"-size {size}{noai}{verbose}" 61 | cmd_str = f"zfsadm {operation} -aggregate {self.aggregate_name} {cmd}" 62 | 63 | rc, stdout, stderr = self.module.run_command(cmd_str) 64 | 65 | return rc, stdout, stderr, cmd_str 66 | 67 | @staticmethod 68 | def get_aggregate_size(aggregate_name, module): 69 | """Execute a command to get the size of a zfs dataset. 70 | 71 | Returns 72 | ------- 73 | rc : int 74 | The rc of the executed command. 75 | stdout : str 76 | The stdout of the executed command 77 | stderr : str 78 | The stderr of the executed command. 79 | """ 80 | cmd = f"zfsadm aggrinfo {aggregate_name}" 81 | 82 | rc, stdout, stderr = module.run_command(cmd) 83 | 84 | return rc, stdout, stderr 85 | -------------------------------------------------------------------------------- /plugins/module_utils/zoau_version_checker.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) IBM Corporation 2022, 2025 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | # import subprocess 17 | 18 | try: 19 | from zoautil_py import ZOAU_API_VERSION 20 | except Exception: 21 | ZOAU_API_VERSION = "1.2.0" 22 | 23 | __metaclass__ = type 24 | 25 | 26 | def is_zoau_version_higher_than(min_version_str): 27 | """Reports back if ZOAU version is high enough. 28 | 29 | Parameters 30 | ---------- 31 | min_version_str : str 32 | The minimal desired ZOAU version '#.#.#'. 33 | 34 | Returns 35 | ------- 36 | bool 37 | Whether ZOAU version found was high enough. 38 | """ 39 | if is_valid_version_string(min_version_str): 40 | # check zoau version on system (already a list) 41 | system_version_list = get_zoau_version_str() 42 | 43 | # convert input to list format 44 | min_version_list = min_version_str.split('.') 45 | 46 | # convert list of strs to list of ints 47 | system_version_list = [int(i) for i in system_version_list] 48 | min_version_list = [int(i) for i in min_version_list] 49 | 50 | # compare major 51 | if system_version_list[0] > min_version_list[0]: 52 | return True 53 | if system_version_list[0] < min_version_list[0]: 54 | return False 55 | 56 | # majors are equal, compare minor 57 | if system_version_list[1] > min_version_list[1]: 58 | return True 59 | if system_version_list[1] < min_version_list[1]: 60 | return False 61 | 62 | # majors and minors are equal, compare patch 63 | if system_version_list[2] > min_version_list[2]: 64 | return True 65 | if system_version_list[2] < min_version_list[2]: 66 | return False 67 | 68 | # check for a 4th level if system and min_version provided it 69 | if len(system_version_list) < 4: 70 | system_version_list.append(0) 71 | if len(min_version_list) < 4: 72 | min_version_list.append(0) 73 | 74 | # return result of comparison of 4th levels. 75 | return system_version_list[3] >= min_version_list[3] 76 | 77 | # invalid version string 78 | return False 79 | 80 | 81 | def is_valid_version_string(version_str): 82 | """Reports back if string is in proper version format. Expected format is a 83 | series of numbers (major) followed by a dot(.) followed by another 84 | series of numbers (minor) followed by another dot(.) followed by a 85 | series of numbers (patch) i.e. "#.#.#" where '#' can be any integer. 86 | There is a provision for a 4th level to this eg "v1.2.0.1". 87 | 88 | Parameters 89 | ---------- 90 | min_version_str : str 91 | String to be verified is in correct format. 92 | 93 | Returns 94 | ------- 95 | bool 96 | Whether provided str is in correct format. 97 | """ 98 | 99 | # split string into [major, minor, patch] 100 | version_list = version_str.split('.') 101 | 102 | # check each element in list isnumeric() 103 | for ver in version_list: 104 | if not ver.isnumeric(): 105 | return False 106 | 107 | return True 108 | 109 | 110 | def get_zoau_version_str(): 111 | """Attempts to call zoaversion on target and parses out version string. 112 | 113 | Returns 114 | ------- 115 | Union[int, int, int] 116 | ZOAU version found in format [#,#,#]. There is a 117 | provision for a 4th level eg "v1.2.0.1". 118 | """ 119 | version_list = ( 120 | ZOAU_API_VERSION.split('.') 121 | ) 122 | 123 | return version_list 124 | -------------------------------------------------------------------------------- /plugins/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/plugins/modules/__init__.py -------------------------------------------------------------------------------- /plugins/modules/zos_ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) IBM Corporation 2019, 2025 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | DOCUMENTATION = r""" 16 | --- 17 | module: zos_ping 18 | version_added: "1.1.0" 19 | short_description: Ping z/OS and check dependencies. 20 | description: 21 | - L(zos_ping,./zos_ping.html) verifies the presence of z/OS Web Client Enablement Toolkit, 22 | iconv, and Python. 23 | - L(zos_ping,./zos_ping.html) returns C(pong) when the target host is not missing any required 24 | dependencies. 25 | - If the target host is missing optional dependencies, the L(zos_ping,./zos_ping.html) will 26 | return one or more warning messages. 27 | - If a required dependency is missing from the target host, an explanatory 28 | message will be returned with the module failure. 29 | author: 30 | - "Vijay Katoch (@vijayka)" 31 | - "Blake Becker (@blakeinate)" 32 | - "Demetrios Dimatos (@ddimatos)" 33 | options: {} 34 | 35 | attributes: 36 | action: 37 | support: full 38 | description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller. 39 | async: 40 | support: full 41 | description: Supports being used with the ``async`` keyword. 42 | check_mode: 43 | support: none 44 | description: Can run in check_mode and return changed status prediction without modifying target. If not supported, the action will be skipped. 45 | 46 | notes: 47 | - This module is written in REXX and relies on the SCP protocol to transfer the source to 48 | the managed z/OS node and encode it in the managed nodes default encoding, eg IBM-1047. 49 | Starting with OpenSSH 9.0, it switches from SCP to use SFTP by default, meaning transfers 50 | are no longer treated as text and are transferred as binary preserving the source files 51 | encoding resulting in a module failure. If you are using OpenSSH 9.0 (ssh -V) or later, 52 | you can instruct SSH to use SCP by adding the entry C(scp_extra_args="-O") into the ini 53 | file named C(ansible.cfg). 54 | - For more information, review the 55 | L(ansible.builtin.ssh, https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ssh_connection.html) 56 | module. 57 | """ 58 | 59 | EXAMPLES = r""" 60 | - name: Ping the z/OS host and perform resource checks 61 | zos_ping: 62 | register: result 63 | """ 64 | 65 | RETURN = r""" 66 | ping: 67 | description: Should contain the value "pong" on success. 68 | returned: always 69 | type: str 70 | sample: pong 71 | warnings: 72 | description: List of warnings returned from stderr when performing resource checks. 73 | returned: failure 74 | type: list 75 | elements: str 76 | """ 77 | -------------------------------------------------------------------------------- /plugins/modules/zos_ping.rexx: -------------------------------------------------------------------------------- 1 | /* rexx __ANSIBLE_ENCODE_EBCDIC__ */ 2 | /* WANT_JSON */ 3 | 4 | /* Copyright (c) IBM Corporation 2019, 2023 */ 5 | 6 | /* Licensed under the Apache License, Version 2.0 (the "License"); */ 7 | /* you may not use this file except in compliance with the License. */ 8 | /* You may obtain a copy of the License at */ 9 | /* http://www.apache.org/licenses/LICENSE-2.0 */ 10 | /* Unless required by applicable law or agreed to in writing, software */ 11 | /* distributed under the License is distributed on an "AS IS" BASIS, */ 12 | /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ 13 | /* See the License for the specific language governing permissions and */ 14 | /* limitations under the License. */ 15 | 16 | /* 17 | 18 | 19 | DOCUMENTATION = ''' 20 | --- 21 | module: zos_ping 22 | version_added: 1.1.0 23 | short_description: Ping z/OS and check dependencies. 24 | description: 25 | - L(zos_ping,./zos_ping.html) verifies the presence of z/OS Web Client Enablement Toolkit, 26 | iconv, and Python. 27 | - L(zos_ping,./zos_ping.html) returns C(pong) when the target host is not missing any required 28 | dependencies. 29 | - If the target host is missing optional dependencies, the L(zos_ping,./zos_ping.html) will 30 | return one or more warning messages. 31 | - If a required dependency is missing from the target host, an explanatory 32 | message will be returned with the module failure. 33 | author: 34 | - "Vijay Katoch (@vijayka)" 35 | - "Blake Becker (@blakeinate)" 36 | - "Demetrios Dimatos (@ddimatos)" 37 | options: {} 38 | ''' 39 | 40 | EXAMPLES = ''' 41 | - name: Ping the z/OS host and perform resource checks 42 | zos_ping: 43 | register: result 44 | ''' 45 | 46 | RETURN = ''' 47 | ping: 48 | description: Should contain the value "pong" on success. 49 | returned: always 50 | type: str 51 | sample: pong 52 | warnings: 53 | description: List of warnings returned from stderr when performing resource 54 | checks. 55 | returned: failure 56 | type: list 57 | elements: str 58 | ''' 59 | */ 60 | 61 | Parse Arg argFile . 62 | 63 | pythonName = 'Python' 64 | majVersionPython = 3 65 | minVersionPython = 10 66 | warningJsonList = '' 67 | 68 | If (argFile = '') Then Do 69 | failModule('Internal Error: JSON argument file missing' || ESC_N, "", 16) 70 | End 71 | newArgFile1 = argFile || 1 72 | /* Check for iconv utility by converting the JSON argument file form ASCII to EBCDIC */ 73 | retC = bpxwunix('iconv -f ISO8859-1 -t IBM-1047 ' argFile,,stderr.) 74 | 75 | If (retC <> 0) Then Do 76 | failModule('Command iconv not found.', stderr, retC) 77 | End 78 | 79 | /* Load z/OS Web Client Enablement Toolkit to verify system has z/OS Web Client Enablement toolkit installed */ Call hwtcalls "on" 80 | Address hwtjson 'hwtConst returnCode resbuf.' 81 | If (rc <> 0 | returnCode <> HWTJ_OK) Then Do 82 | retC = rc 83 | errmsg = 'Error: Unable to start JSON Parser may be due to missing', 84 | 'z/OS Web Client enablement toolkit.' || ESC_N 85 | failModule(errmsg, "", retC) 86 | End 87 | 88 | /* Check for Python version >= 3.10 eg: 'Python 3.10.0' */ 89 | retC = bpxwunix('python3 --version', out., err.) 90 | If (err.0 > 0) Then Do 91 | Do index=1 To err.0 92 | warningJsonList = addWarningToList(warningJsonList, 'Python Warning: ' || err.index) 93 | End 94 | End 95 | Else Do 96 | If (out.0 > 0) Then Do 97 | parse Var out.1 name version 98 | parse Var version majVer '.' minVer '.' micVer 99 | If (pythonName == strip(name)) Then Do 100 | If (majVer < majVersionPython | minVer < minVersionPython) Then Do 101 | warningJsonList = addWarningToList(warningJsonList, "Python Warning: Python not up to the level to support z/OS modules") 102 | End 103 | End 104 | Else Do 105 | warningJsonList = addWarningToList(warningJsonList, "Python Warning: Incorrect Python Found") 106 | End 107 | End 108 | End 109 | 110 | retJson = '{"changed":false,"ping": "pong","failed":false' 111 | /* Construct a JSON list for warnings */ 112 | If (warningJsonList <> '') Then 113 | retJson = retJson || ',"warnings": [' || warningJsonList || ']' 114 | retJson = retJson || '}' 115 | 116 | Say retJson 117 | Exit(0) 118 | 119 | 120 | /* Build a comma separated list of warnings */ 121 | addWarningToList: 122 | PARSE ARG warningList, warning 123 | if (warningList <> '') Then 124 | warningList = warningist || ',' 125 | warningList = warningList || '"' || warning || '"' 126 | return warningList 127 | 128 | 129 | /* Fail the module when unacceptable situation has occurred */ 130 | failModule: 131 | PARSE ARG output,stderr,retC 132 | Address Syscall 133 | 'Write' 2 'output' length(output) 134 | Do index=1 To stderr.0 135 | errmsg = stderr.index || ESC_N 136 | 'Write' 2 'errmsg' length(errmsg) 137 | End 138 | Exit(retC) 139 | return 140 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # © Copyright IBM Corporation 2021 3 | ################################################################################ 4 | # This file maintains a list of any python dependencies needed by this 5 | # Collection to run effectively on an Ansible controller. 6 | # At this time there are no python dependencies. 7 | # For more information on requirements files, 8 | # see https://pip.pypa.io/en/latest/user_guide/#requirements-files 9 | ################################################################################ -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/tests/__init__.py -------------------------------------------------------------------------------- /tests/config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) IBM Corporation 2024 3 | ################################################################################ 4 | 5 | # ############################################################################# 6 | # Description 7 | # Support for this feature was first added in ansible-core 2.12 so that 8 | # ansible-test configured with desirable changes. This is an optional 9 | # configuration, but when used, must be placed in "tests/config.yml" 10 | # relative to the base of the collection. This configuration only 11 | # applies to modules and module_utils. 12 | # 13 | # See additional example - 14 | # https://github.com/ansible/ansible/blob/devel/test/lib/ansible_test/config/config.yml 15 | # 16 | # Options 17 | # modules - required 18 | # python_requires - required 19 | # - 'default' - All Python versions supported by Ansible. 20 | # This is the default value if no configuration is provided. 21 | # - 'controller' - All Python versions supported by the Ansible controller. 22 | # This indicates the modules/module_utils can only run on the controller. 23 | # Intended for use only with modules/module_utils that depend on 24 | # ansible-connection, which only runs on the controller. 25 | # Unit tests for modules/module_utils will be permitted to import any 26 | # Ansible code, instead of only module_utils. 27 | # - SpecifierSet - A PEP 440 specifier set indicating the supported Python versions. 28 | # This is only needed when modules/module_utils do not support all 29 | # Python versions supported by Ansible. It is not necessary to exclude 30 | # versions which Ansible does not support, as this will be done automatically. 31 | # ############################################################################# 32 | 33 | modules: 34 | python_requires: '>=3.9' 35 | -------------------------------------------------------------------------------- /tests/functional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/tests/functional/__init__.py -------------------------------------------------------------------------------- /tests/functional/modules/test_zos_ping_func.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2019, 2020 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import (absolute_import, division, print_function) 15 | 16 | __metaclass__ = type 17 | 18 | 19 | def test_job_submit_pds(ansible_zos_module): 20 | hosts = ansible_zos_module 21 | results = hosts.all.zos_ping() 22 | for result in results.contacted.values(): 23 | assert result.get("ping") == "pong" 24 | -------------------------------------------------------------------------------- /tests/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/tests/helpers/__init__.py -------------------------------------------------------------------------------- /tests/helpers/dataset.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2024 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | __metaclass__ = type 17 | import pytest 18 | import string 19 | import random 20 | import time 21 | import re 22 | 23 | 24 | def get_tmp_ds_name(mlq_size=7, llq_size=7, symbols=False): 25 | """ Function or test to ensure random names of datasets 26 | the values of middle and last qualifier can change size by parameter, 27 | but by default includes one letter. 28 | Also includes indication if symbols should be in the string, default=false.""" 29 | ds = "ANSIBLE" + "." 30 | if symbols: 31 | ds += "P" + get_random_qs(mlq_size).upper() + "." 32 | else: 33 | ds += "P" + get_random_q(mlq_size).upper() + "." 34 | ds += "T" + str(int(time.time()*1000))[-7:] + "." 35 | if symbols: 36 | ds += "C" + get_random_qs(llq_size).upper() 37 | else: 38 | ds += "C" + get_random_q(llq_size).upper() 39 | 40 | return(ds) 41 | 42 | 43 | def get_random_q(size=7): 44 | """ Function or test to ensure random hlq of datasets""" 45 | # Generate the first random hlq of size pass as parameter 46 | letters = string.ascii_uppercase + string.digits 47 | random_q = ''.join(random.choice(letters)for iteration in range(size)) 48 | count = 0 49 | # Generate a random HLQ and verify if is valid, if not, repeat the process 50 | while count < 5 and not re.fullmatch( 51 | r"^(?:[A-Z$#@]{1}[A-Z0-9$#@-]{0,7})", 52 | random_q, 53 | re.IGNORECASE, 54 | ): 55 | random_q = ''.join(random.choice(letters)for iteration in range(size)) 56 | count += 1 57 | return random_q 58 | 59 | def get_random_qs(size=7): 60 | """ Function or test to ensure random hlq of datasets, including symbol characters""" 61 | # Generate the first random hlq of size pass as parameter 62 | letters = string.ascii_uppercase + string.digits 63 | special_chars = "$@#-" 64 | random_q = ''.join(random.choice(letters)for iteration in range(size)) 65 | random_char = random_q[random.choice(range(0, size))] 66 | random_q = random_q.replace(random_char, random.choice(special_chars)) 67 | count = 0 68 | # Generate a random HLQ and verify if is valid, if not, repeat the process 69 | while count < 5 and not re.fullmatch( 70 | r"^(?:[A-Z$#@]{1}[A-Z0-9$#@-]{0,7})", 71 | random_q, 72 | re.IGNORECASE, 73 | ): 74 | random_q = ''.join(random.choice(letters)for iteration in range(size)) 75 | random_char = random_q[random.choice(range(0, size))] 76 | random_q = random_q.replace(random_char, random.choice(special_chars)) 77 | count += 1 78 | return random_q 79 | -------------------------------------------------------------------------------- /tests/helpers/utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2024 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | The helpers/utils.py file contains various utility functions that, 16 | while not fitting into a specific standalone helper module, 17 | are used across multiple test suites and can be reused from one util. 18 | """ 19 | from datetime import datetime 20 | 21 | def get_random_file_name(prefix="", suffix="", dir=""): 22 | """ 23 | Returns a randomly generated USS file name with options to have a specific suffix and prefix 24 | in it. By default, returns a 8 numeric character name generated by the current seconds + milliseconds 25 | from the local system. 26 | 27 | It is not guaranteed that the file name won't exist in the remote node, so this function is intended 28 | for naming temporary files, where the responsibility for creating and deleting it is left to the function 29 | caller. 30 | 31 | Parameters 32 | ---------- 33 | prefix : str 34 | Prefix for the temporary file name. 35 | suffix : str 36 | Suffix for the temporary file name, it can be an extension e.g. '.dzp'. 37 | dir : str 38 | Parent temporary folder structure e.g. /tmp/temporary-folder/ 39 | """ 40 | if len(dir) > 0 and not dir.endswith('/'): 41 | dir += '/' 42 | 43 | return dir + prefix + datetime.now().strftime("%S%f") + suffix -------------------------------------------------------------------------------- /tests/helpers/version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) IBM Corporation 2022, 2025 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | import re 17 | 18 | __metaclass__ = type 19 | 20 | 21 | def get_zoau_version(ansible_zos_module): 22 | """ 23 | Fetches the current ZOAU version from the z/OS system using the `zoaversion` command. 24 | 25 | This function runs the `zoaversion` command on the z/OS system and parses the output 26 | to extract the version number in the format `vX.Y.Z.W`, where X, Y, Z, and W are numerical digits. 27 | 28 | Parameters 29 | ---------- 30 | ansible_zos_module : ansible.module_utils.basic.AnsibleModule 31 | The Ansible z/OS module that provides the `all.shell()` method to run shell commands. 32 | 33 | Returns 34 | ------- 35 | str 36 | The ZOAU version number (e.g., "1.2.3.4") extracted from the command output. 37 | Returns `"1.2.0"` if no valid version is found. 38 | """ 39 | cmd_str = "zoaversion" 40 | version_results = ansible_zos_module.all.shell(cmd=cmd_str) 41 | zoa_version = "0.0.0" # Default version if not found 42 | 43 | # Iterate through all contacted hosts and check the result output 44 | for result in version_results.contacted.values(): 45 | output = result.get("stdout") 46 | if output: 47 | # Search for the version in the format "vX.Y.Z.W" 48 | match = re.search(r'v?(\d+\.\d+\.\d+(?:\.\d+)?)', output) 49 | if match: 50 | zoa_version = match.group(1) 51 | 52 | return zoa_version 53 | 54 | def is_zoau_version_higher_than(ansible_zos_module,min_version_str): 55 | """Reports back if ZOAU version is high enough. 56 | 57 | Parameters 58 | ---------- 59 | min_version_str : str 60 | The minimal desired ZOAU version '#.#.#'. 61 | 62 | Returns 63 | ------- 64 | bool 65 | Whether ZOAU version found was high enough. 66 | """ 67 | if is_valid_version_string(min_version_str): 68 | # check zoau version on system (already a list) 69 | system_version_list = get_zoau_version_str(ansible_zos_module) 70 | 71 | # convert input to list format 72 | min_version_list = min_version_str.split('.') 73 | 74 | # convert list of strs to list of ints 75 | system_version_list = [int(i) for i in system_version_list] 76 | min_version_list = [int(i) for i in min_version_list] 77 | 78 | # compare major 79 | if system_version_list[0] > min_version_list[0]: 80 | return True 81 | if system_version_list[0] < min_version_list[0]: 82 | return False 83 | 84 | # majors are equal, compare minor 85 | if system_version_list[1] > min_version_list[1]: 86 | return True 87 | if system_version_list[1] < min_version_list[1]: 88 | return False 89 | 90 | # majors and minors are equal, compare patch 91 | if system_version_list[2] > min_version_list[2]: 92 | return True 93 | if system_version_list[2] < min_version_list[2]: 94 | return False 95 | 96 | # check for a 4th level if system and min_version provided it 97 | if len(system_version_list) < 4: 98 | system_version_list.append(0) 99 | if len(min_version_list) < 4: 100 | min_version_list.append(0) 101 | 102 | # return result of comparison of 4th levels. 103 | return system_version_list[3] >= min_version_list[3] 104 | 105 | # invalid version string 106 | return False 107 | 108 | 109 | def is_valid_version_string(version_str): 110 | """Reports back if string is in proper version format. Expected format is a 111 | series of numbers (major) followed by a dot(.) followed by another 112 | series of numbers (minor) followed by another dot(.) followed by a 113 | series of numbers (patch) i.e. "#.#.#" where '#' can be any integer. 114 | There is a provision for a 4th level to this eg "v1.2.0.1". 115 | 116 | Parameters 117 | ---------- 118 | min_version_str : str 119 | String to be verified is in correct format. 120 | 121 | Returns 122 | ------- 123 | bool 124 | Whether provided str is in correct format. 125 | """ 126 | 127 | # split string into [major, minor, patch] 128 | version_list = version_str.split('.') 129 | 130 | # check each element in list isnumeric() 131 | for ver in version_list: 132 | if not ver.isnumeric(): 133 | return False 134 | 135 | return True 136 | 137 | def get_zoau_version_str(ansible_zos_module): 138 | """Attempts to call zoaversion on target and parses out version string. 139 | 140 | Returns 141 | ------- 142 | Union[int, int, int] 143 | ZOAU version found in format [#,#,#]. There is a 144 | provision for a 4th level eg "v1.2.0.1". 145 | """ 146 | ZOAU_API_VERSION = get_zoau_version(ansible_zos_module) 147 | version_list = ( 148 | ZOAU_API_VERSION.split('.') 149 | ) 150 | 151 | return version_list 152 | -------------------------------------------------------------------------------- /tests/pytest.ini: -------------------------------------------------------------------------------- 1 | # content of pytest.ini 2 | [pytest] 3 | python_files = test_*.py 4 | python_functions = test_* 5 | markers = 6 | ds: dataset test cases. 7 | uss: uss test cases. 8 | seq: sequential data sets test cases. 9 | pdse: partitioned data sets test cases. 10 | vsam: VSAM data sets test cases. 11 | template: Jinja2 templating test cases. 12 | aliases: aliases option test cases. 13 | loadlib: executable copy test cases. 14 | asa: ASA text files test cases. -------------------------------------------------------------------------------- /tests/requirements.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) IBM Corporation 2019, 2020, 2023 2 | # Left purposely empty. -------------------------------------------------------------------------------- /tests/sanity/ignore-2.13.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/zos_apf.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 2 | plugins/modules/zos_backup_restore.py validate-modules:doc-choices-do-not-match-spec # We use our own argument parser for advanced conditional and dependent arguments. 3 | plugins/modules/zos_backup_restore.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 4 | plugins/modules/zos_blockinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 5 | plugins/modules/zos_copy.py validate-modules:doc-default-does-not-match-spec # We use our own argument parser for advanced conditional and dependent arguments. 6 | plugins/modules/zos_copy.py validate-modules:doc-type-does-not-match-spec # doc type should be str, while spec type is path to allow user path expansion 7 | plugins/modules/zos_copy.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 8 | plugins/modules/zos_copy.py validate-modules:parameter-type-not-in-doc # Passing args from action plugin 9 | plugins/modules/zos_copy.py validate-modules:undocumented-parameter # Passing args from action plugin 10 | plugins/modules/zos_data_set.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 11 | plugins/modules/zos_encode.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 12 | plugins/modules/zos_fetch.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 13 | plugins/modules/zos_fetch.py validate-modules:parameter-type-not-in-doc # Passing args from action plugin 14 | plugins/modules/zos_fetch.py validate-modules:undocumented-parameter # Passing args from action plugin 15 | plugins/modules/zos_find.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 16 | plugins/modules/zos_job_output.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 17 | plugins/modules/zos_job_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 18 | plugins/modules/zos_job_submit.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 19 | plugins/modules/zos_job_submit.py validate-modules:parameter-type-not-in-doc # Passing args from action plugin 20 | plugins/modules/zos_job_submit.py validate-modules:undocumented-parameter # Passing args from action plugin 21 | plugins/modules/zos_job_submit.py pylint:catching-non-exception # False positive, Exception is inherited 22 | plugins/modules/zos_lineinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 23 | plugins/modules/zos_mount.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 24 | plugins/modules/zos_mvs_raw.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 25 | plugins/modules/zos_operator.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 26 | plugins/modules/zos_operator_action_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 27 | plugins/modules/zos_ping.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 28 | plugins/modules/zos_ping.rexx validate-modules:invalid-extension # Opened issue https://github.com/ansible/ansible/issues/79784 29 | plugins/modules/zos_ping.rexx validate-modules:python-syntax-error # Opened issue https://github.com/ansible/ansible/issues/79784 30 | plugins/modules/zos_script.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 31 | plugins/modules/zos_stat.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 32 | plugins/modules/zos_tso_command.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 33 | plugins/modules/zos_gather_facts.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 34 | plugins/modules/zos_volume_init.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 35 | plugins/modules/zos_archive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 36 | plugins/modules/zos_unarchive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 37 | -------------------------------------------------------------------------------- /tests/sanity/ignore-2.14.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/zos_apf.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 2 | plugins/modules/zos_backup_restore.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 3 | plugins/modules/zos_blockinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 4 | plugins/modules/zos_copy.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 5 | plugins/modules/zos_data_set.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 6 | plugins/modules/zos_encode.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 7 | plugins/modules/zos_fetch.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 8 | plugins/modules/zos_find.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 9 | plugins/modules/zos_job_output.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 10 | plugins/modules/zos_job_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 11 | plugins/modules/zos_job_submit.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 12 | plugins/modules/zos_lineinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 13 | plugins/modules/zos_mount.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 14 | plugins/modules/zos_mvs_raw.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 15 | plugins/modules/zos_operator.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 16 | plugins/modules/zos_operator_action_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 17 | plugins/modules/zos_ping.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 18 | plugins/modules/zos_ping.rexx validate-modules:invalid-extension # Opened issue https://github.com/ansible/ansible/issues/79784 19 | plugins/modules/zos_ping.rexx validate-modules:python-syntax-error # Opened issue https://github.com/ansible/ansible/issues/79784 20 | plugins/modules/zos_script.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 21 | plugins/modules/zos_stat.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 22 | plugins/modules/zos_tso_command.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 23 | plugins/modules/zos_gather_facts.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 24 | plugins/modules/zos_volume_init.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 25 | plugins/modules/zos_archive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 26 | plugins/modules/zos_unarchive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 27 | plugins/modules/zos_zfs_resize.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 28 | -------------------------------------------------------------------------------- /tests/sanity/ignore-2.15.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/zos_apf.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 2 | plugins/modules/zos_backup_restore.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 3 | plugins/modules/zos_blockinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 4 | plugins/modules/zos_copy.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 5 | plugins/modules/zos_data_set.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 6 | plugins/modules/zos_encode.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 7 | plugins/modules/zos_fetch.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 8 | plugins/modules/zos_find.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 9 | plugins/modules/zos_job_output.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 10 | plugins/modules/zos_job_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 11 | plugins/modules/zos_job_submit.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 12 | plugins/modules/zos_lineinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 13 | plugins/modules/zos_mount.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 14 | plugins/modules/zos_mvs_raw.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 15 | plugins/modules/zos_operator.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 16 | plugins/modules/zos_operator_action_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 17 | plugins/modules/zos_ping.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 18 | plugins/modules/zos_ping.rexx validate-modules:invalid-extension # Opened issue https://github.com/ansible/ansible/issues/79784 19 | plugins/modules/zos_ping.rexx validate-modules:python-syntax-error # Opened issue https://github.com/ansible/ansible/issues/79784 20 | plugins/modules/zos_script.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 21 | plugins/modules/zos_stat.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 22 | plugins/modules/zos_tso_command.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 23 | plugins/modules/zos_gather_facts.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 24 | plugins/modules/zos_volume_init.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 25 | plugins/modules/zos_archive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 26 | plugins/modules/zos_unarchive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 27 | plugins/modules/zos_zfs_resize.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 28 | -------------------------------------------------------------------------------- /tests/sanity/ignore-2.16.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/zos_apf.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 2 | plugins/modules/zos_backup_restore.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 3 | plugins/modules/zos_blockinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 4 | plugins/modules/zos_copy.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 5 | plugins/modules/zos_data_set.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 6 | plugins/modules/zos_encode.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 7 | plugins/modules/zos_fetch.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 8 | plugins/modules/zos_find.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 9 | plugins/modules/zos_job_output.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 10 | plugins/modules/zos_job_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 11 | plugins/modules/zos_job_submit.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 12 | plugins/modules/zos_lineinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 13 | plugins/modules/zos_mount.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 14 | plugins/modules/zos_mvs_raw.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 15 | plugins/modules/zos_operator.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 16 | plugins/modules/zos_operator_action_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 17 | plugins/modules/zos_ping.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 18 | plugins/modules/zos_ping.rexx validate-modules:invalid-extension # Opened issue https://github.com/ansible/ansible/issues/79784 19 | plugins/modules/zos_ping.rexx validate-modules:python-syntax-error # Opened issue https://github.com/ansible/ansible/issues/79784 20 | plugins/modules/zos_script.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 21 | plugins/modules/zos_stat.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 22 | plugins/modules/zos_tso_command.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 23 | plugins/modules/zos_gather_facts.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 24 | plugins/modules/zos_volume_init.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 25 | plugins/modules/zos_archive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 26 | plugins/modules/zos_unarchive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 27 | plugins/modules/zos_zfs_resize.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 28 | -------------------------------------------------------------------------------- /tests/sanity/ignore-2.17.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/zos_apf.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 2 | plugins/modules/zos_backup_restore.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 3 | plugins/modules/zos_blockinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 4 | plugins/modules/zos_copy.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 5 | plugins/modules/zos_data_set.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 6 | plugins/modules/zos_encode.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 7 | plugins/modules/zos_fetch.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 8 | plugins/modules/zos_find.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 9 | plugins/modules/zos_job_output.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 10 | plugins/modules/zos_job_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 11 | plugins/modules/zos_job_submit.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 12 | plugins/modules/zos_lineinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 13 | plugins/modules/zos_mount.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 14 | plugins/modules/zos_mvs_raw.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 15 | plugins/modules/zos_operator.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 16 | plugins/modules/zos_operator_action_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 17 | plugins/modules/zos_ping.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 18 | plugins/modules/zos_ping.rexx validate-modules:missing-gplv3-license # Licensed under Apache 2.0 19 | plugins/modules/zos_ping.rexx validate-modules:invalid-extension # Opened issue https://github.com/ansible/ansible/issues/79784 20 | plugins/modules/zos_script.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 21 | plugins/modules/zos_stat.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 22 | plugins/modules/zos_tso_command.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 23 | plugins/modules/zos_gather_facts.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 24 | plugins/modules/zos_volume_init.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 25 | plugins/modules/zos_archive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 26 | plugins/modules/zos_unarchive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 27 | plugins/modules/zos_zfs_resize.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 28 | -------------------------------------------------------------------------------- /tests/sanity/ignore-2.18.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/zos_apf.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 2 | plugins/modules/zos_backup_restore.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 3 | plugins/modules/zos_blockinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 4 | plugins/modules/zos_copy.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 5 | plugins/modules/zos_data_set.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 6 | plugins/modules/zos_encode.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 7 | plugins/modules/zos_fetch.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 8 | plugins/modules/zos_find.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 9 | plugins/modules/zos_job_output.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 10 | plugins/modules/zos_job_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 11 | plugins/modules/zos_job_submit.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 12 | plugins/modules/zos_lineinfile.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 13 | plugins/modules/zos_mount.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 14 | plugins/modules/zos_mvs_raw.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 15 | plugins/modules/zos_operator.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 16 | plugins/modules/zos_operator_action_query.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 17 | plugins/modules/zos_ping.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 18 | plugins/modules/zos_ping.rexx validate-modules:missing-gplv3-license # Licensed under Apache 2.0 19 | plugins/modules/zos_ping.rexx validate-modules:invalid-extension # Opened issue https://github.com/ansible/ansible/issues/79784 20 | plugins/modules/zos_script.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 21 | plugins/modules/zos_stat.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 22 | plugins/modules/zos_tso_command.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 23 | plugins/modules/zos_gather_facts.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 24 | plugins/modules/zos_volume_init.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 25 | plugins/modules/zos_archive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 26 | plugins/modules/zos_unarchive.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 27 | plugins/modules/zos_zfs_resize.py validate-modules:missing-gplv3-license # Licensed under Apache 2.0 -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/ibm_zos_core/37d80c7d6875d38d53f519dea519aab2c2461811/tests/unit/__init__.py -------------------------------------------------------------------------------- /tests/unit/test_data_set_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2024 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | __metaclass__ = type 17 | 18 | from ibm_zos_core.plugins.module_utils.data_set import ( 19 | DataSet 20 | ) 21 | 22 | import pytest 23 | 24 | 25 | gds_relative_test_data = [ 26 | {"name": "USER.GDG(+1)", "valid_gds" : True}, 27 | {"name": "USER.GDG(-3)", "valid_gds" : True}, 28 | {"name": "USER.GDG(0)", "valid_gds" : True}, 29 | {"name": "USER.GDG(+22)", "valid_gds" : True}, 30 | {"name": "USER.GDG(-33)", "valid_gds" : True}, 31 | {"name": "USER.GDG(MEMBER)", "valid_gds" : False}, 32 | {"name": "USER.GDG.TEST", "valid_gds" : False}, 33 | {"name": "USER.GDG(\-33)", "valid_gds": True}, 34 | ] 35 | 36 | @pytest.mark.parametrize("gds", gds_relative_test_data) 37 | def test_gds_valid_relative_name(gds): 38 | assert gds["valid_gds"] == DataSet.is_gds_relative_name(gds["name"]) 39 | 40 | 41 | special_chars_test_data = [ 42 | {"name": "USER.SPECIAL.@TEST", "escaped_name" : r"USER.SPECIAL.\@TEST"}, 43 | {"name": "USER.SPECIAL.A$A", "escaped_name" : r"USER.SPECIAL.A\$A"}, 44 | {"name": "USER.SPECIAL.$TEST#@", "escaped_name" : r"USER.SPECIAL.\$TEST\#\@"}, 45 | {"name": "USER.SPECIAL.TEST", "escaped_name" : r"USER.SPECIAL.TEST"}, 46 | ] 47 | 48 | @pytest.mark.parametrize("data_set", special_chars_test_data) 49 | def test_data_set_name_escaping(data_set): 50 | print(data_set) 51 | 52 | assert data_set["escaped_name"] == DataSet.escape_data_set_name(data_set["name"]) 53 | -------------------------------------------------------------------------------- /tests/unit/test_module_utils_data_set_unit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2024 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import pytest 20 | 21 | from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.data_set import MVSCmdExecError 22 | 23 | IMPORT_NAME = "ansible_collections.ibm.ibm_zos_core.plugins.module_utils.data_set" 24 | 25 | 26 | class DummyModule(object): 27 | """Used in place of Ansible's module 28 | so we can easily mock the desired behavior.""" 29 | 30 | def __init__(self, rc=0, stdout="", stderr=""): 31 | self.rc = rc 32 | self.stdout = stdout 33 | self.stderr = stderr 34 | 35 | def run_command(self, *args, **kwargs): 36 | return (self.rc, self.stdout, self.stderr) 37 | 38 | 39 | # Unit tests are intended to exercise code paths (not test for functionality). 40 | 41 | # These unit tests are NOT run on any z/OS system, so hard-coded data set names will not matter. 42 | data_set_name = "USER.PRIVATE.TESTDS" 43 | 44 | stdout_ds_in_catatlog = """0 45 | LISTCAT ENTRIES('{0}') 46 | 0NONVSAM ------- {0} 47 | IN-CAT --- CATALOG.SVPLEX9.MASTER 48 | 1IDCAMS SYSTEM SERVICES """.format(data_set_name) 49 | 50 | stdout_ds_not_in_catalog=""" 51 | 1IDCAMS SYSTEM SERVICES TIME: 13:34:18 06/06/24 PAGE 1 52 | 0 53 | LISTCAT ENTRIES('{0}') 54 | 0IDC3012I ENTRY {0} NOT FOUND 55 | IDC3009I ** VSAM CATALOG RETURN CODE IS 8 - REASON CODE IS IGG0CLEG-42 56 | IDC1566I ** {0} NOT LISTED 57 | 1IDCAMS SYSTEM SERVICES TIME: 13:34:18 06/06/24 PAGE 2 58 | 0 THE NUMBER OF ENTRIES PROCESSED WAS: 59 | 0 AIX -------------------0 60 | ALIAS -----------------0 61 | CLUSTER ---------------0 62 | DATA ------------------0 63 | GDG -------------------0 64 | INDEX -----------------0 65 | NONVSAM ---------------0 66 | PAGESPACE -------------0 67 | PATH ------------------0 68 | SPACE -----------------0 69 | USERCATALOG -----------0 70 | TAPELIBRARY -----------0 71 | TAPEVOLUME ------------0 72 | TOTAL -----------------0 73 | 0 THE NUMBER OF PROTECTED ENTRIES SUPPRESSED WAS 0 74 | 0IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 4 75 | 0 76 | 0IDC0002I IDCAMS PROCESSING COMPLETE. MAXIMUM CONDITION CODE WAS 4 77 | """.format(data_set_name) 78 | 79 | # passing in a lowercase data set causes idcams to fail. 80 | # this behavior isn't possible via ansible because we upper-case the input. 81 | stdout_mvscmd_failed="""0 82 | LISTCAT ENTRIES('...................') 83 | 0IDC3203I ITEM '...................' DOES NOT ADHERE TO RESTRICTIONS 84 | 0IDC3202I ABOVE TEXT BYPASSED UNTIL NEXT COMMAND. CONDITION CODE IS 12 85 | 0 86 | 0IDC0002I IDCAMS PROCESSING COMPLETE. MAXIMUM CONDITION CODE WAS 12""" 87 | 88 | 89 | @pytest.mark.parametrize( 90 | ("rc, stdout, expected_return, expected_exception_type"), 91 | [ 92 | (0, stdout_ds_in_catatlog, True, None), 93 | (4, stdout_ds_not_in_catalog, False, None), 94 | (12, stdout_mvscmd_failed, None, MVSCmdExecError) 95 | ], 96 | ) 97 | def test_dataset_cataloged_unit(zos_import_mocker, rc, stdout, expected_return, expected_exception_type): 98 | mocker, importer = zos_import_mocker 99 | zos_module_util_data_set = importer(IMPORT_NAME) 100 | mocker.patch( 101 | "{0}.AnsibleModuleHelper".format(IMPORT_NAME), 102 | create=True, 103 | return_value=DummyModule(rc=rc, stdout=stdout), 104 | ) 105 | 106 | 107 | results = None 108 | error_raised = False 109 | try: 110 | results = zos_module_util_data_set.DataSet.data_set_cataloged(data_set_name) 111 | except Exception as e: 112 | error_raised = True 113 | assert type(e) == expected_exception_type 114 | finally: 115 | if not expected_exception_type: 116 | assert not error_raised 117 | assert results == expected_return -------------------------------------------------------------------------------- /tests/unit/test_zoau_version_checker_unit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2023 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | __metaclass__ = type 17 | 18 | from ibm_zos_core.plugins.module_utils.zoau_version_checker import ( 19 | get_zoau_version_str, 20 | is_valid_version_string, 21 | is_zoau_version_higher_than 22 | ) 23 | 24 | import pytest, mock 25 | import types 26 | 27 | # used in patch decorators below 28 | IMPORT_NAME = "ibm_zos_core.plugins.module_utils.zoau_version_checker" 29 | 30 | # Tests for zoau_version_checker 31 | 32 | zoaversion_output = [ 33 | 34 | (['1','0','2'], "2020/03/03 19:24:41 CUT V1.0.2"), 35 | (['1','0','3'], "2020/05/06 18:17:13 CUT V1.0.3"), 36 | (['1','0','3'], "2020/07/07 14:54:31 CUT V1.0.3"), 37 | (['1','1','0'], "2020/08/05 13:08:52 CUT V1.1.0"), 38 | (['1','1','0'], "2020/08/20 12:50:07 CUT V1.1.0"), 39 | (['1','1','0'], "2020/09/16 13:41:25 CUT V1.1.0"), 40 | (['1','1','0'], "2020/09/25 14:07:34 CUT V1.1.0"), 41 | (['1','1','1'], "2021/03/26 15:44:32 CUT V1.1.1"), 42 | (['1','2','0'], "2021/07/07 22:36:30 CUT V1.2.0"), 43 | (['1','2','0'], "2021/08/05 22:12:58 CUT V1.2.0"), 44 | (['1','2','1'], "2022/07/12 18:35:28 CUT V1.2.1"), 45 | (['1','2','1'], "2022/08/17 21:25:13 CUT V1.2.1"), 46 | (['1','2','1'], "2022/08/25 21:44:21 CUT V1.2.1 31163ab 1856"), 47 | (['1','2','1'], "2022/09/07 15:26:50 CUT V1.2.1 d2f6557 1880"), 48 | (['1','2','1','1'], ""), 49 | (['1','2','3'], "2022/12/03 13:33:22 CUT V1.2.3 6113dc9 2512"), 50 | (['1','2','2'], "2022/12/06 20:44:00 CUT V1.2.2 ee30137 2525"), 51 | (['1','2','3'], "2023/03/16 18:17:00 CUT V1.2.3 1aa591fb 2148 PH50145"), 52 | (['1','2','3','1'], ""), 53 | (['1','2','3','2'], ""), 54 | (['1','2','4','0'], "2023/06/02 13:28:30 CUT V1.2.4.0 3b866824 2873 PH52034 826 267d9646"), 55 | (['1','2','4','1'], ""), 56 | (['1','2','4','2'], ""), 57 | (['1','2','4','3'], ""), 58 | (['1','2','4','4'], ""), 59 | (['1','2','4','5'], ""), 60 | (['1','2','5','0'], ""), 61 | (['1','2','5','1'], ""), 62 | (['1','2','5','2'], ""), 63 | (['1','2','5','3'], ""), 64 | (['1','2','5','4'], ""), 65 | (['1','2','5','6'], ""), 66 | 67 | ] 68 | 69 | 70 | @pytest.mark.parametrize("version_string, zoaversion", zoaversion_output) 71 | @mock.patch('subprocess.run') 72 | def test_get_zoau_version_str(mocker, version_string, zoaversion): 73 | # 'get_zoau_version_str' makes a call to 'zoaversion' on the target host by 74 | # calling 'subprocess.run', which returns an object with an attr 'stdout' 75 | # that contains the byte string of the console output. The following mocks 76 | # this behavior so the code can be tested without making a call to a host. 77 | # Instead, zoaversion output for various versions of ZOAU are stored in the 78 | # list of tuples 'zoaversion_output' above and returned by the mocked call 79 | # to 'subprocess.run' after being converted to bytes. SimpleNamespace is an 80 | # object subclass which allows for attributes to be set/removed. In our 81 | # case, 'get_zoau_version_str' expects a 'stdout' attribute in the return 82 | # struct of 'subprocess.run', which we mock via SimpleNamespace. 83 | 84 | mocker.return_value = types.SimpleNamespace( 85 | stdout = bytes(zoaversion, 'utf-8'), 86 | ) 87 | 88 | assert version_string == get_zoau_version_str() 89 | 90 | 91 | @pytest.mark.parametrize("version_string, zoaversion", zoaversion_output) 92 | def test_is_valid_version_string(version_string,zoaversion): 93 | # The first parameter in our zoaversion_output list of tuples above is the 94 | # return value of the function 'get_zoau_version_str' in the form of 95 | # ['#','#','#'] or ['#','#','#','#']. A 'join' str operation with a dot(.) 96 | # yields "#.#.#" or "#.#.#.#". And since these values are taken from this 97 | # list, they can all be expected to be valid ZOAU verison strings. 98 | 99 | assert True == is_valid_version_string('.'.join(version_string)) 100 | 101 | 102 | test_data = [ 103 | # result, "sytem-level" ZOAU >= min-ZOAU 104 | (True, ['1', '2', '1'], "1.2.1"), 105 | (True, ['1', '2', '3'], "1.2.1"), 106 | (True, ['1', '2', '4', '0'], "1.2.2"), 107 | 108 | (False, ['1', '1', '1'], "1.2.3"), 109 | (False, ['1', '1', '1'], "1.2.4.0"), 110 | (False, ['1', '2', '0', '1'], "1.2.1"), 111 | ] 112 | 113 | 114 | @pytest.mark.parametrize("expected, sys_zoau, min_version_str", test_data) 115 | @mock.patch(IMPORT_NAME+'.get_zoau_version_str') 116 | def test_is_zoau_version_higher_than(mocker, expected, sys_zoau, min_version_str): 117 | # The 'is_zoau_version_higher_than' function calls 'get_zoau_version_str' to 118 | # get the ZOAU version string from the system. We mock that call and provide 119 | # our own "system" level ZOAU version str to compare against our provided 120 | # minimum ZOAU version string. 121 | 122 | mocker.return_value = sys_zoau 123 | assert expected == is_zoau_version_higher_than(min_version_str) 124 | -------------------------------------------------------------------------------- /tests/unit/test_zos_gather_facts.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2022 - 2024 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | from ibm_zos_core.plugins.modules.zos_gather_facts import flatten_zinfo_json 17 | 18 | __metaclass__ = type 19 | 20 | import pytest 21 | 22 | # Used my some mock modules, should match import directly below 23 | IMPORT_NAME = "ibm_zos_core.plugins.modules.zos_gather_facts" 24 | 25 | # Tests for zos_father_facts helper functions 26 | 27 | test_data = [ 28 | (["ipl"], ["ipl"]), 29 | (["ipl "], ["ipl"]), 30 | ([" ipl"], ["ipl"]), 31 | (["ipl", "sys"], ["ipl", "sys"]), 32 | (["all"], ["all"]), 33 | (None, ["all"]), 34 | (["ipl", "all", "sys"], ["all"]), 35 | # function does not validate legal vs illegal subsets 36 | (["asdf"], ["asdf"]), 37 | ([""], None), 38 | (["ipl; cat /.bashrc"], None), # attemtped injection 39 | # for now, 'all' with some other invalid subset resolves to 'all' 40 | (["ipl", "all", "ipl; cat /.ssh/id_rsa"], ["all"]), 41 | ] 42 | 43 | 44 | @pytest.mark.parametrize("args,expected", test_data) 45 | def test_zos_gather_facts_zinfo_facts_list_builder( 46 | zos_import_mocker, args, expected): 47 | 48 | mocker, importer = zos_import_mocker 49 | zos_gather_facts = importer(IMPORT_NAME) 50 | 51 | try: 52 | result = zos_gather_facts.zinfo_facts_list_builder(args) 53 | # add more logic here as the function evolves. 54 | except Exception: 55 | result = None 56 | assert result == expected 57 | 58 | 59 | test_data = [ 60 | ( 61 | {'x': {'a': 'aa', 'b': 'bb', 'c': 'cc'}, 62 | 'y': {'d': True}}, 63 | {'a': 'aa', 'b': 'bb', 'c': 'cc', 'd': True} 64 | ), 65 | ({}, {}) 66 | ] 67 | 68 | 69 | @pytest.mark.parametrize("args,expected", test_data) 70 | def test_zos_gather_facts_flatten_zinfo_json( 71 | zos_import_mocker, args, expected): 72 | 73 | mocker, importer = zos_import_mocker 74 | zos_gather_facts = importer(IMPORT_NAME) 75 | 76 | try: 77 | result = zos_gather_facts.flatten_zinfo_json(args) 78 | except Exception: 79 | result = None 80 | assert result == expected 81 | 82 | 83 | test_data = [ 84 | # actual dict, filter_list, expected dict 85 | 86 | # empty filter list 87 | ({'a': 1, 'b': 2}, [], {'a': 1, 'b': 2}), 88 | # filter with * at end 89 | ( 90 | {'dog_1': 1, 'dog_2': 2, 'cat_1': 1, 'cat_2': 2}, 91 | ['dog*'], 92 | {'dog_1': 1, 'dog_2': 2} 93 | ), 94 | # filter with * at front 95 | ( 96 | {'dog_1': 1, 'dog_2': 2, 'cat_1': 1, 'cat_2': 2}, 97 | ['*_2'], 98 | {'dog_2': 2, 'cat_2': 2} 99 | ), 100 | # filter wtih exact match 101 | ( 102 | {'dog_1': 1, 'dog_2': 2, 'cat_1': 1, 'cat_2': 2}, 103 | ['cat_2'], 104 | {'cat_2': 2} 105 | ), 106 | # empty dict, empty filter 107 | ({}, [], {}), 108 | # empty dict, non-empty filter 109 | ({}, ['a*'], {}), 110 | 111 | ] 112 | 113 | 114 | @pytest.mark.parametrize("actual,filter_list,expected", test_data) 115 | def test_zos_gather_facts_apply_filter( 116 | zos_import_mocker, actual, filter_list, expected): 117 | 118 | mocker, importer = zos_import_mocker 119 | zos_gather_facts = importer(IMPORT_NAME) 120 | 121 | try: 122 | result = zos_gather_facts.apply_filter(actual, filter_list) 123 | except Exception: 124 | result = None 125 | assert result == expected 126 | -------------------------------------------------------------------------------- /tests/unit/test_zos_operator_action_query_unit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2019, 2020 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | __metaclass__ = type 17 | 18 | 19 | from ansible.module_utils.basic import AnsibleModule 20 | import pytest 21 | import sys 22 | from mock import call 23 | 24 | # Used my some mock modules, should match import directly below 25 | IMPORT_NAME = "ibm_zos_core.plugins.modules.zos_operator_action_query" 26 | 27 | 28 | # * Tests for zos_operator_action_query 29 | 30 | dummy_dict1 = {} 31 | 32 | dummy_dict2 = {"system": "mv2c"} 33 | 34 | 35 | dummy_dict3 = {"message_id": "DFH*"} 36 | 37 | dummy_dict4_uppercase = {"message_id": "DFH*", "system": "MV28"} 38 | 39 | dummy_dict4_lowercase = {"message_id": "DFH*", "system": "mv28"} 40 | 41 | dummy_dict5 = {"message_filter": {"filter": "^.*IMS.*$", "use_regex": True}} 42 | 43 | dummy_dict6 = {"system": "mv27", "message_id": "DFS*", "job_name": "IM5H*", "message_filter": {"filter": "IMS"}} 44 | 45 | dummy_dict_invalid_message = {"message_id": "$$#$%#"} 46 | dummy_dict_invalid_filter = {"message_filter": {"filter": "*IMS", "use_regex": True}} 47 | dummy_dict_invalid_job_name = {"job_name": "IM5H123456"} 48 | dummy_dict_invalid_system = {"system": "mv2712345"} 49 | 50 | 51 | test_data = [ 52 | (dummy_dict1, True), 53 | (dummy_dict2, True), 54 | (dummy_dict3, True), 55 | (dummy_dict4_uppercase, True), 56 | (dummy_dict4_lowercase, True), 57 | (dummy_dict5, True), 58 | (dummy_dict6, True), 59 | (dummy_dict_invalid_message, False), 60 | (dummy_dict_invalid_filter, False), 61 | (dummy_dict_invalid_job_name, False), 62 | (dummy_dict_invalid_system, False), 63 | ] 64 | 65 | 66 | @pytest.mark.parametrize("args,expected", test_data) 67 | def test_zos_operator_action_query_various_args(zos_import_mocker, args, expected): 68 | mocker, importer = zos_import_mocker 69 | zos_operator_action_query = importer(IMPORT_NAME) 70 | passed = True 71 | try: 72 | zos_operator_action_query.parse_params(args) 73 | except Exception: 74 | passed = False 75 | assert passed == expected 76 | -------------------------------------------------------------------------------- /tests/unit/test_zos_operator_unit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (c) IBM Corporation 2019, 2020 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from __future__ import absolute_import, division, print_function 15 | 16 | __metaclass__ = type 17 | 18 | from ansible.module_utils.basic import AnsibleModule 19 | import pytest 20 | import sys 21 | from mock import call 22 | 23 | # Used my some mock modules, should match import directly below 24 | IMPORT_NAME = "ibm_zos_core.plugins.modules.zos_operator" 25 | 26 | 27 | # * Tests for zos_operator 28 | 29 | dummy_dict1 = { 30 | "verbose": False, 31 | } 32 | 33 | dummy_dict2 = { 34 | "cmd": 123, 35 | "verbose": True, 36 | } 37 | 38 | dummy_dict3 = {"cmd": "d u,all"} 39 | 40 | dummy_dict4 = {"cmd": "d u,all", "verbose": True} 41 | 42 | dummy_dict5 = {"cmd": "d u,all", "verbose": "NotTrueOrFalse"} 43 | 44 | dummy_return_dict1 = {"rc": 0, "message": "good result"} 45 | 46 | dummy_return_dict2 = {"rc": 1, "message": None} 47 | 48 | test_data = [ 49 | (dummy_dict1, False), 50 | (dummy_dict2, False), 51 | (dummy_dict3, True), 52 | (dummy_dict4, True), 53 | (dummy_dict5, False), 54 | ] 55 | 56 | 57 | @pytest.mark.parametrize("args,expected", test_data) 58 | def test_zos_opreator_various_args(zos_import_mocker, args, expected): 59 | mocker, importer = zos_import_mocker 60 | zos_operator = importer(IMPORT_NAME) 61 | passed = True 62 | try: 63 | zos_operator.parse_params(args) 64 | except Exception as e: 65 | passed = False 66 | assert passed == expected 67 | --------------------------------------------------------------------------------