├── .ansible-lint ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CLA.md ├── CONTRIBUTING.md ├── LICENSE ├── README-GALAXY.md ├── README.md ├── blueprints └── sdr-rcvr │ ├── demo.yml │ ├── receiver-config.mqsc │ ├── sdr-rcvr.yml │ ├── sender-config.mqsc │ └── setup.yml ├── docs ├── MQ_UPGRADE.md ├── QUEUE_MANAGER.md └── WINSTALL.md ├── galaxy.yml ├── meta └── runtime.yml ├── playbooks ├── ansible.cfg ├── files │ └── dev-config.mqsc ├── ibmmq.yml ├── mq-install.yml ├── mq-setup.yml ├── mq-upgrade.yml ├── mq-winstall.yml └── sample-playbook.yml ├── plugins └── modules │ └── queue_manager.py ├── requirements.txt ├── roles ├── applyfixpack │ ├── README.md │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── Linux_applyfixpack.yml │ │ └── main.yml ├── downloadmq │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ ├── AIX_ppc64le_downloadmq.yml │ │ ├── Linux_s390x_downloadmq.yml │ │ ├── Linux_x86_64_downloadmq.yml │ │ ├── Win32NT_64-bit_downloadmq.yml │ │ └── main.yml │ └── vars │ │ ├── Win32NT_64-bit_downloadmq.yml │ │ └── common_downloadmq.yml ├── getconfig │ ├── README.md │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── AIX_getconfig.yml │ │ ├── Linux_getconfig.yml │ │ ├── Win32NT_setupenvironment.yml │ │ └── main.yml ├── installmq │ ├── README.md │ ├── tasks │ │ ├── AIX_installmq.yml │ │ ├── Linux_installmq.yml │ │ ├── Win32NT_installmq.yml │ │ └── main.yml │ └── vars │ │ ├── AIX_installmq.yml │ │ ├── Linux_installmq.yml │ │ └── Win32NT_installmq.yml ├── setupconsole │ ├── README.md │ └── tasks │ │ ├── AIX_setupconsole.yml │ │ ├── Linux_setupconsole.yml │ │ ├── Win32NT_setupconsole.yml │ │ └── main.yml ├── setupenvironment │ ├── README.md │ └── tasks │ │ ├── AIX_setupenvironment.yml │ │ ├── Linux_setupenvironment.yml │ │ ├── Win32NT_setupenvironment.yml │ │ └── main.yml ├── setupusers │ ├── README.md │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── AIX_setupusers.yml │ │ ├── Linux_setupusers.yml │ │ ├── Win32NT_setupusers.yml │ │ └── main.yml └── startconsole │ ├── README.md │ └── tasks │ ├── AIX_startconsole.yml │ ├── Linux_startconsole.yml │ ├── Win32NT_startconsole.yml │ └── main.yml ├── tests ├── playbooks │ ├── 1_test_install.yml │ ├── 2_setup_test.yml │ ├── 3_test_absent_qmgr.yml │ ├── 4_test_present_qmgr.yml │ ├── 5_test_running_qmgr.yml │ ├── 6_test_misc.yml │ ├── 7_test_web_console.yml │ ├── 8_cleanup_test.yml │ ├── 9_test_all_qmgrs.yml │ ├── ansible.cfg │ ├── main_test.yml │ ├── mqsc_display │ ├── test_windows_install.yml │ ├── test_windows_webconsole.yml │ ├── tests_unix_based.yml │ └── tests_windows.yml └── unit │ └── test_queue_manager.py └── tmp └── args.json /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | profile: # min, basic, moderate,safety, shared, production 3 | 4 | # Allows dumping of results in SARIF format 5 | # sarif_file: result.sarif 6 | 7 | # exclude_paths included in this file are parsed relative to this file's location 8 | # and not relative to the CWD of execution. CLI arguments passed to the --exclude 9 | # option are parsed relative to the CWD of execution. 10 | exclude_paths: 11 | - .ansible-lint 12 | - .cache/ # implicit unless exclude_paths is defined in config 13 | - .github/ 14 | # - test/fixtures/formatting-before/ 15 | # - test/fixtures/formatting-prettier/ 16 | # parseable: true 17 | # quiet: true 18 | # strict: true 19 | # verbosity: 1 20 | 21 | # Mock modules or roles in order to pass ansible-playbook --syntax-check 22 | mock_modules: 23 | - queue_manager 24 | # note the foo.bar is invalid as being neither a module or a collection 25 | # - fake_namespace.fake_collection.fake_module 26 | # - fake_namespace.fake_collection.fake_module.fake_submodule 27 | # mock_roles: 28 | # - mocked_role 29 | # - author.role_name # old standalone galaxy role 30 | # - fake_namespace.fake_collection.fake_role # role within a collection 31 | 32 | # Enable checking of loop variable prefixes in roles 33 | # loop_var_prefix: ^(__|{role}_) 34 | 35 | # Enforce variable names to follow pattern below, in addition to Ansible own 36 | # requirements, like avoiding python identifiers. To disable add `var-naming` 37 | # to skip_list. 38 | var_naming_pattern: ^[a-z_][a-z0-9_]*$ 39 | 40 | use_default_rules: true 41 | # Load custom rules from this specific folder 42 | # rulesdir: 43 | # - ./rule/directory/ 44 | 45 | # Ansible-lint is able to recognize and load skip rules stored inside 46 | # `.ansible-lint-ignore` (or `.config/ansible-lint-ignore.txt`) files. 47 | # To skip a rule just enter filename and tag, like "playbook.yml package-latest" 48 | # on a new line. 49 | # Optionally you can add comments after the tag, prefixed by "#". We discourage 50 | # the use of skip_list below because that will hide violations from the output. 51 | # When putting ignores inside the ignore file, they are marked as ignored, but 52 | # still visible, making it easier to address later. 53 | skip_list: 54 | - fqcn-builtins # For the sake of readability 55 | - empty-string-compare 56 | 57 | # Ansible-lint does not automatically load rules that have the 'opt-in' tag. 58 | # You must enable opt-in rules by listing each rule 'id' below. 59 | enable_list: 60 | - args 61 | - no-log-password # opt-in 62 | - no-same-owner # opt-in 63 | # add yaml here if you want to avoid ignoring yaml checks when yamllint 64 | # library is missing. Normally its absence just skips using that rule. 65 | - yaml 66 | # Report only a subset of tags and fully ignore any others 67 | # tags: 68 | # - jinja[spacing] 69 | 70 | # Ansible-lint does not fail on warnings from the rules or tags listed below 71 | warn_list: 72 | - experimental # experimental is included in the implicit list 73 | # - role-name 74 | # - yaml[document-start] # you can also use sub-rule matches 75 | 76 | # Some rules can transform files to fix (or make it easier to fix) identified 77 | # errors. `ansible-lint --write` will reformat YAML files and run these transforms. 78 | # By default it will run all transforms (effectively `write_list: ["all"]`). 79 | # You can disable running transforms by setting `write_list: ["none"]`. 80 | # Or only enable a subset of rule transforms by listing rules/tags here. 81 | write_list: 82 | - all 83 | 84 | # Offline mode disables installation of requirements.yml and schema refreshing 85 | offline: false 86 | 87 | # Return success if number of violations compared with previous git 88 | # commit has not increased. This feature works only in git 89 | # repositories. 90 | progressive: false 91 | 92 | # Define required Ansible's variables to satisfy syntax check 93 | extra_vars: 94 | foo: bar 95 | multiline_string_variable: | 96 | line1 97 | line2 98 | complex_variable: ":{;\t$()" 99 | 100 | # Uncomment to enforce action validation with tasks, usually is not 101 | # needed as Ansible syntax check also covers it. 102 | # skip_action_validation: false 103 | 104 | # List of additional kind:pattern to be added at the top of the default 105 | # match list, first match determines the file kind. 106 | kinds: 107 | # - playbook: "**/examples/*.{yml,yaml}" 108 | - playbook: "**/ibmmq/*.{yml,yaml}" 109 | - playbook: "**/playbooks/*.{yml,yaml}" 110 | # - galaxy: "**/folder/galaxy.yml" 111 | - tasks: "**/tasks/*.yml" 112 | - vars: "**/vars/*.yml" 113 | - meta: "**/meta/main.yml" 114 | # - yaml: "**/*.yaml-too" 115 | 116 | # List of additional collections to allow in only-builtins rule. 117 | # only_builtins_allow_collections: 118 | # - example_ns.example_collection 119 | 120 | # List of additions modules to allow in only-builtins rule. 121 | # only_builtins_allow_modules: 122 | # - example_module 123 | 124 | # Allow setting custom prefix for name[prefix] rule 125 | task_name_prefix: "{stem} | " 126 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create an issue to report a bug to us 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behaviour (For Example): 15 | 1. Use this config '....' 16 | 2. Setup inventory file with '....' 17 | 3. Run the playbook 18 | 4. See the following Error 19 | 20 | **Expected behaviour** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. These can include the error message or screenshots of your config for extra context. 25 | 26 | **Tell us the platform and version of the machine that ansible is being run on:** 27 | - OS: [e.g. Windows] 28 | - Version [e.g. 11] 29 | 30 | **Tell us the version of ansible being used:** 31 | - Version [e.g. core 2.12.4] 32 | 33 | **Tell us the platforms and versions of the machines that the playbook is targetting (Usually supplied in an inventory file):** 34 | - OS: [e.g. Ubuntu] 35 | - Version [e.g. 23.10] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac Directory Files 2 | *.DS_STORE 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | *.ini 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | 135 | # Ansible Unit Tests 136 | ansible_collections/tests/unit/output/ 137 | groups_vars/windows.yml 138 | .vscode/settings.json 139 | -------------------------------------------------------------------------------- /CLA.md: -------------------------------------------------------------------------------- 1 | IBM Contributor License Agreement 2 | ================================= 3 | 4 | Version 1.0.0 January 14, 2014 5 | 6 | In order for You (as defined below) to make intellectual property Contributions (as defined below) now or in the future to IBM GitHub repositories, 7 | You must agree to this Contributor License Agreement ("CLA"). 8 | 9 | Please read this CLA carefully before accepting its terms. By accepting the CLA, You are agreeing to be bound by its terms. 10 | If You submit a Pull Request against an IBM repository on GitHub You must include in the Pull Request a statement of Your acceptance of this CLA. 11 | 12 | As used in this CLA: 13 | (i) "You" (or "Your") shall mean the entity that is making this Agreement with IBM; 14 | (ii)"Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is submitted by You to IBM for inclusion in, 15 | or documentation of, any of the IBM GitHub repositories; 16 | (iii) "Submit" (or "Submitted") means any form of communication sent to IBM (e.g. the content You post in a GitHub Issue or submit as part of a GitHub Pull Request). 17 | 18 | This agreement applies to all Contributions You Submit. 19 | 20 | This CLA, and the license(s) associated with the particular IBM GitHub repositories You are contributing to, provides a license to Your Contributions to IBM and downstream consumers, 21 | but You still own Your Contributions, and except for the licenses provided for in this CLA, You reserve all right, title and interest in Your Contributions. 22 | 23 | IBM requires that each Contribution You Submit now or in the future comply with the following four commitments. 24 | 25 | 1) You will only Submit Contributions where You have authored 100% of the content. 26 | 2) You will only Submit Contributions to which You have the necessary rights. This means that if You are employed You have received the necessary permissions from Your employer to make the 27 | Contributions. 28 | 3) Whatever content You Contribute will be provided under the license(s) associated with the particular IBM GitHub repository You are contributing to. 29 | 4) You understand and agree that IBM GitHub repositories and Your contributions are public, and that a record of the contribution (including all personal information You submit with it) 30 | is maintained indefinitely and may be redistributed consistent with the license(s) involved. You will promptly create an Issue in the appropriate GitHub repository if You become aware of any facts or circumstances that would make these commitments inaccurate in any way. 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to MQ-Ansible 2 | 3 | Thank you for your interest in contributing to our open-source project, MQ-Ansible. 4 | 5 | To ensure that the codebase is always healthy and does not result in deployment issues when forked and used, it is important that you pre-check your additions and updates for any potential code conflicts before uploading your changes to the GitHub Repository. 6 | 7 | Therefore, the following steps should be followed to submit your contributions: 8 | 9 | 1. Fork the repository 10 | 2. Create and run Ansible Test Playbooks 11 | 3. Commit/Push changes to your fork 12 | 4. Create a Pull Request 13 | 14 | 15 | ### 1. Fork the repository 16 | 17 | To fork the repository: 18 | - Get started by clicking on "Fork" from the top-right corner of the main repository page. 19 | - Choose a name and description for your fork. 20 | - Select the option "Copy the main branch only", as in most cases, you will only need the default branch to be copied. 21 | - Click on "Create fork". 22 | 23 | Once you have forked the repository, you can then clone your fork to your computer locally. In order to do that: 24 | - Click on "Code" (the green button on your forked repository). 25 | - Copy the forked repository URL under HTTPS. 26 | - Type the following on your terminal: 27 | 28 | ``` 29 | git clone 30 | ``` 31 | 32 | You can set up Git to pull updates from the MQ-Ansible repository into the local clone of your fork when you fork a project in order to propose changes to the MQ-Ansible repository. In order to do that, run the following command: 33 | 34 | ``` 35 | git remote add upstream https://github.com/ibm-messaging/mq-ansible 36 | ``` 37 | 38 | To verify the new upstream repository you have specified for your fork, run the following command: 39 | 40 | ``` 41 | git remote -v 42 | ``` 43 | 44 | You should see the URL for your fork as origin, and the URL for the MQ-Ansible repository as upstream. 45 | 46 | Now, you can work locally and commit to your changes to your fork. This will not impact the main branch. 47 | 48 | ### 2. Create and run Ansible Test Playbooks 49 | 50 | Before committing changes, ensure that they work with the main codebase. 51 | 52 | In the repository, navigate to “~/tests/playbooks”. You will find a group of YAML playbooks that will ensure the deployment is still successful with your proposed changes. 53 | 54 | For any additions you contribute with, you will also need to write “assert that” statements to confirm that your changes will not break the codebase or cause any issues. You can go through the Python files in the directory to get an idea of how these Test Playbooks should be structured. 55 | 56 | After writing your Test Playbooks, make sure to include them in the “main.py” file to execute all of the Test Playbooks at once. It will look something like this: 57 | 58 | ``` 59 | subprocess.run(['ansible-playbook', '--inventory', 'inventory.ini', 'playbook_name.yml']) 60 | ``` 61 | 62 | If the playbook runs successfully and no errors are displayed, then proceed to Step #3. 63 | 64 | ### 3. Commit/Push changes to your fork 65 | 66 | If you are looking to add all the files you have modified in a particular directory, you can stage them all with the following command: 67 | 68 | ``` 69 | git add . 70 | ``` 71 | 72 | If you are looking to recursively add all changes including those in subdirectories, you can type: 73 | 74 | ``` 75 | git add -A 76 | ``` 77 | 78 | Alternatively, you can type _git add -all_ for all new files to be staged. 79 | 80 | Once you are ready to submit your changes, ensure that you commit them to your fork with a message. The commit message is an important aspect of your code contribution; it helps the maintainers of MQ-Ansible and other contributors to fully understand the change you have made, why you made it, and how significant it is. 81 | 82 | You can commit your changes by running: 83 | 84 | ``` 85 | git commit -m "Brief description of your changes/additions" 86 | ``` 87 | 88 | To push all your changes to the forked repo: 89 | 90 | ``` 91 | git push 92 | ``` 93 | 94 | ### 4. Create a Pull Request 95 | 96 | Merge any changes that were made in the original repository’s main branch: 97 | 98 | ``` 99 | git merge upstream/main 100 | ``` 101 | 102 | Before creating a Pull Request, ensure you have read the [IBM Contributor License Agreement](CLA.md). By creating a PR, you certify that your contribution: 103 | 1. is licensed under Apache Licence Version 2.0, The MIT License, or any BSD License. 104 | 2. does not result in IBM MQ proprietary code being statically or dynamically linked to Ansible runtime. 105 | 106 | Once you have carefully read and agreed to the terms mentioned in the [CLA](CLA.md), you are ready to make a pull request to the original repository. 107 | 108 | Navigate to your forked repository and press the _New pull request_ button. Then, you should add a title and a comment to the appropriate fields and then press the _Create pull request_ button. 109 | 110 | The maintainers of the original repository will then review your contribution and decide whether or not to accept your pull request. 111 | 112 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README-GALAXY.md: -------------------------------------------------------------------------------- 1 | # *MQ-Ansible* 2 | 3 | | :memo: | Interested in contributing to this project? Please read our [IBM Contributor License Agreement](CLA.md) and our [Contributing Guide](CONTRIBUTING.md). | 4 | |---------------|:------------------------| 5 | 6 | A collection for automating the installation and configuration of IBM MQ using Ansible on Ubuntu, Redhat, Windows and IBM AIX machines. Our aim is to make MQ-Ansible extensible for other platforms and more detailed IBM MQ configuration. 7 | 8 | This directory contains: 9 | - ansible [`roles`](https://github.com/ibm-messaging/mq-ansible/tree/main/roles) for the installation and configuration of IBM MQ. 10 | - module [`queue_manager.py`](plugins/modules/queue_manager.py) to create and configure a queue manager. 11 | - playbook [`ibmmq.yml`](playbooks/ibmmq.yml) which implements the roles and module. 12 | 13 | For a detailed explanation and documentation on how MQ-Ansible works, click [here](https://github.com/ibm-messaging/mq-ansible/wiki). 14 | 15 | | Section | 16 | | :------ | 17 | | [Requirements](https://github.com/ibm-messaging/mq-ansible#requirements) | 18 | | [Our collection - IBM MQ installation on target machines](https://github.com/ibm-messaging/mq-ansible/README-GALAXY.md#our-collection---ibm-mq-installation-on-target-machines) | 19 | | [Ansible Galaxy - Installation](https://github.com/ibm-messaging/mq-ansible/#ansible-galaxy---installation) | 20 | 21 | ## Requirements 22 | 23 | - `ansible`, `passlib` and `ansible-lint` are required on your local machine to run playbooks implementing this collection. 24 | - a target machine of any of the supported platforms: 25 | - Ubuntu 26 | - RedHat 27 | - Windows 28 | - IBM AIX 29 | 30 | ##### *Ansible* installation ([Installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)) 31 | 32 | # Our collection - IBM MQ installation on target machines 33 | The implementation of our collection can carry out an installation of IBM MQ Advanced on a target machine with Ansible roles. These roles set up the required users on the machine, download the software, install and configure IBM MQ, copy over a configurable `dev-config.mqsc` file ready to be run on the target machine, and setup and start the web console. Developers can change this file to customise the configuration of their queue managers. 34 | 35 | - `setupusers` - creates the `mqm`, `admin`, and `app` users; the `mqm`, `mqclient` groups; and sets the MQ environment variables. User and group IDs can be specified when calling this role. 36 | 37 | - `downloadmq` - downloads and unzips the appropriate MQ package based on the target platform to `/var/MQServer` on the target machine. The MQ version to be installed can be specified when calling this role. 38 | You can also specify a local source for the MQ source packages to be copied over to target machine. Example: 39 | 40 | ```yaml 41 | - role: downloadmq 42 | vars: 43 | local_source: true 44 | mq_local_path: YOUR_PATH 45 | ``` 46 | Where `YOUR_PATH` is the local path to the MQ source package. Example: `/Users/user1/Downloads/mqadv_dev932_ubuntu_x86-64.tar.gz` 47 | 48 | - `installmq` - handles platform-specific installation steps, where Ubuntu machines carry out a Debian installation and RedHat machines carry out an RPM installation. Core MQ components are installed as default, however further components and languages can be be added by uncommenting packages within the `package_files` list in `/roles/installmq/tasks/main.yml`: 49 | 50 | ##### *Note*: For Ubuntu, dependencies are sensitive to the order of regex-matched packages in the `with_items` attribute of the above task. 51 | 52 | - `getconfig` - copies the dev-config.mqsc file to the target machine. You can also specify a local sourced MQSC file with the var `mqsc_local`. 53 | 54 | - `setupconsole` - configures a target machine's environment and permissions to be able to run the MQ Web Console. 55 | 56 | - `startconsole` - starts the MQ Web Console. 57 | 58 | ## Installation roles on Windows machines 59 | 60 | Detailed documentation and guide for installing MQ on Windows using our roles can be found [here](https://github.com/ibm-messaging/mq-ansible/blob/main/docs/WINSTALL.md). 61 | 62 | ## Modules for IBM MQ resources' configuration 63 | 64 | - `queue_manager.py` - Creates, starts, deletes an IBM MQ queue manager and runs an MQSC file. See the documentation [here.](https://github.com/ibm-messaging/mq-ansible/blob/main/docs/QUEUE_MANAGER.md) 65 | 66 | # Ansible Galaxy - Installation 67 | 68 | 1. First, make sure that you have the minimun required version of ansible core with 69 | 70 | ``` 71 | ansible --version 72 | ``` 73 | 74 | 2. Install the latest version from our github repo with 75 | 76 | ``` 77 | ansible-galaxy collection install git+https://github.com/ibm-messaging/mq-ansible.git,main 78 | ``` 79 | 80 | or the latest version in ansible galaxy with: 81 | 82 | ``` 83 | ansible-galaxy collection install ibm_messaging.ibmmq 84 | ``` 85 | 86 | 3. In your desired working directory, make sure to create your ansible inventory `inventory.ini` with the proper target hosts, as you'll refer to them while running the playbook: 87 | 88 | ``` 89 | [mqservers] 90 | my.mqserver-001.dev 91 | my.mqserver-002.dev 92 | ``` 93 | 94 | 4. Create now a playbook file `setup-playbook.yml` with the following content to try our roles and modules: 95 | 96 | ``` 97 | --- 98 | - name: prepares MQ server 99 | hosts: mqservers 100 | become: true 101 | environment: 102 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 103 | collections: 104 | - ibm_messaging.ibmmq 105 | 106 | tasks: 107 | - name: Import downloadmq role 108 | ansible.builtin.import_role: 109 | name: ibm_messaging.ibmmq.downloadmq 110 | 111 | - name: Import setupusers role 112 | ansible.builtin.import_role: 113 | name: ibm_messaging.ibmmq.setupusers 114 | 115 | - name: Import installmq role 116 | ansible.builtin.import_role: 117 | name: ibm_messaging.ibmmq.installmq 118 | 119 | - name: Import setupenvironment role 120 | ansible.builtin.import_role: 121 | name: ibm_messaging.ibmmq.setupenvironment 122 | 123 | - name: Get MQSC file 124 | become: true 125 | become_user: mqm 126 | ansible.builtin.import_role: 127 | name: ibm_messaging.ibmmq.getconfig 128 | vars: 129 | mqsc_local: ../../../playbooks/files/dev-config.mqsc 130 | 131 | - name: Set up web console 132 | become: true 133 | become_user: mqm 134 | ansible.builtin.import_role: 135 | name: ibm_messaging.ibmmq.setupconsole 136 | 137 | - name: Start web console 138 | become: true 139 | become_user: mqm 140 | ansible.builtin.import_role: 141 | name: ibm_messaging.ibmmq.startconsole 142 | 143 | - name: Create a queue manager 144 | become_user: mqm 145 | tags: ["queue"] 146 | ibm_messaging.ibmmq.queue_manager: 147 | qmname: queue_manager_12 148 | state: present 149 | 150 | - name: Use our MQSC File 151 | become: true 152 | become_user: mqm 153 | ibm_messaging.ibmmq.queue_manager: 154 | qmname: queue_manager_12 155 | state: running 156 | mqsc_file: /var/mqm/dev-config.mqsc 157 | ``` 158 | 159 | 5. Run it with 160 | 161 | ``` 162 | ansible-playbook setup-playbook.yml -i ./inventory.ini -e 'ibmMqLicence=accept' 163 | ``` 164 | 165 | # License 166 | 167 | [Apache 2.0 license](LICENSE) 168 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # *MQ-Ansible* 2 | 3 | ## Issue Support 4 | 5 | The code in this repository is provided and maintained on a community basis, and is not covered by any IBM commercial support agreement or warranty. 6 | 7 | For enhancements, issues and fixes you are welcome raise an issue against this repository so that it may be considered. Alternatively, you may contribute updates as per the CLA outlined below. 8 | 9 | | :memo: | Interested in contributing to this project? Please read our [IBM Contributor License Agreement](CLA.md) and our [Contributing Guide](CONTRIBUTING.md). | 10 | |---------------|:------------------------| 11 | 12 | 13 | ## What is MQ-Ansible? 14 | 15 | A collection for automating the installation and configuration of IBM MQ using Ansible on Ubuntu, Redhat, Windows and IBM AIX machines. Our aim is to make MQ-Ansible extensible for other platforms and more detailed IBM MQ configuration. 16 | 17 | This directory contains: 18 | - ansible [`roles`](https://github.com/ibm-messaging/mq-ansible/tree/main/roles) for the installation and configuration of IBM MQ. 19 | - module [`queue_manager.py`](plugins/modules/queue_manager.py) to create and configure a queue manager. 20 | - playbook [`ibmmq.yml`](playbooks/ibmmq.yml) which implements the roles and module. 21 | 22 | For a detailed explanation and documentation on how MQ-Ansible works, click [here](https://github.com/ibm-messaging/mq-ansible/wiki). 23 | 24 | | Section | 25 | | :------ | 26 | | [Requirements](https://github.com/ibm-messaging/mq-ansible#requirements) | 27 | | [Playbooks and Roles for IBM MQ installation](https://github.com/ibm-messaging/mq-ansible#playbooks-and-roles-for-ibm-mq-installation-on-ubuntu-target-machines) | 28 | | [Run our sample playbook](https://github.com/ibm-messaging/mq-ansible#run-our-sample-playbook) | 29 | | [Troubleshooting](https://github.com/ibm-messaging/mq-ansible/tree/aix-support#troubleshooting) | 30 | | [Testing Framework](https://github.com/ibm-messaging/mq-ansible/#testing-framework) | 31 | | [Ansible Galaxy - Installation](https://github.com/ibm-messaging/mq-ansible/#ansible-galaxy---installation) | 32 | 33 | ## Requirements 34 | 35 | - `ansible`, `passlib` and `ansible-lint` are required on your local machine to run playbooks implementing this collection. 36 | - a target machine of any of the supported platforms: 37 | - Ubuntu 38 | - RedHat 39 | - Windows 40 | - IBM AIX 41 | 42 | ##### *Ansible* installation ([Installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)) 43 | 44 | # Playbooks and Roles for IBM MQ installation on Ubuntu target machines 45 | The playbooks and roles in this collection carry out an installation of IBM MQ Advanced on a target machine. The roles have been implemented to set up the required users on the machine, download the software, install and configure IBM MQ, copy over a configurable `dev-config.mqsc` file ready to be run on the target machine, and setup and start the web console. Developers can change this file to customise the configuration of their queue managers. Here we use a playbook that calls other playbooks but you can run the roles in playbooks to suit your requirements. 46 | 47 | ## Example Playbooks 48 | 49 | `ibmmq.yml` - this playbook calls the mq-install and mq-setup playbooks, host names are passed into the imported playbook variable as {{ ansible_play_batch }} 50 | 51 | ```yaml 52 | - name: Install and setup IBM MQ 53 | hosts: ['servers'] 54 | 55 | - name: Run the install playbook 56 | import_playbook: mq-install.yml 57 | 58 | - name: Run the setup playbook 59 | import_playbook: mq-setup.yml 60 | ``` 61 | 62 | `mq-install.yml` - this playbook installs IBM MQ with the SSH user specified in the inventory. 63 | ##### *Note*: The MQ *version* and app user's *UID and GID* can be specified here. 64 | ```yaml 65 | - hosts: "{{ ansible_play_batch }}" 66 | serial: 1 67 | become: false 68 | environment: 69 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 70 | 71 | roles: 72 | - role: setupusers 73 | vars: 74 | app_uid: 909 75 | app_gid: 909 76 | mqm_home: /home/mqm 77 | mqm_profile: .profile 78 | - role: downloadmq 79 | vars: 80 | version: 930 81 | ``` 82 | `mq-setup.yml` - this playbook sets up IBM MQ using the 'mqm' user 83 | 84 | ```yaml 85 | - hosts: "{{ ansible_play_hosts }}" 86 | serial: 1 87 | become: yes 88 | become_user: mqm 89 | environment: 90 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 91 | 92 | roles: 93 | - getconfig 94 | - setupconsole 95 | - startconsole 96 | 97 | tasks: 98 | 99 | - name: Create a queue manager 100 | queue_manager: 101 | qmname: 102 | - 'QM1' 103 | - 'QM2' 104 | state: 'present' 105 | ``` 106 | 107 | `mq-upgrade.yml` - this playbook installs an applicable fix pack to an existing MQ installation 108 | 109 | ```yaml 110 | - hosts: "{{ ansible_play_batch }}" 111 | serial: 1 112 | become: true 113 | environment: 114 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 115 | 116 | roles: 117 | - role: applyfixpack 118 | vars: 119 | mq_local_path: ~/tmp/ 120 | ``` 121 | ## Roles 122 | 123 | - `setupusers` - creates the `mqm`, `admin`, and `app` users; the `mqm`, `mqclient` groups; and sets the MQ environment variables. User and group IDs can be specified when calling this role. 124 | 125 | - `downloadmq` - downloads and unzips the appropriate MQ package based on the target platform to `/var/MQServer` on the target machine. The MQ version to be installed can be specified when calling this role. 126 | You can also specify a local source for the MQ source packages to be copied over to target machine. Example: 127 | 128 | ```yaml 129 | - role: downloadmq 130 | vars: 131 | local_source: true 132 | mq_local_path: YOUR_PATH 133 | ``` 134 | Where `YOUR_PATH` is the local path to the MQ source package. Example: `/Users/user1/Downloads/mqadv_dev932_ubuntu_x86-64.tar.gz` 135 | 136 | - `installmq` - handles platform-specific installation steps, where Ubuntu machines carry out a Debian installation and RedHat machines carry out an RPM installation. Core MQ components are installed as default, however further components and languages can be be added by uncommenting packages within the `package_files` list in `/roles/installmq/tasks/main.yml`: 137 | 138 | ##### *Note*: For Ubuntu, dependencies are sensitive to the order of regex-matched packages in the `with_items` attribute of the above task. 139 | 140 | - `getconfig` - copies the dev-config.mqsc file to the target machine. You can also specify a local sourced MQSC file with the var `mqsc_local`. 141 | 142 | - `setupconsole` - configures a target machine's environment and permissions to be able to run the MQ Web Console. 143 | 144 | - `startconsole` - starts the MQ Web Console. 145 | 146 | `applyfixpack` - installs a locally available fix pack to an existing MQ installation. The selected fix pack must be applicable to the MQ version already existing on the target machine. 147 | 148 | ## Modules for IBM MQ resources' configuration 149 | 150 | - `queue_manager.py` - Creates, starts, deletes an IBM MQ queue manager and runs an MQSC file. See the documentation [here.](docs/QUEUE_MANAGER.md) 151 | 152 | ## Installation roles on Windows machines 153 | 154 | Detailed documentation and guide for installing MQ on Windows using our roles can be found [here](docs/WINSTALL.md). 155 | 156 | # Run our sample playbook 157 | 158 | ##### *Note*: *Ansible* must be installed on the local machine ([Installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)) 159 | 160 | Before running the playbook and implementing our modules and roles for IBM MQ: 161 | 162 | 1. Check if you have an *ssh* key pair in order to access the target machines via SSH. Go to the `~/.ssh` directory in your machine and look for the public and private key files e.g. `id_rsa` and `id_rsa.pub`. 163 | 164 | ```shell 165 | cd ~/.ssh 166 | ``` 167 | 168 | 2. If those two files are not in your `ssh` directory, you need to generate `id_rsa` and `id_rsa.pub` with the following command: 169 | 170 | ```shell 171 | ssh-keygen 172 | ``` 173 | 174 | 3. Once the keys have been generated, you need to copy the public key to the target machine's user `ssh` directory. 175 | 176 | ```shell 177 | ssh-copy-id -i id_rsa.pub [USER]@[YOUR_TARGET_HOST] 178 | ``` 179 | 180 | 4. To confirm the keys have been copied successfully, connect to your target machine by: 181 | 182 | ```shell 183 | ssh [USER]@[YOUR_TARGET_HOST] 184 | ``` 185 | 186 | This should connect to your target machine without asking for a password. 187 | 188 | 5. On your local machine clone this repository. 189 | 190 | 6. Go to the `playbooks` directory. 191 | 192 | ```shell 193 | cd playbooks 194 | ``` 195 | 196 | 7. Create a file `inventory.ini` inside the directory with the following content: 197 | 198 | ```ini 199 | [servers] 200 | YOUR_HOST_ALIAS ansible_host=YOUR_HOSTNAME ansible_ssh_user=YOUR_SSH_USER 201 | YOUR_HOST_ALIAS ansible_host=YOUR_HOSTNAME ansible_ssh_user=YOUR_SSH_USER 202 | ``` 203 | ##### *Note*: you can specify one or more hosts 204 | - Change `YOUR_HOST_ALIAS` to an alias name that you wish to use e.g. `mq-host-1` , you can omit aliases if you prefer 205 | - Change `YOUR_HOSTNAME` to your server/hostname, e.g. `myserver-1.fyre.com` 206 | - Change `YOUR_SSH_USER` to your target machine's SSH user 207 | ##### *Note*: the user on the target machine MUST have `root` or `sudo` privileges 208 | 209 | ### ibmmq.yml 210 | 211 | The sample playbook [`ibmmq.yml`](playbooks/ibmmq.yml) installs IBM MQ Advanced with our roles and configures a queue manager with the `queue_manager.py` module. 212 | 213 | 1. Before running the playbook, ensure that you have added the following directory path to the ANSIBLE_LIBRARY environment variable. 214 | 215 | ##### *Note*: change `` to your local directory path: 216 | 217 | - On Mac: 218 | 219 | ```shell 220 | export ANSIBLE_LIBRARY=${ANSIBLE_LIBRARY}:/mq-ansible/plugins/modules 221 | ``` 222 | 223 | - On Windows: 224 | 225 | ```shell 226 | set ANSIBLE_LIBRARY=%ANSIBLE_LIBRARY%;/mq-ansible/plugins/modules 227 | ``` 228 | 229 | 2. Run the following command to execute the tasks within the playbook: 230 | 231 | ```shell 232 | ansible-playbook ./ibmmq.yml -i inventory.ini -e 'ibmMqLicence=accept' 233 | ``` 234 | 235 | - ##### *Note*: you can optionally add `-K` (uppercase) to the command, this will prompt the user to enter the sudo password for [YOUR_SSH_USER] on the target machine, you can omit if you have setup SSH keys 236 | 237 | 3. The playbook should return the result of `dspmq` with the queue manager created listed. Log into your target machine and check it manually: 238 | 239 | ```shell 240 | dspmq 241 | ``` 242 | 243 | # Troubleshooting 244 | 245 | If one of the following errors appears during the run of the playbook, run the following commands according to the problem: 246 | 247 | - `Please add this host's fingerprint to your known_hosts file to manage this host.` - Indicates that an SSH password cannot be used instead of a key. 248 | 249 | Fix: 250 | ##### *Note*: change `[YOUR_HOST]` to the target machine's network address 251 | 252 | ```shell 253 | ssh-keyscan -H [YOUR_HOST] >> ~/.ssh/known_hosts 254 | ``` 255 | 256 | - `zsh: command not found: dspmq` - Appears that MQ environment variables have not been set. 257 | 258 | Fix: 259 | 260 | ```shell 261 | . /opt/mqm/bin/setmqenv -s 262 | ``` 263 | 264 | - `AMQ7077E: You are not authorized to perform the requested operation` - Appears that the user cannot carry out queue manager operations. This occurs when an SSH session to a target machine hasn't been refreshed after the roles have been executed. 265 | 266 | Fix: 267 | 268 | Restart the SSH session. 269 | 270 | 271 | # Testing Framework 272 | 273 | ### Testing module's functionality with playbooks 274 | 275 | These playbooks test the functionality and performance of our roles and the queue_manager module in Ansible plays. 276 | 277 | To run the test playbooks first: 278 | 279 | 1. Try the installation with our sample playbook. You should run `ibmmq.yml` prior. 280 | 281 | 2. copy your `inventory.ini` file to the `tests/playbooks` directory 282 | 283 | ```shell 284 | cp inventory.ini tests/playbooks 285 | ``` 286 | 287 | 3. go to the `tests/playbooks` directory 288 | 289 | ```shell 290 | cd tests/playbooks 291 | ``` 292 | 293 | 4. export the modules to your Ansible library 294 | 295 | ```shell 296 | export ANSIBLE_LIBRARY=${ANSIBLE_LIBRARY}:/mq-ansible/plugins/modules 297 | ``` 298 | 299 | - ##### *Note*: change `` to your local directory path: 300 | 5. run all test playbooks 301 | 302 | ```shell 303 | ansible-playbook --inventory 'inventory.ini' main_test.yml 304 | ``` 305 | 306 | 6. if any of the tests fail, run: 307 | 308 | ```shell 309 | ansible-playbook --inventory 'inventory.ini' cleanup_test.yml 310 | ``` 311 | 312 | # Ansible Galaxy - Installation 313 | 314 | 1. First, make sure that you have the minimun required version of ansible core with 315 | 316 | ``` 317 | ansible --version 318 | ``` 319 | 320 | 2. Install the latest version from our github repo with 321 | 322 | ``` 323 | ansible-galaxy collection install git+https://github.com/ibm-messaging/mq-ansible.git,main 324 | ``` 325 | 326 | or the latest version in ansible galaxy with: 327 | 328 | ``` 329 | ansible-galaxy collection install ibm_messaging.ibmmq 330 | ``` 331 | 332 | 3. In your desired working directory, make sure to create your ansible inventory `inventory.ini` with the proper target hosts, as you'll refer to them while running the playbook: 333 | 334 | ``` 335 | [mqservers] 336 | my.mqserver-001.dev 337 | my.mqserver-002.dev 338 | ``` 339 | 340 | 4. Create now a playbook file `setup-playbook.yml` with the following content to try our roles and modules: 341 | 342 | ```shell 343 | --- 344 | - name: prepares MQ server 345 | hosts: mqservers 346 | become: true 347 | environment: 348 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 349 | collections: 350 | - ibm_messaging.ibmmq 351 | 352 | tasks: 353 | - name: Import downloadmq role 354 | ansible.builtin.import_role: 355 | name: ibm_messaging.ibmmq.downloadmq 356 | 357 | - name: Import setupusers role 358 | ansible.builtin.import_role: 359 | name: ibm_messaging.ibmmq.setupusers 360 | 361 | - name: Import installmq role 362 | ansible.builtin.import_role: 363 | name: ibm_messaging.ibmmq.installmq 364 | 365 | - name: Import setupenvironment role 366 | ansible.builtin.import_role: 367 | name: ibm_messaging.ibmmq.setupenvironment 368 | 369 | - name: Get MQSC file 370 | become: true 371 | become_user: mqm 372 | ansible.builtin.import_role: 373 | name: ibm_messaging.ibmmq.getconfig 374 | vars: 375 | mqsc_local: ../../../playbooks/files/dev-config.mqsc 376 | 377 | - name: Set up web console 378 | become: true 379 | become_user: mqm 380 | ansible.builtin.import_role: 381 | name: ibm_messaging.ibmmq.setupconsole 382 | 383 | - name: Start web console 384 | become: true 385 | become_user: mqm 386 | ansible.builtin.import_role: 387 | name: ibm_messaging.ibmmq.startconsole 388 | 389 | - name: Create a queue manager 390 | become_user: mqm 391 | tags: ["queue"] 392 | ibm_messaging.ibmmq.queue_manager: 393 | qmname: queue_manager_12 394 | state: present 395 | 396 | - name: Use our MQSC File 397 | become: true 398 | become_user: mqm 399 | ibm_messaging.ibmmq.queue_manager: 400 | qmname: queue_manager_12 401 | state: running 402 | mqsc_file: /var/mqm/dev-config.mqsc 403 | 404 | ``` 405 | 406 | 5. run it with 407 | 408 | ``` 409 | ansible-playbook setup-playbook.yml -i ./inventory.ini -e 'ibmMqLicence=accept' 410 | ``` 411 | 412 | # License 413 | 414 | [Apache 2.0 license](LICENSE) 415 | -------------------------------------------------------------------------------- /blueprints/sdr-rcvr/demo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install IBM MQ and set up a sender-receiver configuration 3 | hosts: all 4 | 5 | - name: Run the install playbook 6 | import_playbook: setup.yml 7 | 8 | - name: Run the sender-receiver playbook 9 | import_playbook: sdr-rcvr.yml -------------------------------------------------------------------------------- /blueprints/sdr-rcvr/receiver-config.mqsc: -------------------------------------------------------------------------------- 1 | * © Copyright IBM Corporation 2017, 2019 2 | * 3 | * 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 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 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 | STOP LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') IGNSTATE(YES) 17 | 18 | * Define and start receiver-side listener 19 | DEFINE LISTENER('RCVR.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) REPLACE 20 | START LISTENER('RCVR.LISTENER.TCP') IGNSTATE(YES) 21 | 22 | * Use a different dead letter queue, for undeliverable messages 23 | DEFINE QLOCAL('DEV.DEAD.LETTER.QUEUE') REPLACE 24 | ALTER QMGR DEADQ('DEV.DEAD.LETTER.QUEUE') 25 | 26 | * Define target queue in receiver: 27 | DEFINE QLOCAL('RCVR.TARGET.Q') REPLACE 28 | 29 | * Define receiver channel 30 | DEFINE CHANNEL(SDR.TO.RCVR) CHLTYPE(RCVR) 31 | 32 | * Turning security off - for demo purposes 33 | ALTER QMGR CHLAUTH(DISABLED) 34 | ALTER QMGR CONNAUTH(' ') 35 | REFRESH SECURITY TYPE(CONNAUTH) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /blueprints/sdr-rcvr/sdr-rcvr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set up the sender-receiver configuration 3 | hosts: all 4 | become: true 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | collections: 8 | - ibm_messaging.ibmmq 9 | 10 | tasks: 11 | - name: Get the IP address of receiver host 12 | ansible.builtin.setup: 13 | when: inventory_hostname == "receiver" 14 | register: receiver_facts 15 | 16 | - name: msg debug 17 | ansible.builtin.debug: 18 | msg: "{{ receiver_facts }}" 19 | 20 | - name: Set the IP of receiver as a fact 21 | ansible.builtin.set_fact: 22 | receiver_ip: "{{ receiver_facts['ansible_facts']['ansible_default_ipv4']['address'] }}" 23 | when: inventory_hostname == "receiver" 24 | delegate_to: localhost 25 | 26 | - name: Get MQSC file for sender 27 | become: true 28 | become_user: mqm 29 | ansible.builtin.import_role: 30 | name: ibm_messaging.ibmmq.getconfig 31 | vars: 32 | mqsc_local: ./sender-config.mqsc 33 | when: inventory_hostname == "sender" 34 | 35 | - name: Get MQSC file for receiver 36 | become: true 37 | become_user: mqm 38 | ansible.builtin.import_role: 39 | name: ibm_messaging.ibmmq.getconfig 40 | vars: 41 | mqsc_local: ./receiver-config.mqsc 42 | when: inventory_hostname == "receiver" 43 | 44 | - name: Add the receiver qmgr's IP 45 | ansible.builtin.replace: 46 | path: /var/mqm/sender-config.mqsc 47 | regexp: "" 48 | replace: "{{ hostvars['receiver']['receiver_ip'] }}" 49 | when: inventory_hostname == "sender" 50 | 51 | - name: Create a queue manager 52 | become_user: mqm 53 | tags: ["queue"] 54 | ibm_messaging.ibmmq.queue_manager: 55 | qmname: SENDER 56 | state: present 57 | when: inventory_hostname == "sender" 58 | 59 | - name: Create a queue manager 60 | become_user: mqm 61 | tags: ["queue"] 62 | ibm_messaging.ibmmq.queue_manager: 63 | qmname: RECEIVER 64 | state: present 65 | when: inventory_hostname == "receiver" 66 | 67 | - name: Use our MQSC File to set up the RECEIVER 68 | become: true 69 | become_user: mqm 70 | ibm_messaging.ibmmq.queue_manager: 71 | qmname: RECEIVER 72 | state: running 73 | mqsc_file: /var/mqm/receiver-config.mqsc 74 | when: inventory_hostname == "receiver" 75 | 76 | - name: Use our MQSC File to set up the SENDER 77 | become: true 78 | become_user: mqm 79 | ibm_messaging.ibmmq.queue_manager: 80 | qmname: SENDER 81 | state: running 82 | mqsc_file: /var/mqm/sender-config.mqsc 83 | when: inventory_hostname == "sender" -------------------------------------------------------------------------------- /blueprints/sdr-rcvr/sender-config.mqsc: -------------------------------------------------------------------------------- 1 | * © Copyright IBM Corporation 2017, 2019 2 | * 3 | * 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 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 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 | STOP LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') IGNSTATE(YES) 17 | 18 | * Define transmit queue (make sure name matches target QM) 19 | DEFINE QLOCAL(RECEIVER) USAGE (XMITQ) 20 | 21 | * Define sender channel 22 | DEFINE CHANNEL(SDR.TO.RCVR) CHLTYPE(SDR) CONNAME('(1414)') XMITQ(RECEIVER) 23 | 24 | * Define remote queue 25 | DEFINE QREMOTE(REMOTE.Q) RNAME(RCVR.TARGET.Q) RQMNAME(RECEIVER) 26 | 27 | * Start channel 28 | START CHANNEL(SDR.TO.RCVR) -------------------------------------------------------------------------------- /blueprints/sdr-rcvr/setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install MQ in servers 3 | hosts: all 4 | become: true 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | collections: 8 | - ibm_messaging.ibmmq 9 | 10 | tasks: 11 | - name: Import downloadmq role 12 | ansible.builtin.import_role: 13 | name: ibm_messaging.ibmmq.downloadmq 14 | 15 | - name: Import setupusers role 16 | ansible.builtin.import_role: 17 | name: ibm_messaging.ibmmq.setupusers 18 | 19 | - name: Import installmq role 20 | ansible.builtin.import_role: 21 | name: ibm_messaging.ibmmq.installmq 22 | 23 | - name: Import setupenvironment role 24 | ansible.builtin.import_role: 25 | name: ibm_messaging.ibmmq.setupenvironment 26 | -------------------------------------------------------------------------------- /docs/MQ_UPGRADE.md: -------------------------------------------------------------------------------- 1 | # `IBM MQ Fix Pack Maintenance` 2 | 3 | Our collection allows you to automate the installation of IBM MQ Fix Packs via the [mq-upgrade.yml](https://github.com/ibm-messaging/mq-ansible/blob/main/playbooks/mq-upgrade.yml) playbook for Linux systems. To ensure Fix Pack applicability and maintenance conventions, refer to documentation on [Maintaining and Migrating IBM MQ](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=migrating-maintaining). 4 | 5 | ## Pre-Requisites 6 | 7 | 1. Verify base installation 8 | 9 | Your target machine/s must have an existing installation of IBM MQ, which can be automated by running our [Sample Playbook](https://github.com/ibm-messaging/mq-ansible#run-our-sample-playbook). Verify the current version by issuing: 10 | 11 | ```shell 12 | dspmqver 13 | ``` 14 | 15 | 2. Acquire Fix Pack 16 | 17 | Acquire the applicable Fix Pack from [IBM Fix Central](https://www.ibm.com/support/fixcentral) by filtering for the current IBM MQ base installation version and platform for the target machine/s. 18 | 19 | 3. End the MQ Web Server 20 | 21 | Check for whether the web server is running by issuing: 22 | 23 | ```shell 24 | dspmqweb 25 | ``` 26 | 27 | If web console is still running, end it by issuing: 28 | 29 | ```shell 30 | endmqweb 31 | ``` 32 | 33 | 4. End all running queue manager objects 34 | 35 | Check for any running queue managers for the current installation by issuing: 36 | 37 | ```shell 38 | dspmq -o installation -o status 39 | ``` 40 | 41 | If any queue managers are still running, end them by issuing: 42 | 43 | ```shell 44 | endmqm QMgrName 45 | ``` 46 | 47 | Check for any listeners associated with a queue manager by issuing: 48 | 49 | ```shell 50 | echo "DISPLAY LSSTATUS(*) STATUS" | runmqsc QmgrName 51 | ``` 52 | 53 | If any listeners are still running, stop end them by issuing: 54 | 55 | ```shell 56 | endmqlsr -m QMgrName 57 | ``` 58 | 5. Set up inventory file 59 | 60 | Enter the location of your playbooks, for example: 61 | 62 | ```shell 63 | cd mq-ansible/ansible_collections/ibm/ibmmq/playbooks 64 | ``` 65 | 66 | Create an `inventory.ini` file containing the hostname/s of your target machine/s: 67 | 68 | ```ini 69 | [upgrades] 70 | YOUR_HOSTNAME 71 | ``` 72 | 73 | ## Roles for Fix Pack installation 74 | 75 | - ``applyfixpack``: Copies a Fix Pack from your local machine to the target machine/s, and carries out installation of the Fix Pack. The path to your local Fix Pack must be specified in the `mq_local_path` variable when calling the role. 76 | 77 | ## Implementing the roles on your playbook 78 | 79 | Example based on our sample playbook `mq-upgrade.yml`, specifying the location of the Fix Pack to be installed on the target machine/s: 80 | 81 | ```yaml 82 | --- 83 | - hosts: "{{ ansible_play_batch }}" 84 | serial: 1 85 | become: true 86 | environment: 87 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 88 | 89 | roles: 90 | - role: applyfixpack 91 | vars: 92 | mq_local_path: YOUR_PATH 93 | ``` 94 | 95 | Where `YOUR_PATH` is the local path to the MQ Fix Pack. Example: `/Users/user1/Downloads/9.3.4-IBM-MQ-UbuntuLinuxX64-FP0001.tar.gz` 96 | 97 | 98 | To run the playbook, issue the following command on your local host: 99 | 100 | ``` 101 | ansible-playbook ./mq-upgrade.yml -i inventory.ini -e 'ibmMqLicence=accept' 102 | ``` 103 | 104 | ## Troubleshooting 105 | 106 | If one of the following errors appears during the run of the playbook, carry out the suggested fixes: 107 | 108 | - `"ERROR: Shared resources for installation at /opt/mqm are in use` - MQ objects haven't correctly been ended before installation of the Fix Packs has started. 109 | 110 | Fix: 111 | 112 | Ensure steps 3 and 4 in the [Pre-Requisites](#pre-requisites) section are completed before re-running the playbook. 113 | 114 | - `"The task includes an option with an undefined variable. The error was: list object has no element 0"` during deb/rpm package installation - the required package files for installation were not present in the Fix Pack you specified to install. 115 | 116 | Fix: 117 | 118 | Ensure that your `mq_local_path` points to the applicable Fix Pack download for the target machine/s. For instance, Ubuntu installations require a specific download containing `UbuntuLinuxX64` in the file name as opposed to just `LinuxX64`. -------------------------------------------------------------------------------- /docs/QUEUE_MANAGER.md: -------------------------------------------------------------------------------- 1 | # `queue_manager.py` 2 | 3 | Module to create, start, delete a queue manager and run MQSC files. 4 | 5 | ## Parameters 6 | 7 | - `qmname` : IBM MQ queue manager name. 8 | - `state` : Desired state of the queue manager (`present`, `absent`, `running`). 9 | - `description` : IBM MQ queue manager description - *optional*. 10 | - `unit_test`: flag used for unit tests of modules. 11 | - `mqsc_file` : Specified MQSC command file to run - *optional*. 12 | 13 | ## Return values 14 | 15 | - `msg` : message of the performed task. 16 | - `rc` : return code. 17 | - `state` 18 | 19 | ## Examples for playbooks 20 | 21 | #### Creating a Queue Manager task 22 | 23 | ``` 24 | - name: Create queue manager 25 | queue_manager: 26 | qmname: 'queue_manager_name' 27 | state: present 28 | ``` 29 | 30 | #### Starting a Queue Manager task 31 | 32 | ``` 33 | - name: Start queue manager 34 | queue_manager: 35 | qmname: 'queue_manager_name' 36 | state: running 37 | ``` 38 | 39 | #### Deleting a Queue Manager task 40 | 41 | ``` 42 | - name: Start queue manager 43 | queue_manager: 44 | qmname: 'queue_manager_name' 45 | state: absent 46 | ``` 47 | 48 | #### Run MQSC command file task 49 | 50 | ``` 51 | - name: Run MQSC command file 52 | queue_manager: 53 | qmname: 'queue_manager_name' 54 | state: running 55 | mqsc_file: 'commfile.in' 56 | ``` 57 | 58 | #### Use of ALL_QMGRS value 59 | 60 | This may be used to refer to all queue managers currently defined to a system, e.g to start/stop both QM1 and QM2 defined in mq-setup.yml. 61 | 62 | ``` 63 | - name: Run MQSC command file 64 | queue_manager: 65 | qmname: 'ALL_QMGRS' 66 | state: running 67 | ``` 68 | 69 | ## Example of unit testing of a module 70 | 71 | Note: Exeption classes `AnsibleExitJson` and `AnsibleFailJson` should be set. See [`test_queue_manager.py`](ansible_collections/ibm/ibmmq/tests/unit/test_queue_manager.py) for reference. 72 | 73 | ``` 74 | def test_delete_qm(self): 75 | set_module_args({ 76 | 'qmname': 'qm1', 77 | 'state': 'absent', 78 | 'description': 'testing', 79 | 'unit_test': True 80 | }) 81 | with self.assertRaises(AnsibleExitJson) as result: 82 | queue_manager.main() 83 | self.assertEquals(result.exception.args[0]['state'], 'absent') 84 | ``` 85 | -------------------------------------------------------------------------------- /docs/WINSTALL.md: -------------------------------------------------------------------------------- 1 | # `IBM MQ installation roles for Windows platforms` 2 | 3 | Our collection now also allows you to automate the download and install of IBM MQ on Windows. Different to Unix-based platforms, _Ansible_ connects to Windows hosts using Windows remote management (WinRM). Thus, as requirement, your target machine must be set up to allow the remote connection. 4 | 5 | ## Pre-requesites 6 | 7 | 1. Set up your target machine 8 | 9 | Your target host must: 10 | 11 | - Be running either desktop Windows OS 8.1 or later, or server OSs such as Windows Server 2012 or newer. 12 | - Have PowerShell 3.0 or newer and at least .NET 4.0 13 | - Have WinRM configured to have a listener created and activated. 14 | 15 | For more information on how to set up your Windows host, please refer to [Ansible documentation](https://docs.ansible.com/ansible/latest/os_guide/windows_setup.html#winrm-listener). You can also run a [_Configure Remoting for Ansible_](https://raw.githubusercontent.com/ansible/ansible-documentation/devel/examples/scripts/ConfigureRemotingForAnsible.ps1) script to set up your Windows machine and turn on WinRM. For more details of the script, refer to the official Ansible blog [here](https://www.ansible.com/blog/connecting-to-a-windows-host). 16 | 17 | 2. Set up your local machine 18 | 19 | Your local machine, where Ansible Engine will be executing the playbooks, must run Linux. You must also ensure that your local machine has ```pywinrm``` dependencies installed to use WinRM. You can do this by running ``` pip install pywinrm ```. 20 | 21 | 3. Set up Inventory file 22 | 23 | Your inventory file should be located within the ibmmq directory: 24 | 25 | ```shell 26 | cd mq-ansible/ansible_collections/ibm/ibmmq/ 27 | ``` 28 | 29 | **Option 1: Plaintext variables in inventory file** 30 | 31 | To indicate the Ansible Engine to use a WinRM connection, you must configure your ```ansible_connection``` host variable to ```winrm```. If you have set up your target machine with self-sigend certificates, you will also need to configure your host var to ignore certificate validtion. An example inventory file: 32 | 33 | ```ini 34 | [windows] 35 | YOUR_HOSTNAME 36 | 37 | [windows:vars] 38 | ansible_user=Administrator 39 | ansible_password=YOUR_PASSWORD 40 | ansible_connection=winrm 41 | ansible_winrm_server_cert_validation=ignore 42 | ``` 43 | 44 | *Note*: As installs modify Windows' registry, the install can only be performed by the Administrator user. 45 | 46 | - Change `YOUR_HOSTNAME` to your server/hostname, e.g. `myserver-windows.fyre.com` 47 | - Change `YOUR_PASSWORD` to your target machine *Administrator*'s password. 48 | 49 | **Option 2:** Encrypted variables for host in inventory file 50 | 51 | To avoid storing plaintext passwords, we recommend using `ansible-vault` to store the Windows host variables. Your `inventory.ini` file would only consist on: 52 | 53 | ```ini 54 | [windows] 55 | YOUR_HOSTNAME 56 | ``` 57 | 58 | Now you can encrypt the windows variables with `ansible-vault`. In your terminal, execute the following commands: 59 | 60 | ```shell 61 | ansible-vault create groups_vars/windows.yml 62 | ``` 63 | 64 | This command will prompt you to create a new vault password to decrypt the variables if you haven't set one previously. 65 | 66 | ```shell 67 | New Vault password: 68 | Confirm New Vault password: 69 | ``` 70 | 71 | It will then launch your system editor where you can paste the windows host variables below: 72 | 73 | ``` 74 | ansible_user: Administrator 75 | ansible_password: "YOUR_PASSWORD" 76 | ansible_connection: winrm 77 | ansible_winrm_server_cert_validation: ignore 78 | ``` 79 | - Change `"YOUR_PASSWORD"` to your target machine *Administrator*'s password in quotes. Example: _"ansiblepassword"_ 80 | 81 | After you close your editor, the file will be saved with the encrypted content. The variables will be automatically applied for the the Windows host group when targeted on a playbook. 82 | 83 | More information about ansible-vault and content encryption can be found [here](https://docs.ansible.com/ansible/latest/vault_guide/vault_encrypting_content.html#encrypting-individual-variables-with-ansible-vault). 84 | 85 | 86 | ## Roles for Windows installation 87 | 88 | - ``downloadmq``: For Windows, downloads the IBM MQ Advanced developer package to an specified directory. Default directory in our sample playbook is `C:\Users\Administrator`. You can also specify a local source to copy to the target directory with the variable `local_source` 89 | - ``installmq``: Installs the package. 90 | - ``setupconsole``: Sets up the web console. 91 | - ``startconsole``: Starts the web console. 92 | 93 | ## Implementing the roles on your playbook 94 | 95 | Example based in our sample playbook `mq-winstall.yml`, specifying the directory, version and download URL: 96 | 97 | ```yaml 98 | - hosts: windows 99 | 100 | roles: 101 | - role: downloadmq 102 | vars: 103 | directory: C:\Users\Administrator 104 | version: 930 105 | downloadURL: "https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/" 106 | - installmq 107 | - setupconsole 108 | - startconsole 109 | 110 | ``` 111 | To specify a local source, set the `local_source` and `mq_local_path` for the `downloadmq` role as follows: 112 | 113 | ```yaml 114 | - role: downloadmq 115 | vars: 116 | local_source: true 117 | mq_local_path: YOUR_PATH 118 | ``` 119 | Where `YOUR_PATH` is the local path to the MQ source package. Example: `/Users/user1/Downloads/mqadv_dev932_windows.zip` 120 | 121 | To run the playbook, issue the following command on your local host: 122 | 123 | ``` 124 | ansible-playbook ./mq-winstall.yml -i inventory.ini -e 'ibmMqLicence=yes' 125 | ``` 126 | 127 | ## Troubleshooting 128 | 129 | If one of the following errors appears during the run of the playbook, run the following commands according to the problem: 130 | 131 | - `ERROR! A worker was found in a dead state` - macOs High Sierra and later versions may get this issue when implementing multithreading scripts. 132 | 133 | Fix: 134 | ```shell 135 | export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES 136 | ``` -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | ### REQUIRED 2 | # The namespace of the collection. This can be a company/brand/organization or product namespace under which all 3 | # content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with 4 | # underscores or numbers and cannot contain consecutive underscores 5 | namespace: ibm_messaging 6 | 7 | # The name of the collection. Has the same character restrictions as 'namespace' 8 | name: ibmmq 9 | 10 | # The version of the collection. Must be compatible with semantic versioning 11 | version: 1.0.4 12 | 13 | # The path to the Markdown (.md) readme file. This path is relative to the root of the collection 14 | readme: README-GALAXY.md 15 | 16 | # A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) 17 | # @nicks:irc/im.site#channel' 18 | authors: 19 | - James Page 20 | - Stewart Mclaughlin 21 | - Mariana Villar Pacheco 22 | - Bimsara Pilapitiya 23 | - Mohammad Alatoum 24 | 25 | 26 | ### OPTIONAL but strongly recommended 27 | # A short summary description of the collection 28 | description: A collection for automating the installation and configuration of IBM MQ using Ansible on Ubuntu, Redhat, Windows and IBM AIX machines. Our aim is to make MQ-Ansible extensible for other platforms and more detailed IBM MQ configuration. 29 | 30 | # Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only 31 | # accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' 32 | # license: 33 | # - Apache-2.0 34 | 35 | # The path to the license file for the collection. This path is relative to the root of the collection. This key is 36 | # mutually exclusive with 'license' 37 | license_file: 'LICENSE' 38 | 39 | # A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character 40 | # requirements as 'namespace' and 'name' 41 | tags: 42 | - ibm 43 | - ibmmq 44 | - mq 45 | - queue 46 | - linux 47 | - aix 48 | - windows 49 | 50 | # Collections that this collection requires to be installed for it to be usable. The key of the dict is the 51 | # collection label 'namespace.name'. The value is a version range 52 | # L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version 53 | # range specifiers can be set and are separated by ',' 54 | dependencies: {} 55 | 56 | # The URL of the originating SCM repository 57 | repository: https://github.com/ibm-messaging/mq-ansible 58 | 59 | # The URL to any online docs 60 | documentation: https://github.com/ibm-messaging/mq-ansible/blob/main/README.md 61 | 62 | # The URL to the homepage of the collection/project 63 | homepage: https://github.com/ibm-messaging/mq-ansible 64 | 65 | # The URL to the collection issue tracker 66 | issues: https://github.com/ibm-messaging/mq-ansible/issues 67 | 68 | # A list of file glob-like patterns used to filter any files or directories that should not be included in the build 69 | # artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This 70 | # uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', 71 | # and '.git' are always filtered. Mutually exclusive with 'manifest' 72 | build_ignore: 73 | - ansible.cfg 74 | - .gitignore 75 | - .github 76 | - .git 77 | - .cache 78 | - '*.tar.gz' 79 | - docs 80 | - collections 81 | - venv 82 | - .idea 83 | - meta/context 84 | 85 | # A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a 86 | # list of MANIFEST.in style 87 | # L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key 88 | # 'omit_default_directives' is a boolean that controls whether the default directives are used. Mutually exclusive 89 | # with 'build_ignore' 90 | # manifest: null 91 | 92 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Collections must specify a minimum required ansible version to upload 3 | # to galaxy 4 | requires_ansible: '>=2.9.10' 5 | 6 | # Content that Ansible needs to load from another location or that has 7 | # been deprecated/removed 8 | # plugin_routing: 9 | # action: 10 | # redirected_plugin_name: 11 | # redirect: ns.col.new_location 12 | # deprecated_plugin_name: 13 | # deprecation: 14 | # removal_version: "4.0.0" 15 | # warning_text: | 16 | # See the porting guide on how to update your playbook to 17 | # use ns.col.another_plugin instead. 18 | # removed_plugin_name: 19 | # tombstone: 20 | # removal_version: "2.0.0" 21 | # warning_text: | 22 | # See the porting guide on how to update your playbook to 23 | # use ns.col.another_plugin instead. 24 | # become: 25 | # cache: 26 | # callback: 27 | # cliconf: 28 | # connection: 29 | # doc_fragments: 30 | # filter: 31 | # httpapi: 32 | # inventory: 33 | # lookup: 34 | # module_utils: 35 | # modules: 36 | # netconf: 37 | # shell: 38 | # strategy: 39 | # terminal: 40 | # test: 41 | # vars: 42 | 43 | # Python import statements that Ansible needs to load from another location 44 | # import_redirection: 45 | # ansible_collections.ns.col.plugins.module_utils.old_location: 46 | # redirect: ansible_collections.ns.col.plugins.module_utils.new_location 47 | 48 | # Groups of actions/modules that take a common set of options 49 | # action_groups: 50 | # group_name: 51 | # - module1 52 | # - module2 53 | -------------------------------------------------------------------------------- /playbooks/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | roles_path = ../roles -------------------------------------------------------------------------------- /playbooks/files/dev-config.mqsc: -------------------------------------------------------------------------------- 1 | * © Copyright IBM Corporation 2017, 2019 2 | * 3 | * 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 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 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 | STOP LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') IGNSTATE(YES) 17 | 18 | * Developer queues 19 | DEFINE QLOCAL('DEV.QUEUE.1') REPLACE 20 | DEFINE QLOCAL('DEV.QUEUE.2') REPLACE 21 | DEFINE QLOCAL('DEV.QUEUE.3') REPLACE 22 | DEFINE QLOCAL('DEV.DEAD.LETTER.QUEUE') REPLACE 23 | 24 | * Use a different dead letter queue, for undeliverable messages 25 | ALTER QMGR DEADQ('DEV.DEAD.LETTER.QUEUE') 26 | 27 | * Developer topics 28 | DEFINE TOPIC('DEV.BASE.TOPIC') TOPICSTR('dev/') REPLACE 29 | 30 | * Developer connection authentication 31 | DEFINE AUTHINFO('DEV.AUTHINFO') AUTHTYPE(IDPWOS) CHCKCLNT(REQDADM) CHCKLOCL(OPTIONAL) ADOPTCTX(YES) REPLACE 32 | ALTER QMGR CONNAUTH('DEV.AUTHINFO') 33 | REFRESH SECURITY(*) TYPE(CONNAUTH) 34 | 35 | * Developer channels (Application + Admin) 36 | * Developer channels (Application + Admin) 37 | DEFINE CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) REPLACE 38 | DEFINE CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) MCAUSER('app') REPLACE 39 | 40 | * Developer channel authentication rules 41 | SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('Back-stop rule - Blocks everyone') ACTION(REPLACE) 42 | SET CHLAUTH('DEV.APP.SVRCONN') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED) DESCR('Allows connection via APP channel') ACTION(REPLACE) 43 | SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(BLOCKUSER) USERLIST('nobody') DESCR('Allows admins on ADMIN channel') ACTION(REPLACE) 44 | SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(USERMAP) CLNTUSER('admin') USERSRC(CHANNEL) DESCR('Allows admin user to connect via ADMIN channel') ACTION(REPLACE) 45 | SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(USERMAP) CLNTUSER('admin') USERSRC(MAP) MCAUSER ('mqm') DESCR ('Allow admin as MQ-admin') ACTION(REPLACE) 46 | 47 | * Developer authority records 48 | SET AUTHREC PRINCIPAL('app') OBJTYPE(QMGR) AUTHADD(CONNECT,INQ) 49 | SET AUTHREC PROFILE('DEV.**') PRINCIPAL('app') OBJTYPE(QUEUE) AUTHADD(BROWSE,GET,INQ,PUT) 50 | SET AUTHREC PROFILE('DEV.**') PRINCIPAL('app') OBJTYPE(TOPIC) AUTHADD(PUB,SUB) 51 | 52 | * Developer listener 53 | DEFINE LISTENER('DEV.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) REPLACE 54 | START LISTENER('DEV.LISTENER.TCP') IGNSTATE(YES) 55 | STOP LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') IGNSTATE(YES) -------------------------------------------------------------------------------- /playbooks/ibmmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install and setup IBM MQ 3 | hosts: ['servers'] 4 | 5 | - name: Run the install playbook 6 | import_playbook: mq-install.yml 7 | 8 | - name: Run the setup playbook 9 | import_playbook: mq-setup.yml 10 | -------------------------------------------------------------------------------- /playbooks/mq-install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: "{{ ansible_play_batch }}" 3 | serial: 1 4 | become: true 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | 8 | roles: 9 | - role: setupusers 10 | vars: 11 | app_uid: 909 12 | gid: 909 13 | app_gid: 909 14 | mqm_home: /home/mqm 15 | mqm_profile: .profile 16 | - role: downloadmq 17 | vars: 18 | version: 940 19 | downloadURL: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/ 20 | - role: installmq 21 | - role: setupenvironment 22 | -------------------------------------------------------------------------------- /playbooks/mq-setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: "{{ ansible_play_hosts }}" 3 | serial: 1 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | roles: 10 | - role: getconfig 11 | vars: 12 | mqsc_local: ../../../playbooks/files/dev-config.mqsc 13 | - setupconsole 14 | - startconsole 15 | 16 | tasks: 17 | - name: Create a queue manager 18 | queue_manager: 19 | qmname: 20 | - QM1 21 | - QM2 22 | state: present 23 | 24 | - name: Start a queue manager 25 | queue_manager: 26 | qmname: 27 | - QM1 28 | - QM2 29 | state: running 30 | 31 | - name: Run MQSC File 32 | queue_manager: 33 | qmname: 34 | - QM1 35 | - QM2 36 | state: running 37 | mqsc_file: /var/mqm/dev-config.mqsc 38 | -------------------------------------------------------------------------------- /playbooks/mq-upgrade.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: "{{ ansible_play_batch }}" 3 | serial: 1 4 | become: true 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | 8 | roles: 9 | - role: applyfixpack 10 | vars: 11 | mq_local_path: ~/tmp/ -------------------------------------------------------------------------------- /playbooks/mq-winstall.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: windows 3 | 4 | roles: 5 | - downloadmq 6 | - installmq 7 | - setupconsole 8 | - startconsole 9 | -------------------------------------------------------------------------------- /playbooks/sample-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: prepares MQ server 3 | hosts: mqservers 4 | become: true 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | collections: 8 | - ibm_messaging.ibmmq 9 | 10 | tasks: 11 | - name: Import downloadmq role 12 | ansible.builtin.import_role: 13 | name: ibm_messaging.ibmmq.downloadmq 14 | 15 | - name: Import setupusers role 16 | ansible.builtin.import_role: 17 | name: ibm_messaging.ibmmq.setupusers 18 | 19 | - name: Import installmq role 20 | ansible.builtin.import_role: 21 | name: ibm_messaging.ibmmq.installmq 22 | 23 | - name: Import setupenvironment role 24 | ansible.builtin.import_role: 25 | name: ibm_messaging.ibmmq.setupenvironment 26 | 27 | - name: Get MQSC file 28 | become: true 29 | become_user: mqm 30 | ansible.builtin.import_role: 31 | name: ibm_messaging.ibmmq.getconfig 32 | vars: 33 | mqsc_local: ../../../playbooks/files/dev-config.mqsc 34 | 35 | - name: Set up web console 36 | become: true 37 | become_user: mqm 38 | ansible.builtin.import_role: 39 | name: ibm_messaging.ibmmq.setupconsole 40 | 41 | - name: Start web console 42 | become: true 43 | become_user: mqm 44 | ansible.builtin.import_role: 45 | name: ibm_messaging.ibmmq.startconsole 46 | 47 | - name: Create a queue manager 48 | become_user: mqm 49 | tags: ["queue"] 50 | ibm_messaging.ibmmq.queue_manager: 51 | qmname: queue_manager_12 52 | state: present 53 | 54 | - name: Use our MQSC File 55 | become: true 56 | become_user: mqm 57 | ibm_messaging.ibmmq.queue_manager: 58 | qmname: queue_manager_12 59 | state: running 60 | mqsc_file: /var/mqm/dev-config.mqsc -------------------------------------------------------------------------------- /plugins/modules/queue_manager.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 IBM Corp. 3 | # 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 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 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 | from ansible.module_utils.basic import AnsibleModule 18 | import os.path 19 | import re 20 | 21 | result = dict( 22 | rc=0, 23 | msg='', 24 | state='', 25 | output='' 26 | ) 27 | 28 | def check_status_queue_managers(qmname, module): 29 | rc, stdout, stderr = module.run_command(['dspmq', '-m', qmname]) 30 | 31 | if stdout is not None: 32 | if 'Running' in stdout: 33 | return True 34 | 35 | return False 36 | 37 | 38 | 39 | def state_present(qmname, module): 40 | if module.params['unit_test'] is False: 41 | rc, stdout, stderr = module.run_command(['crtmqm', qmname]) 42 | result['rc'] = rc 43 | 44 | if module.params['mqsc_file'] is not None: 45 | result['rc'], result['msg'], result['output'] = run_mqsc_file(qmname, module) 46 | 47 | if rc == 0: 48 | result['rc'] = rc 49 | result['msg'] = 'IBM MQ Queue Manager Created' 50 | result['state'] = 'present' 51 | elif rc == 8: 52 | result['rc'] = 0 53 | result['msg'] = 'IBM MQ Queue Manager already exists. ' + result['msg'] 54 | result['state'] = 'present' 55 | elif rc > 0: 56 | # Critical Error 57 | module.fail_json(**result) 58 | 59 | def run_mqsc_file(qmname, module): 60 | is_running = check_status_queue_managers(qmname, module) 61 | exists = os.path.isfile(module.params['mqsc_file']) 62 | 63 | if exists is True: 64 | if is_running: 65 | rc, stdout, stderr = module.run_command(["runmqsc", qmname, "-f", module.params['mqsc_file']]) 66 | result['rc'] = rc 67 | result['output'] = stdout + stderr 68 | if rc == 0: 69 | result['state'] = 'running' 70 | result['msg'] = 'MQSC configuration successfully applied to queue manager.' 71 | 72 | else: 73 | rc, stdout, stderr = module.run_command(['strmqm', qmname]) 74 | rc, stdout, stderr = module.run_command(["runmqsc", qmname, "-f", module.params['mqsc_file']]) 75 | result['rc'] = rc 76 | result['output'] = stdout + stderr 77 | rc, stdout, stderr = module.run_command(['endmqm', qmname]) 78 | if rc == 0: 79 | result['msg'] = 'MQSC configuration successfully applied to queue manager.' 80 | else: 81 | if is_running: 82 | result['state'] = 'running' 83 | result['rc'] = 16 84 | result['msg'] = 'MQSC file could not be found' 85 | return (result['rc'], result['msg'], result['output']) 86 | 87 | 88 | def state_running(qmname, module): 89 | result['msg'] = 'IBM MQ queue manager \'' + str(qmname) + '\' started.' 90 | result['state'] = 'running' 91 | if module.params['unit_test'] is False: 92 | rc, stdout, stderr = module.run_command(['dspmq', '-m', qmname]) 93 | 94 | if rc == 72: 95 | # QMGR does not exist Create then set running 96 | rc, stdout, stderr = module.run_command(['crtmqm', qmname]) 97 | if rc > 0: 98 | # Critical Error 99 | module.fail_json(**result) 100 | 101 | rc, stdout, stderr = module.run_command(['strmqm', qmname]) 102 | result['rc'] = rc 103 | result['msg'] = stdout + stderr 104 | 105 | 106 | if rc == 5 and module.params['mqsc_file'] is None: 107 | result['rc'] = 0 108 | result['msg'] = 'IBM MQ queue manager running' 109 | result['state'] = 'running' 110 | elif rc == 5 and module.params['mqsc_file']: 111 | run_mqsc_file(qmname, module) 112 | elif rc == 0: 113 | 114 | result['state'] = 'running' 115 | result['msg'] = 'IBM MQ queue manager \'' + str(qmname) + '\' running.' 116 | 117 | if module.params['mqsc_file']: 118 | run_mqsc_file(qmname, module) 119 | 120 | else: 121 | # Critical Error 122 | module.fail_json(**result) 123 | 124 | def state_stopped(qmname, module): 125 | if module.params['unit_test'] is False: 126 | 127 | if module.params['mqsc_file'] is not None: 128 | result['rc'], result['msg'], result['output'] = run_mqsc_file(qmname, module) 129 | 130 | rc, stdout, stderr = module.run_command(['endmqm', qmname]) 131 | result['msg'] = stdout + stderr 132 | 133 | if rc == 16: 134 | result['state'] = 'absent' 135 | module.fail_json(**result) 136 | elif rc == 40: 137 | result['rc'] = 0 138 | result['msg'] = stdout + stderr 139 | result['state'] = 'present' 140 | elif rc == 0: 141 | result['rc'] = rc 142 | result['state'] = 'stopped' 143 | elif rc > 0: 144 | # Critical Error 145 | module.fail_json(**result) 146 | else: 147 | result['rc'] = rc 148 | result['state'] = 'present' 149 | 150 | def state_absent(qmname, module): 151 | # result['msg'] = 'IBM MQ queue manager deleted.' 152 | 153 | if module.params['unit_test'] is False: 154 | 155 | rc, stdout, stderr = module.run_command(['dltmqm', qmname]) 156 | result['msg'] = stdout 157 | result['rc'] = rc 158 | result['state'] = 'absent' 159 | 160 | if rc == 0: 161 | result['msg'] = 'IBM MQ queue manager \'' + str(qmname) + '\' deleted.' 162 | elif rc == 5: 163 | result['rc'] = 0 164 | result['msg'] = 'IBM MQ queue manager running.' 165 | result['state'] = 'running' 166 | elif rc == 16: 167 | # Queue Manager does not exist 168 | result['rc'] = 0 169 | result['msg'] = 'AMQ8118E: IBM MQ queue manager does not exist.' 170 | result['state'] = 'absent' 171 | else: 172 | # Critical Error 173 | module.fail_json(**result) 174 | 175 | def state_invalid(qmname, module): 176 | result['state'] = '' 177 | result['msg'] = 'Unrecognised State' 178 | result['rc'] = 16 179 | module.fail_json(**result) 180 | 181 | 182 | def main(): 183 | qmgr_attributes = dict( 184 | qmname=dict(type='list', required=True, max_len=48), 185 | state=dict(type='str', required=True), 186 | description=dict(type='str', required=False), 187 | unit_test=dict(type='bool', default=False, required=False), 188 | mqsc_file=dict(type='str', required=False) 189 | ) 190 | 191 | module = AnsibleModule( 192 | argument_spec=qmgr_attributes 193 | ) 194 | 195 | if module.params['qmname'][0] == "ALL_QMGRS": 196 | module.params['qmname'] = re.findall("(?<=QMNAME\()([^\)]*)", module.run_command(['dspmq'])[1]) 197 | result['qmlists'] = re.findall("(?<=QMNAME\()([^\)]*)", module.run_command(['dspmq'])[1]) 198 | 199 | ops = { 200 | "present": state_present, 201 | "running": state_running, 202 | "stopped": state_stopped, 203 | "absent": state_absent 204 | } 205 | 206 | if module.params['unit_test'] is False: 207 | for qmname in module.params['qmname']: 208 | ops.get(module.params['state'], state_invalid)(qmname, module) 209 | 210 | module.exit_json(**result) 211 | 212 | if __name__ == '__main__': 213 | main() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ansible 2 | ansible-lint 3 | passlib -------------------------------------------------------------------------------- /roles/applyfixpack/README.md: -------------------------------------------------------------------------------- 1 | # ApplyFixPack 2 | Downloads and installs a fix pack onto the target machine. 3 | ### Parameters 4 | 5 | | Name | Description | Example | 6 | | --- | --- | --- | 7 | | mq_local_path | Host machine local path to an applicable fix pack `tar` or `zip` | `~/tmp/9.3.4-IBM-MQ-UbuntuLinuxX64-FP0001.tar.gz` | 8 | -------------------------------------------------------------------------------- /roles/applyfixpack/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | mq_local_path: ~/tmp/ -------------------------------------------------------------------------------- /roles/applyfixpack/tasks/Linux_applyfixpack.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Store fixpack name 3 | ansible.builtin.set_fact: 4 | fixpack_tar: '{{ mq_local_path | basename }}' 5 | 6 | - name: Store fixpack directory 7 | ansible.builtin.set_fact: 8 | fixpack_dir: '{{ fixpack_tar | replace(".tar.gz","") }}' 9 | 10 | - name: Copy fixpack to target 11 | ansible.builtin.copy: 12 | src: '{{ mq_local_path }}' 13 | dest: '/var' 14 | mode: "0644" 15 | 16 | - name: Create fixpack directory 17 | ansible.builtin.file: 18 | path: '/var/{{ fixpack_dir }}' 19 | state: directory 20 | 21 | - name: Extract fixpack fom zip 22 | ansible.builtin.unarchive: 23 | src: '/var/{{ fixpack_tar }}' 24 | remote_src: true 25 | dest: '/var/{{ fixpack_dir }}' 26 | 27 | - name: Check if MQ license has been accepted 28 | ansible.builtin.stat: 29 | path: '/var/MQServer/licensestatus.txt' 30 | register: license_status 31 | 32 | - name: Accept MQ license if not already done 33 | ansible.builtin.shell: >- 34 | /var/MQServer/mqlicense.sh 35 | -{{ ibmMqLicence }} > 36 | /var/MQServer/licensestatus.txt 37 | changed_when: not license_status.stat.exists 38 | 39 | - name: Gather package facts 40 | ansible.builtin.package_facts: 41 | manager: auto 42 | 43 | - name: End web server 44 | become_user: mqm 45 | ansible.builtin.command: endmqweb 46 | register: mqweb_status 47 | failed_when: mqweb_status.stderr != "" 48 | 49 | - name: Find required package files 50 | ansible.builtin.find: 51 | paths: '/var/{{ fixpack_dir }}' 52 | use_regex: true 53 | patterns: '{{ item }}' 54 | register: package_files 55 | with_items: 56 | - (?i).*runtime.* 57 | - (?i).*gskit.* 58 | - (?i).*server.* 59 | - (?i).*java.* 60 | - (?i).*jre.* 61 | - (?i).*sdk.* 62 | - (?i).*samples.* 63 | - (?i).*man.* 64 | - (?i).*client.* 65 | - (?i).*amqp.* 66 | - (?i).*ams.* 67 | - (?i).*web.* 68 | - (?i).*(-|_)es.* 69 | - (?i).*(-|_)cn.* 70 | # - '(?i).*ftbase.*' 71 | # - '(?i).*ftlogger.*' 72 | # - '(?i).*fttools.*' 73 | # - '(?i).*ftagent.*' 74 | # - '(?i).*ftservice.*' 75 | # - '(?i).*xrservice.*' 76 | # - '(?i).*sfbridge.*' 77 | # - '(?i).*bcbridge.*' 78 | # - '(?i).*(-|_)de.*' 79 | # - '(?i).*(-|_)fr.*' 80 | # - '(?i).*(-|_)ja.*' 81 | # - '(?i).*(-|_)it.*' 82 | # - '(?i).*(-|_)ko.*' 83 | # - '(?i).*(-|_)ru.*' 84 | # - '(?i).*(-|_)pt.*' 85 | # - '(?i).*(-|_)hu.*' 86 | # - '(?i).*(-|_)pl.*' 87 | # - '(?i).*(-|_)cs.*' 88 | # - '(?i).*(-|_)tw.*' 89 | when: '"MQSeriesRuntime" in ansible_facts.packages or "ibmmq-runtime" in ansible_facts.packages' 90 | 91 | - name: Create a list of paths to the packages from found files 92 | ansible.builtin.set_fact: 93 | package_list: "{{ package_files.results | map(attribute='files.0.path') | list }}" 94 | when: '"MQSeriesRuntime" in ansible_facts.packages or "ibmmq-runtime" in ansible_facts.packages' 95 | 96 | - name: Deb Installation 97 | ansible.builtin.apt: 98 | deb: '{{ item }}' 99 | state: present 100 | when: 101 | - ansible_distribution == 'Ubuntu' 102 | - "'ibmmq-runtime' in ansible_facts.packages" 103 | loop: '{{ package_list }}' 104 | 105 | - name: RPM Installation 106 | ansible.builtin.dnf: 107 | name: "{{ package_list }}" 108 | state: present 109 | disable_gpg_check: true 110 | when: 111 | - ansible_distribution == 'RedHat' 112 | - "'MQSeriesRuntime' in ansible_facts.packages" 113 | 114 | - name: Reset ssh connection 115 | ansible.builtin.meta: reset_connection -------------------------------------------------------------------------------- /roles/applyfixpack/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the task list for this platform 3 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" -------------------------------------------------------------------------------- /roles/downloadmq/README.md: -------------------------------------------------------------------------------- 1 | # DownloadMQ 2 | Retrieves and unpackages the specified MQ installation. 3 | 4 | ### Parameters 5 | 6 | | Name | Description | Example | 7 | | --- | --- | --- | 8 | | version | Non-separated MQ version number to be installed | `942` | 9 | | downloadURL| Download location for MQ installation | `https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/` | 10 | | local_source | Bool to specify if you want a local source (from Ansible machine) to be installed in your target machines | 11 | | mq_local_path | Path where MQ source package is located locally | 12 | 13 | ### Installing from local source 14 | 15 | To specify a local source, set the `local_source` and `mq_local_path` for the `downloadmq` role as follows: 16 | 17 | ```yaml 18 | - role: downloadmq 19 | vars: 20 | local_source: true 21 | mq_local_path: YOUR_PATH 22 | ``` 23 | Where `YOUR_PATH` is the local path to the MQ source package. Example: `/Users/user1/Downloads/mqadv_dev932_ubuntu_x86-64.tar.gz` -------------------------------------------------------------------------------- /roles/downloadmq/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 942 3 | local_source: false 4 | mq_local_path: ~/tmp/ -------------------------------------------------------------------------------- /roles/downloadmq/tasks/AIX_ppc64le_downloadmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Download MQ Advanced for Developers 3 | ansible.builtin.copy: 4 | src: "{{ mq_local_path: }}" 5 | dest: ~/tmp/ 6 | mode: "0644" 7 | when: local_source 8 | -------------------------------------------------------------------------------- /roles/downloadmq/tasks/Linux_s390x_downloadmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy MQ Trial from Control to Z Worker 3 | ansible.builtin.copy: 4 | src: "{{ mq_local_path }}" 5 | dest: /var/mq.tar.gz 6 | mode: "0644" 7 | when: local_source 8 | 9 | - name: Extract MQ fom TAR 10 | ansible.builtin.unarchive: 11 | src: /var/mq.tar.gz 12 | remote_src: true 13 | dest: /var 14 | tags: download 15 | when: local_source 16 | -------------------------------------------------------------------------------- /roles/downloadmq/tasks/Linux_x86_64_downloadmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Set zip filename for releases with old naming convention 4 | - name: Set filename of zip if target host is Ubuntu (old naming convention) 5 | ansible.builtin.set_fact: 6 | zip_file: mqadv_dev{{ version }}_ubuntu_x86-64.tar.gz 7 | when: ansible_distribution == 'Ubuntu' and not local_source and convention=='old' 8 | 9 | - name: Set filename of zip if target host is RedHat (old naming convention) 10 | ansible.builtin.set_fact: 11 | zip_file: mqadv_dev{{ version }}_linux_x86-64.tar.gz 12 | when: ansible_distribution == 'RedHat' and not local_source and convention=='old' 13 | 14 | # Set zip filename for releases with new naming convention (>9.3) 15 | - name: Set filename of zip if target host is Ubuntu (new naming convention) 16 | ansible.builtin.set_fact: 17 | zip_file: '{{ vrmf }}-IBM-MQ-Advanced-for-Developers-UbuntuLinuxX64.tar.gz' 18 | when: ansible_distribution == 'Ubuntu' and not local_source and convention=='new' 19 | 20 | - name: Set filename of zip if target host is RedHat (new naming convention) 21 | ansible.builtin.set_fact: 22 | zip_file: '{{ vrmf }}-IBM-MQ-Advanced-for-Developers-LinuxX64.tar.gz ' 23 | when: ansible_distribution == 'RedHat' and not local_source and convention=='new' 24 | 25 | # Get the file if local source is false 26 | - name: Download MQ Advanced for Developers 27 | ansible.builtin.get_url: 28 | url: "{{ downloadURL }}{{ zip_file }}" 29 | dest: /var/mq.tar.gz 30 | force: false 31 | mode: "0644" 32 | tags: download 33 | when: not local_source 34 | 35 | # Copy source to target if local source is true 36 | - name: Copy local MQ source to target 37 | ansible.builtin.copy: 38 | src: "{{ mq_local_path }}" 39 | dest: /var/mq.tar.gz 40 | tags: download 41 | when: local_source 42 | 43 | - name: Extract MQ fom TAR 44 | ansible.builtin.unarchive: 45 | src: /var/mq.tar.gz 46 | remote_src: true 47 | dest: /var 48 | tags: download 49 | -------------------------------------------------------------------------------- /roles/downloadmq/tasks/Win32NT_64-bit_downloadmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including specific vars for Windows 3 | ansible.builtin.include_vars: "{{ ansible_system }}_{{ ansible_architecture }}_{{ role_name }}.yml" 4 | 5 | # Set zip filename for releases with old naming convention 6 | - name: Set filename of zip if target host is Windows (old naming convention) 7 | ansible.builtin.set_fact: 8 | zipFile: mqadv_dev{{ version }}_windows.zip 9 | when: ansible_os_family == 'Windows' and not local_source and convention=='old' 10 | 11 | # Set zip filename for releases with new naming convention (>9.3) 12 | - name: Set filename of zip if target host is Windows (new naming convention) 13 | ansible.builtin.set_fact: 14 | zipFile: '{{ vrmf }}-IBM-MQ-Advanced-for-Developers-Win64.zip' 15 | when: ansible_os_family == 'Windows' and not local_source and convention=='new' 16 | 17 | - name: Download MQ Advanced for Developers on Windows 18 | ansible.windows.win_get_url: 19 | url: "{{ downloadURL }}{{ zipFile }}" 20 | dest: "{{ directory }}\\mq.zip" 21 | force: false 22 | tags: download 23 | when: ansible_os_family == 'Windows' and not local_source 24 | 25 | - name: Copy local MQ source to target 26 | ansible.windows.win_copy: 27 | src: "{{ mq_local_path }}" 28 | dest: "{{ directory }}\\mq.zip" 29 | when: local_source 30 | 31 | - name: Unzip MQ on Windows 32 | community.windows.win_unzip: 33 | src: "{{ directory }}\\mq.zip" 34 | remote_src: true 35 | dest: "{{ directory }}\\mq-install" 36 | tags: download 37 | when: ansible_os_family == 'Windows' 38 | -------------------------------------------------------------------------------- /roles/downloadmq/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including common vars for each platform 3 | ansible.builtin.include_vars: "common_{{ role_name }}.yml" 4 | 5 | # Set convention types based on release version (new for >9.3 releases) 6 | - name: Set convention type to old for 9.3 and 9.2 LTS 7 | ansible.builtin.set_fact: 8 | convention: old 9 | when: version==930 or version==920 10 | 11 | - name: Set convention type to new to other releases 12 | ansible.builtin.set_fact: 13 | convention: new 14 | when: convention is undefined 15 | 16 | # If new convention, set the respective v.r.m.f 17 | # Supported releases as of now: 9.3.3, 9.3.4 and 9.3.5 and 9.4 LTS 18 | - name: Set V.R.M.F to 9.3.3 if version matches 19 | ansible.builtin.set_fact: 20 | vrmf: '{{ vrmf933 }}' 21 | when: convention=='new' and version==933 22 | 23 | - name: Set V.R.M.F to 9.3.4 if version matches 24 | ansible.builtin.set_fact: 25 | vrmf: '{{ vrmf934 }}' 26 | when: convention=='new' and version==934 27 | 28 | - name: Set V.R.M.F to 9.3.5 if version matches 29 | ansible.builtin.set_fact: 30 | vrmf: '{{ vrmf935 }}' 31 | when: convention=='new' and version==935 32 | 33 | - name: Set V.R.M.F to 9.4.0 if version matches 34 | ansible.builtin.set_fact: 35 | vrmf: '{{ vrmf940 }}' 36 | when: convention=='new' and version==940 37 | 38 | - name: Set V.R.M.F to 9.4.1 if version matches 39 | ansible.builtin.set_fact: 40 | vrmf: '{{ vrmf941 }}' 41 | when: convention=='new' and version==941 42 | 43 | - name: Set V.R.M.F to 9.4.2 if version matches 44 | ansible.builtin.set_fact: 45 | vrmf: '{{ vrmf942 }}' 46 | when: convention=='new' and version==942 47 | 48 | - name: Including the task list for this platform 49 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ ansible_architecture }}_{{ role_name }}.yml" 50 | -------------------------------------------------------------------------------- /roles/downloadmq/vars/Win32NT_64-bit_downloadmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | directory: C:\Users\Administrator 3 | -------------------------------------------------------------------------------- /roles/downloadmq/vars/common_downloadmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | downloadURL: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/ 3 | vrmf933: '9.3.3.0' 4 | vrmf934: '9.3.4.0' 5 | vrmf935: '9.3.5.0' 6 | vrmf940: '9.4.0.0' 7 | vrmf941: '9.4.1.0' 8 | vrmf942: '9.4.2.0' 9 | -------------------------------------------------------------------------------- /roles/getconfig/README.md: -------------------------------------------------------------------------------- 1 | # GetConfig 2 | Retrieves and copies a local `mqsc` file to the target machine. 3 | -------------------------------------------------------------------------------- /roles/getconfig/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | mqsc_local: ../../../playbooks/files/dev-config.mqsc 3 | -------------------------------------------------------------------------------- /roles/getconfig/tasks/AIX_getconfig.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy developer config file to target 3 | become: true 4 | ansible.builtin.copy: 5 | src: "{{ mqsc_local }}" 6 | dest: /tmp/dev-config.mqsc 7 | mode: "0644" 8 | -------------------------------------------------------------------------------- /roles/getconfig/tasks/Linux_getconfig.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy developer config file to target 3 | ansible.builtin.copy: 4 | src: "{{ mqsc_local }}" 5 | dest: /var/mqm 6 | mode: "0644" 7 | -------------------------------------------------------------------------------- /roles/getconfig/tasks/Win32NT_setupenvironment.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-ansible/9c5ed7ee12d2e0aa2bf196165dc21b7919a577c3/roles/getconfig/tasks/Win32NT_setupenvironment.yml -------------------------------------------------------------------------------- /roles/getconfig/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the task list for this platform 3 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" 4 | -------------------------------------------------------------------------------- /roles/installmq/README.md: -------------------------------------------------------------------------------- 1 | # InstallMQ 2 | Installs the specified MQ packages onto the target machine, as well as accepting the developer license. -------------------------------------------------------------------------------- /roles/installmq/tasks/AIX_installmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if license status file exists 3 | ansible.builtin.stat: 4 | path: /tmp/MQServer/licensestatus.txt 5 | register: license_status 6 | 7 | # - name: Accept MQ license 8 | # become: true 9 | # shell: | 10 | # /tmp/MQServer/mqlicense.sh -accept > /tmp/MQServer/licensestatus.txt 11 | # changed_when: not license_status.stat.exists 12 | 13 | - name: Check if MQ is installed 14 | ansible.builtin.shell: set -o pipefail && apt list | grep ibmmq 15 | changed_when: false 16 | register: installed_mq_packages 17 | failed_when: 18 | - "'FAIL' in installed_mq_packages.stderr" 19 | 20 | - name: Set MQ Packages Location 21 | ansible.builtin.set_fact: 22 | mq_packages_location: /tmp/MQServer 23 | 24 | - name: Check if IBM MQ is already installed 25 | ansible.builtin.command: dspmqver 26 | changed_when: false 27 | register: mq_installed 28 | ignore_errors: true 29 | 30 | - name: Run IBM MQ installation script if MQ is not installed 31 | ansible.builtin.shell: | 32 | ./mq_install_script.sh 33 | args: 34 | chdir: "{{ mq_packages_location }}" 35 | when: mq_installed.rc != 0 36 | become: true 37 | become_user: root 38 | 39 | - name: Install MQ Server 40 | become: true 41 | ansible.builtin.shell: | 42 | installp -acgXd . all 43 | args: 44 | chdir: /tmp/MQServer 45 | register: installed_mq_packages 46 | changed_when: "'ibmmq' not in installed_mq_packages.stdout" 47 | 48 | - name: Set MQ environment variables through profile 49 | become: true 50 | ansible.builtin.lineinfile: 51 | dest: /etc/profile 52 | state: present 53 | line: . /opt/mqm/bin/setmqenv -s 54 | 55 | - name: Cleanup after installation 56 | become: true 57 | ansible.builtin.command: echo "No cleanup required." 58 | changed_when: false 59 | 60 | - name: Add the user to group mqm 61 | become: true 62 | changed_when: true 63 | tags: 64 | - skip_ansible_lint 65 | ansible.builtin.shell: | 66 | chuser groups=mqm ${SUDO_USER:-${USER}} 67 | 68 | - name: Add the ansible ssh user to group mqm 69 | become: true 70 | changed_when: true 71 | ansible.builtin.shell: | 72 | chuser groups=mqm "{{ ansible_ssh_user }}" 73 | -------------------------------------------------------------------------------- /roles/installmq/tasks/Linux_installmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if license status file exists 3 | ansible.builtin.stat: 4 | path: /var/MQServer/licensestatus.txt 5 | register: license_status 6 | 7 | - name: Accept MQ license 8 | ansible.builtin.shell: >- 9 | /var/MQServer/mqlicense.sh 10 | -{{ ibmMqLicence }} > 11 | /var/MQServer/licensestatus.txt 12 | changed_when: not license_status.stat.exists 13 | 14 | - name: Gather package facts 15 | ansible.builtin.package_facts: 16 | manager: auto 17 | 18 | - name: Find required package files 19 | ansible.builtin.find: 20 | paths: /var/MQServer 21 | use_regex: true 22 | patterns: "{{ item }}" 23 | register: package_files 24 | with_items: 25 | - (?i).*runtime.* 26 | - (?i).*gskit.* 27 | - (?i).*server.* 28 | - (?i).*java.* 29 | - (?i).*jre.* 30 | - (?i).*sdk.* 31 | - (?i).*samples.* 32 | - (?i).*man.* 33 | - (?i).*client.* 34 | - (?i).*amqp.* 35 | - (?i).*ams.* 36 | - (?i).*web.* 37 | - (?i).*(-|_)es.* 38 | - (?i).*(-|_)cn.* 39 | # - '(?i).*ftbase.*' 40 | # - '(?i).*ftlogger.*' 41 | # - '(?i).*fttools.*' 42 | # - '(?i).*ftagent.*' 43 | # - '(?i).*ftservice.*' 44 | # - '(?i).*xrservice.*' 45 | # - '(?i).*sfbridge.*' 46 | # - '(?i).*bcbridge.*' 47 | # - '(?i).*(-|_)de.*' 48 | # - '(?i).*(-|_)fr.*' 49 | # - '(?i).*(-|_)ja.*' 50 | # - '(?i).*(-|_)it.*' 51 | # - '(?i).*(-|_)ko.*' 52 | # - '(?i).*(-|_)ru.*' 53 | # - '(?i).*(-|_)pt.*' 54 | # - '(?i).*(-|_)hu.*' 55 | # - '(?i).*(-|_)pl.*' 56 | # - '(?i).*(-|_)cs.*' 57 | # - '(?i).*(-|_)tw.*' 58 | when: 59 | - '"MQSeriesRuntime" not in ansible_facts.packages' 60 | - '"ibmmq-runtime" not in ansible_facts.packages' 61 | 62 | - name: Create a list of paths to the packages from found files 63 | ansible.builtin.set_fact: 64 | package_list: "{{ package_files.results | map(attribute='files.0.path') | list }}" 65 | when: 66 | - "'MQSeriesRuntime' not in ansible_facts.packages" 67 | - "'ibmmq-runtime' not in ansible_facts.packages" 68 | 69 | - name: Rpm Installation 70 | ansible.builtin.dnf: 71 | name: "{{ package_list }}" 72 | state: present 73 | disable_gpg_check: true 74 | when: 75 | - ansible_distribution == 'RedHat' 76 | - "'MQSeriesRuntime' not in ansible_facts.packages" 77 | 78 | - name: Deb Installation 79 | ansible.builtin.apt: 80 | deb: "{{ item }}" 81 | state: present 82 | when: 83 | - ansible_distribution == 'Ubuntu' 84 | - "'ibmmq-runtime' not in ansible_facts.packages" 85 | loop: "{{ package_list }}" 86 | -------------------------------------------------------------------------------- /roles/installmq/tasks/Win32NT_installmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if MQ is already installed 3 | ansible.windows.win_shell: Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | sort-object -property DisplayName | Select-Object DisplayName | findstr 'IBM MQ' 4 | register: is_mq_installed 5 | failed_when: 6 | - "'FAIL' in is_mq_installed.stderr" 7 | 8 | - name: Silent Install 9 | ansible.windows.win_command: 10 | cmd: msiexec /i "{{ directory }}\mq-install\MQServer\MSI\IBM MQ.msi" /l*v C:\install.log /q USEINI="{{ directory }}\mq-install\MQServer\Response.ini" TRANSFORMS="1033.mst" 11 | AGREETOLICENSE="{{ ibmMqLicence }}" ADDLOCAL="Server" 12 | when: is_mq_installed.rc == 1 13 | 14 | - name: Set MQ environment variable 15 | ansible.windows.win_command: 16 | cmd: '".\setmqenv.cmd" -s' 17 | chdir: C:\Program Files\IBM\MQ\bin 18 | -------------------------------------------------------------------------------- /roles/installmq/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the vars for this platform 3 | ansible.builtin.include_vars: "{{ ansible_system }}_{{ role_name }}.yml" 4 | 5 | - name: Including the task list for this platform 6 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" 7 | -------------------------------------------------------------------------------- /roles/installmq/vars/AIX_installmq.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-ansible/9c5ed7ee12d2e0aa2bf196165dc21b7919a577c3/roles/installmq/vars/AIX_installmq.yml -------------------------------------------------------------------------------- /roles/installmq/vars/Linux_installmq.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-ansible/9c5ed7ee12d2e0aa2bf196165dc21b7919a577c3/roles/installmq/vars/Linux_installmq.yml -------------------------------------------------------------------------------- /roles/installmq/vars/Win32NT_installmq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ibmMqLicence: "no" 3 | -------------------------------------------------------------------------------- /roles/setupconsole/README.md: -------------------------------------------------------------------------------- 1 | # SetupConsole 2 | Configures the target machine permissions and registries to enable the MQ Web Console. -------------------------------------------------------------------------------- /roles/setupconsole/tasks/AIX_setupconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if basic registry exists 3 | ansible.builtin.stat: 4 | path: /opt/mqm/web/mq/samp/configuration/basic_registry.xml 5 | register: basic_registry_result 6 | 7 | - name: Moving basic registry 8 | become: true 9 | ansible.builtin.copy: 10 | src: /opt/mqm/web/mq/samp/configuration/basic_registry.xml 11 | dest: /var/mqm/web/installations/Installation1/servers/mqweb/ 12 | remote_src: true 13 | mode: "{{ basic_registry_result.stat.mode }}" 14 | when: basic_registry_result.stat.exists 15 | 16 | - name: Remove old basic registry 17 | ansible.builtin.file: 18 | path: /var/mqm/web/installations/Installation1/servers/mqweb/ 19 | state: absent 20 | when: basic_registry_result.stat.exists 21 | 22 | - name: Check if old mqwebuser exists 23 | ansible.builtin.stat: 24 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.old 25 | register: mqwebuser_result 26 | 27 | - name: Stat mqwebuser 28 | ansible.builtin.stat: 29 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 30 | register: mqwebuser_current_result 31 | 32 | - name: Moving mqwebuser to old mqwebuser 33 | become: true 34 | ansible.builtin.copy: 35 | src: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 36 | dest: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.old 37 | remote_src: true 38 | mode: "{{ mqwebuser_current_result.stat.mode }}" 39 | when: not mqwebuser_result.stat.exists 40 | 41 | - name: Check if moved basic registry exists 42 | ansible.builtin.stat: 43 | path: /var/mqm/web/installations/Installation1/servers/mqweb/basic_registry.xml 44 | register: moved_registry 45 | 46 | - name: Using basic_registry as webwebuser 47 | become: true 48 | ansible.builtin.copy: 49 | src: /var/mqm/web/installations/Installation1/servers/mqweb/basic_registry.xml 50 | dest: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 51 | remote_src: true 52 | mode: "{{ moved_registry.stat.mode }}" 53 | when: moved_registry.stat.exists 54 | 55 | - name: Remove old basic_registry 56 | ansible.builtin.file: 57 | path: /var/mqm/web/installations/Installation1/servers/mqweb/basic_registry.xml 58 | state: absent 59 | when: moved_registry.stat.exists 60 | 61 | - name: Check correct mqwebuser exists 62 | ansible.builtin.stat: 63 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 64 | register: final_mqwebuser 65 | 66 | - name: Ensure correct permissions for mqwebuser.xml 67 | become: true 68 | ansible.builtin.file: 69 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 70 | mode: "0640" 71 | when: final_mqwebuser.stat.exists 72 | -------------------------------------------------------------------------------- /roles/setupconsole/tasks/Linux_setupconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if basic registry exists in the install folder 3 | ansible.builtin.stat: 4 | path: /opt/mqm/web/mq/samp/configuration/basic_registry.xml 5 | register: basic_registry_result 6 | 7 | - name: Check if mqwebuser already exists in target folder 8 | ansible.builtin.stat: 9 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 10 | register: target_mqwebuser_result 11 | 12 | - name: Set permissions to allow overwrite of target mqwebuser.xml if it already exists 13 | become: true 14 | ansible.builtin.file: 15 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 16 | mode: "0640" 17 | when: target_mqwebuser_result.stat.exists 18 | 19 | - name: Copying basic registry 20 | become: true 21 | ansible.builtin.copy: 22 | src: /opt/mqm/web/mq/samp/configuration/basic_registry.xml 23 | dest: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 24 | remote_src: true 25 | mode: "0644" 26 | when: basic_registry_result.stat.exists 27 | 28 | - name: Ensure correct permissions for mqwebuser.xml to allow setmqweb commands 29 | become: true 30 | ansible.builtin.file: 31 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 32 | mode: "0640" 33 | -------------------------------------------------------------------------------- /roles/setupconsole/tasks/Win32NT_setupconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if basic registry exists 3 | ansible.windows.win_stat: 4 | path: C:\Program Files\IBM\MQ\web\mq\samp\configuration\basic_registry.xml 5 | register: basic_registry 6 | 7 | - name: Replace the existing config file with basic registry 8 | ansible.windows.win_copy: 9 | src: C:\Program Files\IBM\MQ\web\mq\samp\configuration\basic_registry.xml 10 | dest: C:\ProgramData\IBM\MQ\web\installations\Installation1\servers\mqweb\mqwebuser.xml 11 | remote_src: true 12 | when: basic_registry.stat.exists 13 | -------------------------------------------------------------------------------- /roles/setupconsole/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the task list for this platform 3 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" 4 | -------------------------------------------------------------------------------- /roles/setupenvironment/README.md: -------------------------------------------------------------------------------- 1 | # SetupEnvironment 2 | Configures platform specific attributes such as disk space. -------------------------------------------------------------------------------- /roles/setupenvironment/tasks/AIX_setupenvironment.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Incrase ssh connection timeout 3 | ansible.builtin.command: /usr/sbin/sshd -o ClientAliveInterval=3000 4 | changed_when: true 5 | 6 | - name: Increase space on the disk 7 | ansible.builtin.command: chfs -a size=+4G /tmp 8 | changed_when: true 9 | 10 | - name: Increase max_file 11 | ansible.builtin.command: huser fsize=-1 root 12 | changed_when: true 13 | -------------------------------------------------------------------------------- /roles/setupenvironment/tasks/Linux_setupenvironment.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-ansible/9c5ed7ee12d2e0aa2bf196165dc21b7919a577c3/roles/setupenvironment/tasks/Linux_setupenvironment.yml -------------------------------------------------------------------------------- /roles/setupenvironment/tasks/Win32NT_setupenvironment.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-ansible/9c5ed7ee12d2e0aa2bf196165dc21b7919a577c3/roles/setupenvironment/tasks/Win32NT_setupenvironment.yml -------------------------------------------------------------------------------- /roles/setupenvironment/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the task list for this platform 3 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" 4 | -------------------------------------------------------------------------------- /roles/setupusers/README.md: -------------------------------------------------------------------------------- 1 | # SetupUsers 2 | 3 | ### Parameters 4 | Configures the relevant users required to install MQ on the target machine. 5 | 6 | | Name | Description | Example | 7 | | --- | --- | --- | 8 | | app_uid | Unique user identifier for `app` | `909` | 9 | | gid| Unique group identifier for `mqm` | `909` | 10 | | app_gid | Unique group identifier for `mqclient` | `909` | 11 | | mqm_home | Home path for MQ users | `/home/mqm` | 12 | | mqm_profile | Path for MQ users' profile | `.profile` | 13 | | mqm_shell | Default shell for platform | `/bin/bash` | 14 | -------------------------------------------------------------------------------- /roles/setupusers/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | app_uid: 909 3 | app_gid: 909 4 | mqm_uid: 2001 5 | mqm_gid: 2001 6 | mqm_home: /home/mqm 7 | mqm_profile: .profile 8 | mqm_shell: /bin/bash 9 | -------------------------------------------------------------------------------- /roles/setupusers/tasks/AIX_setupusers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add 'mqclient' group 3 | become: true 4 | ansible.builtin.group: 5 | name: mqclient 6 | state: present 7 | gid: "{{ gid }}" 8 | 9 | - name: Add the user 'app' with a specific UID 10 | become: true 11 | vars: 12 | apppassword: Passw0rd 13 | ansible.builtin.user: 14 | name: app 15 | password: "{{ 'apppassword' | password_hash('sha512', 65534 | random(seed=inventory_hostname) | string) }}" 16 | uid: "{{ gid }}" 17 | group: mqclient 18 | -------------------------------------------------------------------------------- /roles/setupusers/tasks/Linux_setupusers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create mqm group 3 | ansible.builtin.group: 4 | name: mqm 5 | gid: "{{ mqm_gid }}" 6 | 7 | - name: Create mqm user 8 | ansible.builtin.user: 9 | name: mqm 10 | uid: "{{ mqm_uid }}" 11 | group: mqm 12 | home: "{{ mqm_home }}" 13 | shell: "{{ mqm_shell }}" 14 | 15 | - name: Set MQ environment variables through profile 16 | ansible.builtin.lineinfile: 17 | dest: "{{ mqm_home }}/{{ mqm_profile }}" 18 | state: present 19 | line: . /opt/mqm/bin/setmqenv -s 20 | when: ansible_distribution != 'RedHat' 21 | 22 | - name: Set MQ environment variables through profile on RedHat 23 | ansible.builtin.lineinfile: 24 | dest: "{{ mqm_home }}/.bashrc" 25 | state: present 26 | line: . /opt/mqm/bin/setmqenv -s 27 | when: ansible_distribution == 'RedHat' 28 | 29 | - name: Create an admin user 30 | ansible.builtin.user: 31 | name: mqadm 32 | groups: mqm 33 | append: true 34 | home: "{{ mqm_home }}" 35 | shell: "{{ mqm_shell }}" 36 | 37 | - name: Add 'mqclient' group 38 | become: true 39 | ansible.builtin.group: 40 | name: mqclient 41 | state: present 42 | gid: "{{ app_gid }}" 43 | 44 | - name: Add the user 'app' with a specific UID 45 | become: true 46 | vars: 47 | apppassword: Passw0rd 48 | ansible.builtin.user: 49 | name: app 50 | password: "{{ 'apppassword' | password_hash('sha512', 65534 | random(seed=inventory_hostname) | string) }}" 51 | uid: "{{ app_uid }}" 52 | group: mqclient 53 | -------------------------------------------------------------------------------- /roles/setupusers/tasks/Win32NT_setupusers.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-ansible/9c5ed7ee12d2e0aa2bf196165dc21b7919a577c3/roles/setupusers/tasks/Win32NT_setupusers.yml -------------------------------------------------------------------------------- /roles/setupusers/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the task list for this platform 3 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" 4 | -------------------------------------------------------------------------------- /roles/startconsole/README.md: -------------------------------------------------------------------------------- 1 | # StartConsole 2 | Start and allow the MQ Web Console to be accessed from anywhere. -------------------------------------------------------------------------------- /roles/startconsole/tasks/AIX_startconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Change owner and permissions on mqwebuser.xml 3 | become: true 4 | ansible.builtin.file: 5 | path: mqwebuser.xml 6 | owner: mqm 7 | attributes: u+w 8 | 9 | - name: Allow console to be accessed from anywhere 10 | ansible.builtin.command: 11 | cmd: setmqweb properties -k httpHost -v "*" 12 | chdir: /var/mqm/web/installations/Installation1/servers/mqweb 13 | become: true 14 | become_user: mqm 15 | changed_when: true 16 | 17 | - name: Start web console 18 | ansible.builtin.command: 19 | cmd: nohup strmqweb 20 | chdir: /var/mqm/web/installations/Installation1/servers/mqweb 21 | become: true 22 | become_user: mqm 23 | changed_when: true 24 | 25 | - name: Check if Web Console is Running 26 | become: true 27 | become_user: mqm 28 | ansible.builtin.command: 29 | cmd: dspmqweb 30 | chdir: /var/mqm/web/installations/Installation1/servers/mqweb 31 | changed_when: false 32 | ignore_errors: true 33 | register: console_status 34 | failed_when: 35 | - console_status.rc != 0 36 | -------------------------------------------------------------------------------- /roles/startconsole/tasks/Linux_startconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Allow console to be accessed from anywhere 3 | ansible.builtin.command: 4 | cmd: setmqweb properties -k httpHost -v "*" 5 | chdir: /var/mqm/web/installations/Installation1/servers/mqweb 6 | changed_when: true 7 | 8 | - name: Check if Web Console is Running 9 | ansible.builtin.command: 10 | cmd: dspmqweb 11 | chdir: /var/mqm/web/installations/Installation1/servers/mqweb 12 | ignore_errors: true 13 | changed_when: false 14 | register: console_status 15 | failed_when: 16 | - console_status.rc != 0 17 | - "'is not running.' not in console_status.stderr" 18 | 19 | - name: Start web console 20 | ansible.builtin.command: 21 | cmd: nohup strmqweb 22 | chdir: /var/mqm/web/installations/Installation1/servers/mqweb 23 | when: "'is not running.' in console_status.stderr" 24 | -------------------------------------------------------------------------------- /roles/startconsole/tasks/Win32NT_startconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Enable remote connections to the mqweb 3 | ansible.windows.win_command: 4 | cmd: .\setmqweb.bat properties -k httpHost -v "*" 5 | chdir: C:\Program Files\IBM\MQ\bin 6 | 7 | - name: Start console 8 | ansible.windows.win_command: 9 | cmd: .\strmqweb.bat 10 | chdir: C:\Program Files\IBM\MQ\bin 11 | async: 180 12 | poll: 0 13 | -------------------------------------------------------------------------------- /roles/startconsole/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Including the task list for this platform 3 | ansible.builtin.include_tasks: "{{ ansible_system }}_{{ role_name }}.yml" 4 | -------------------------------------------------------------------------------- /tests/playbooks/1_test_install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Test downloading and installing MQ - Ubuntu, RedHat, AIX 3 | hosts: all 4 | become: true 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | 8 | tasks: 9 | - name: Get 'mqclient' group 10 | command: getent group mqclient 11 | changed_when: false 12 | register: testout_mqclient_group 13 | 14 | - name: Test 'mqclient' group exists 15 | assert: 16 | that: 17 | - '{{ testout_mqclient_group.stdout_lines }} is search("mqclient")' 18 | fail_msg: "<> 'MQclient' group does not exist." 19 | success_msg: "<> 'MQclient' group exists." 20 | 21 | - name: Get 'app' user 22 | command: cat /etc/passwd 23 | changed_when: false 24 | register: testout_app_user 25 | 26 | - name: Test 'app' user exists 27 | assert: 28 | that: 29 | - '{{ testout_app_user.stdout_lines }} is search("app")' 30 | fail_msg: "<> 'app' user does not exist." 31 | success_msg: "<> 'app' user exists." 32 | 33 | - name: Get MQ installation package 34 | stat: 35 | path: /var/mq.tar.gz 36 | register: testout_mq_downloaded 37 | 38 | - name: Test if MQ is downloaded 39 | assert: 40 | that: 41 | - testout_mq_downloaded.stat.exists 42 | fail_msg: "<> MQ installation tar not found." 43 | success_msg: "<> MQ installation tar found." 44 | 45 | - name: Get MQ unarchived directory 46 | stat: 47 | path: /var/MQServer 48 | register: testout_mq_unarchived 49 | 50 | - name: Test MQ is unarchived 51 | assert: 52 | that: testout_mq_unarchived.stat.isdir 53 | fail_msg: "<> MQ Server is not a directory." 54 | success_msg: "<> MQServer is a directory." 55 | 56 | - name: Check license status 57 | command: cat /var/MQServer/licensestatus.txt 58 | register: test_out_accepted 59 | changed_when: false 60 | 61 | - name: Test licence accepted 62 | assert: 63 | that: '{{ test_out_accepted }} is search("Proceed with install")' 64 | fail_msg: "<> License has not been accepted" 65 | success_msg: "<> License has been accepted" 66 | 67 | - name: Get MQ version 68 | command: dspmqver 69 | register: testout_mq_version 70 | changed_when: false 71 | 72 | - name: Test mq installed and environment variables set 73 | assert: 74 | that: '{{ testout_mq_version }} is search("LicenseType: Developer")' 75 | fail_msg: "<> MQ might not be installed or environment variables have not been set" 76 | success_msg: "<> MQ environment variables correctly set." 77 | when: ansible_architecture == 'x86_64' 78 | 79 | - name: Test mq installed and environment variables set 80 | assert: 81 | that: '{{ testout_mq_version }} is search("LicenseType: Trial")' 82 | fail_msg: "<> MQ might not be installed or environment variables have not been set" 83 | success_msg: "<> MQ environment variables correctly set." 84 | when: ansible_architecture != 'x86_64' 85 | 86 | 87 | - name: Get dev config (Linux) 88 | stat: 89 | path: /var/mqm/dev-config.mqsc 90 | register: testout_dev_config_copied_linux 91 | when: ansible_system == 'Linux' 92 | 93 | - name: Get dev config (AIX) 94 | stat: 95 | path: /tmp/dev-config.mqsc 96 | register: testout_dev_config_copied_aix 97 | when: ansible_system != 'Linux' 98 | 99 | - name: Test dev config exists 100 | assert: 101 | that: testout_dev_config_copied_linux.stat.exists or testout_dev_config_copied_aix.stat.exists 102 | fail_msg: "<> MQSC dev config file does not exist." 103 | success_msg: "<> MQSC dev config file exists." 104 | -------------------------------------------------------------------------------- /tests/playbooks/2_setup_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Setup for tests 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | 7 | tasks: 8 | - name: Copy MQSC file to container 9 | copy: 10 | src: mqsc_display 11 | dest: /var/mqm/mqsc_display 12 | mode: "0644" 13 | -------------------------------------------------------------------------------- /tests/playbooks/3_test_absent_qmgr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Tests when absent 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | tasks: 10 | - name: Cannot delete when already deleted 11 | queue_manager: 12 | qmname: qm1_does_not_exist 13 | state: absent 14 | register: testout_1 15 | failed_when: false 16 | 17 | - name: Test delete output 18 | assert: 19 | that: 20 | - testout_1.state == 'absent' 21 | - testout_1.msg == 'AMQ8118E: IBM MQ queue manager does not exist.' 22 | fail_msg: "<> {{testout_1.msg}}" 23 | success_msg: "<> {{testout_1.msg}}" 24 | 25 | - name: Stops QMGR unsuccessfully 26 | queue_manager: 27 | qmname: qm_1 28 | state: stopped 29 | register: testout_2 30 | failed_when: false 31 | 32 | - name: Test stop output 33 | assert: 34 | that: 35 | - testout_2.state == 'absent' 36 | - testout_2.msg == 'AMQ8118E: IBM MQ queue manager does not exist.' 37 | fail_msg: "<> {{testout_2.msg}}" 38 | success_msg: "<> {{testout_2.msg}}" 39 | 40 | - name: Creates QMGR successfully 41 | queue_manager: 42 | qmname: qm_1 43 | state: present 44 | register: testout_2 45 | failed_when: false 46 | 47 | - name: Test create output 48 | assert: 49 | that: 50 | - testout_2.state == 'present' 51 | - testout_2.rc == 0 52 | - testout_2.msg == 'IBM MQ Queue Manager Created' 53 | fail_msg: "<> {{testout_2.msg}}" 54 | success_msg: "<> {{testout_2.msg}}" 55 | -------------------------------------------------------------------------------- /tests/playbooks/4_test_present_qmgr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Test QMGR present 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | tasks: 10 | - name: (SETUP) create QMGR 11 | queue_manager: 12 | qmname: qm1_present_start 13 | state: present 14 | 15 | - name: (SETUP) create QMGR 2 16 | queue_manager: 17 | qmname: qm1_present_mqsc 18 | state: present 19 | 20 | - name: Cannot stop when queue manager is already stopped 21 | queue_manager: 22 | qmname: qm1_present_start 23 | state: stopped 24 | register: testout_1 25 | failed_when: false 26 | 27 | - name: Test the output for present when Queue Manager exists 28 | assert: 29 | that: 30 | - testout_1.state == 'present' 31 | - testout_1.msg == 'AMQ8146E: IBM MQ queue manager not available.\n' 32 | fail_msg: "<> {{testout_1.msg}}" 33 | success_msg: "<> {{testout_1.msg}}" 34 | 35 | - name: Cannot create when queue manager already exists 36 | queue_manager: 37 | qmname: qm1_present_start 38 | state: present 39 | register: testout_1 40 | failed_when: false 41 | 42 | - name: Test the output for present when Queue Manager exists 43 | assert: 44 | that: 45 | - testout_1.state == 'present' 46 | - testout_1.msg == 'IBM MQ Queue Manager already exists. ' 47 | fail_msg: "<> {{testout_1.msg}}" 48 | success_msg: "<> {{testout_1.msg}}" 49 | 50 | 51 | - name: Set queue manager running when it is in present state 52 | queue_manager: 53 | qmname: qm1_present_start 54 | state: running 55 | register: testout_2 56 | failed_when: false 57 | 58 | - name: Test the output for running when Queue Manager does exist 59 | assert: 60 | that: 61 | - testout_2.state == 'running' 62 | - testout_2.rc == 0 63 | - testout_2.msg == 'IBM MQ queue manager \'qm1_present_start\' running.' 64 | fail_msg: "<> {{testout_2.msg}}" 65 | success_msg: "<> {{testout_2.msg}}" 66 | 67 | - name: Run module to test present 68 | queue_manager: 69 | qmname: qm1_present_mqsc 70 | state: present 71 | mqsc_file: /var/mqm/dev-config.mqsc 72 | register: testout_3 73 | failed_when: false 74 | 75 | - name: Test the output for present when MQSC file is supplied 76 | assert: 77 | that: 78 | - testout_3.state == 'present' 79 | - testout_3.msg == 'IBM MQ Queue Manager already exists. MQSC configuration successfully applied to queue manager.' 80 | fail_msg: ' <> {{ testout_3.msg }}' 81 | success_msg: '<> {{ testout_3.msg }}' 82 | -------------------------------------------------------------------------------- /tests/playbooks/5_test_running_qmgr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Tests when running (3) 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | tasks: 10 | - name: (SETUP) create QMGR 11 | queue_manager: 12 | qmname: qm1_running 13 | state: present 14 | 15 | - name: (SETUP) start QMGR 16 | queue_manager: 17 | qmname: qm1_running 18 | state: running 19 | 20 | - name: Can run mqsc when running (given state:present) 21 | queue_manager: 22 | qmname: qm1_running 23 | state: present 24 | mqsc_file: /var/mqm/mqsc_display 25 | register: testout 26 | failed_when: false 27 | 28 | - name: Test mqsc output (given state:present) 29 | assert: 30 | that: 31 | - testout.state == 'present' 32 | - testout.msg == 'IBM MQ Queue Manager already exists. MQSC configuration successfully applied to queue manager.' 33 | fail_msg: "<> {{testout.msg}}" 34 | success_msg: "<> {{testout.msg}}" 35 | 36 | - name: Can run mqsc when running (given state:running) 37 | queue_manager: 38 | qmname: qm1_running 39 | state: running 40 | mqsc_file: /var/mqm/mqsc_display 41 | register: testout 42 | failed_when: false 43 | 44 | - name: Dump test output 45 | debug: 46 | msg: "{{ testout }}" 47 | 48 | - name: Test mqsc output (given state:running) 49 | assert: 50 | that: 51 | - testout.state == 'running' 52 | - testout.msg == 'MQSC configuration successfully applied to queue manager.' 53 | fail_msg: "<> {{testout.msg}}" 54 | success_msg: "<> {{testout.msg}}" 55 | 56 | - name: Cannot run mqsc when file does not exist (given state:running) 57 | queue_manager: 58 | qmname: qm1_running 59 | state: running 60 | mqsc_file: mqsc_display_does_not_exist 61 | register: testout 62 | failed_when: false 63 | 64 | - name: Test mqsc output (given state:running) 65 | assert: 66 | that: 67 | - testout.state == 'running' 68 | - testout.rc == 16 69 | - testout.msg == 'MQSC file could not be found' 70 | fail_msg: "<> {{testout.msg}}" 71 | success_msg: "<> {{testout.msg}}" 72 | 73 | - name: Cannot create when already running 74 | queue_manager: 75 | qmname: qm1_running 76 | state: present 77 | register: testout 78 | failed_when: false 79 | 80 | - name: Test create output 81 | assert: 82 | that: 83 | - testout.msg == 'IBM MQ Queue Manager already exists. ' 84 | fail_msg: "<> {{testout.msg}}" 85 | success_msg: "<> {{testout.msg}}" 86 | 87 | - name: Cannot start when already running 88 | queue_manager: 89 | qmname: qm1_running 90 | state: running 91 | register: testout 92 | failed_when: false 93 | 94 | - name: Test start output 95 | assert: 96 | that: 97 | - testout.state == 'running' 98 | - testout.msg == 'IBM MQ queue manager running' 99 | fail_msg: "<> {{testout.msg}}" 100 | success_msg: "<> {{testout.msg}}" 101 | 102 | - name: Cannot delete when running 103 | queue_manager: 104 | qmname: qm1_running 105 | state: absent 106 | register: testout 107 | failed_when: false 108 | 109 | - name: Test delete output 110 | assert: 111 | that: 112 | - testout.state == 'running' 113 | - testout.msg == 'IBM MQ queue manager running.' 114 | fail_msg: "<> {{testout.msg}}" 115 | success_msg: "<> {{testout.msg}}" 116 | 117 | - name: Can stop when running 118 | queue_manager: 119 | qmname: qm1_running 120 | state: stopped 121 | register: testout 122 | failed_when: false 123 | 124 | - name: Test stop output 125 | assert: 126 | that: 127 | - testout.state == 'stopped' 128 | - testout.rc == 0 129 | - testout.msg == 'Quiesce request accepted. The queue manager will stop when all outstanding work\nis complete.\n' 130 | fail_msg: "<> {{testout.msg}}" 131 | success_msg: "<> {{testout.msg}}" 132 | -------------------------------------------------------------------------------- /tests/playbooks/6_test_misc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Misc tests (4) 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | tasks: 10 | - name: (SETUP) create QMGR 11 | queue_manager: 12 | qmname: qm1_misc 13 | state: present 14 | 15 | - name: Can delete when present 16 | queue_manager: 17 | qmname: qm1_misc 18 | state: absent 19 | register: testout_1 20 | failed_when: false 21 | 22 | - name: Test delete output 23 | assert: 24 | that: 25 | - testout_1.state == 'absent' 26 | - testout_1.rc == 0 27 | - testout_1.msg == "IBM MQ queue manager 'qm1_misc' deleted." 28 | fail_msg: '<> {{testout_1.msg}}' 29 | success_msg: '<> {{testout_1.msg}}' 30 | 31 | - name: Can start, run and configure straight away 32 | queue_manager: 33 | qmname: qm1_misc_2 34 | state: running 35 | mqsc_file: /var/mqm/mqsc_display 36 | register: testout_1 37 | failed_when: false 38 | 39 | - name: Test run output 40 | assert: 41 | that: 42 | # MQSC has run successfully 43 | - testout_1.state == 'running' 44 | - testout_1.rc == 0 45 | - testout_1.msg == 'MQSC configuration successfully applied to queue manager.' 46 | fail_msg: '<> {{testout_1.msg}}' 47 | success_msg: '<> {{testout_1.msg}}' 48 | -------------------------------------------------------------------------------- /tests/playbooks/7_test_web_console.yml: -------------------------------------------------------------------------------- 1 | - name: test downloading and installing MQ 2 | hosts: all 3 | become: true 4 | become_user: mqm 5 | environment: 6 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 7 | 8 | tasks: 9 | - name: get mqwebuser 10 | stat: 11 | path: /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 12 | register: testout_mqwebuser 13 | 14 | - name: test new mqwebuser exists 15 | assert: 16 | that: 17 | - testout_mqwebuser.stat.exists 18 | fail_msg: "<> mqwebuser does not exist." 19 | success_msg: "<> mqwebusesr exists." 20 | 21 | - name: print mqwebuser 22 | debug: 23 | msg: testout_mqwebuser.stat.pw_name 24 | 25 | - name: get mqwebuser file permissions 26 | shell: ls -l /var/mqm/web/installations/Installation1/servers/mqweb/mqwebuser.xml 27 | register: testout_mqwebuser_permissions 28 | changed_when: false 29 | 30 | - name: test mqwebuser has correct permissions 31 | assert: 32 | that: 33 | - '{{ testout_mqwebuser_permissions }} is search("-rw-r-----")' 34 | fail_msg: "<> not correct permissions." 35 | success_msg: "<> correct permissions." 36 | 37 | # - name: test ansible user is owner of mqwebuser 38 | # assert: 39 | # that: 40 | # - '{{ testout_mqwebuser_permissions }} is search("{{ ansible_ssh_user }}")' 41 | 42 | - name: display web console status 43 | shell: dspmqweb status 44 | register: testout_webconsole_status 45 | changed_when: false 46 | ignore_errors: true 47 | 48 | - name: test mq web console is running 49 | assert: 50 | that: 51 | - '{{ testout_webconsole_status.stdout_lines }} is search("is running")' 52 | fail_msg: "<> MQ web console is not running." 53 | success_msg: "<> MQ web console running" 54 | ignore_errors: true -------------------------------------------------------------------------------- /tests/playbooks/8_cleanup_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Cleanup after tests 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | tasks: 10 | - name: Stop qmgr if running 11 | queue_manager: 12 | qmname: qm_1 13 | state: stopped 14 | register: testout_1 15 | failed_when: false 16 | 17 | - name: Dump stop output 18 | debug: 19 | msg: "{{ testout_1 }}" 20 | 21 | - name: Delete qmgr 22 | until: testout_2.state == 'absent' 23 | retries: 3 24 | delay: 1 25 | queue_manager: 26 | qmname: qm_1 27 | state: absent 28 | register: testout_2 29 | failed_when: false 30 | 31 | - name: Dump delete output 32 | debug: 33 | msg: "{{ testout_2 }}" 34 | 35 | - name: Stop qmgr if running 36 | queue_manager: 37 | qmname: qm1_running 38 | state: stopped 39 | register: testout_1 40 | failed_when: false 41 | 42 | - name: Dump stop output 43 | debug: 44 | msg: "{{ testout_1 }}" 45 | 46 | - name: Delete qmgr 47 | until: testout_2.state == 'absent' 48 | retries: 3 49 | delay: 1 50 | queue_manager: 51 | qmname: qm1_running 52 | state: absent 53 | register: testout_2 54 | failed_when: false 55 | 56 | - name: Dump delete output 57 | debug: 58 | msg: "{{ testout_2 }}" 59 | 60 | - name: Delete qmgr 61 | until: testout_1.state == 'absent' 62 | retries: 3 63 | delay: 1 64 | queue_manager: 65 | qmname: qm1_present_mqsc 66 | state: absent 67 | register: testout_1 68 | failed_when: false 69 | 70 | - name: Stop qmgr if running 71 | queue_manager: 72 | qmname: qm1_present_start 73 | state: stopped 74 | register: testout_2 75 | failed_when: false 76 | 77 | - name: Delete qmgr 78 | until: testout_3.state == 'absent' 79 | retries: 3 80 | delay: 1 81 | queue_manager: 82 | qmname: qm1_present_start 83 | state: absent 84 | register: testout_3 85 | failed_when: false 86 | 87 | - name: Stop qmgr if running 88 | queue_manager: 89 | qmname: qm1_misc 90 | state: stopped 91 | register: testout_1 92 | failed_when: false 93 | 94 | - name: Dump stop output 95 | debug: 96 | msg: "{{ testout_1 }}" 97 | 98 | - name: Delete qmgr 99 | until: testout_2.state == 'absent' 100 | retries: 3 101 | delay: 1 102 | queue_manager: 103 | qmname: qm1_misc 104 | state: absent 105 | register: testout_2 106 | failed_when: false 107 | 108 | - name: Dump delete output 109 | debug: 110 | msg: "{{ testout_2 }}" 111 | 112 | - name: Stop qmgr if running 113 | queue_manager: 114 | qmname: qm1_misc_2 115 | state: stopped 116 | register: testout_1 117 | failed_when: false 118 | 119 | - name: Dump stop output 120 | debug: 121 | msg: "{{ testout_1 }}" 122 | 123 | - name: Delete qmgr 124 | until: testout_2.state == 'absent' 125 | retries: 3 126 | delay: 1 127 | queue_manager: 128 | qmname: qm1_misc_2 129 | state: absent 130 | register: testout_2 131 | failed_when: false 132 | 133 | - name: Dump delete output 134 | debug: 135 | msg: "{{ testout_2 }}" 136 | 137 | - name: Delete qmgr 138 | until: testout_1.state == 'absent' 139 | retries: 3 140 | delay: 1 141 | queue_manager: 142 | qmname: qm1_present_mqsc 143 | state: absent 144 | register: testout_1 145 | failed_when: false 146 | 147 | - name: Stop qmgr if running 148 | queue_manager: 149 | qmname: qm1_present_start 150 | state: stopped 151 | register: testout_2 152 | failed_when: false 153 | 154 | - name: Delete qmgr 155 | until: testout_3.state == 'absent' 156 | retries: 3 157 | delay: 1 158 | queue_manager: 159 | qmname: qm1_present_start 160 | state: absent 161 | register: testout_3 162 | failed_when: false 163 | 164 | - name: Stop qmgr if running 165 | queue_manager: 166 | qmname: qm1_all 167 | state: stopped 168 | register: testout_2 169 | failed_when: false 170 | 171 | - name: Delete qmgr 172 | until: testout_3.state == 'absent' 173 | retries: 3 174 | delay: 1 175 | queue_manager: 176 | qmname: qm1_all 177 | state: absent 178 | register: testout_3 179 | failed_when: false 180 | 181 | - name: Stop qmgr if running 182 | queue_manager: 183 | qmname: qm2_all 184 | state: stopped 185 | register: testout_2 186 | failed_when: false 187 | 188 | - name: Delete qmgr 189 | until: testout_3.state == 'absent' 190 | retries: 3 191 | delay: 1 192 | queue_manager: 193 | qmname: qm2_all 194 | state: absent 195 | register: testout_3 196 | failed_when: false -------------------------------------------------------------------------------- /tests/playbooks/9_test_all_qmgrs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ALL_QMGRS Tests (5) 3 | hosts: all 4 | become: true 5 | become_user: mqm 6 | environment: 7 | PATH: /opt/mqm/bin:{{ ansible_env.PATH }} 8 | 9 | tasks: 10 | - name: (SETUP) create QMGRs 11 | queue_manager: 12 | qmname: 13 | - qm1_all 14 | - qm2_all 15 | state: present 16 | register: testout 17 | 18 | - name: Dump create output 19 | debug: 20 | msg: "{{ testout }}" 21 | 22 | - name: Start ALL_QMGRs 23 | queue_manager: 24 | qmname: ALL_QMGRS 25 | state: running 26 | register: testout_1 27 | 28 | - name: Dump start output 29 | debug: 30 | msg: "{{ testout_1 }}" 31 | 32 | - name: Test start output 33 | assert: 34 | that: 35 | - testout_1.state == 'running' 36 | - testout_1.rc == 0 37 | - testout_1.msg == "IBM MQ queue manager 'qm2_all' running." 38 | fail_msg: '<> {{testout_1.msg}}' 39 | success_msg: '<> {{testout_1.msg}}' 40 | 41 | - name: Can stop when present 42 | queue_manager: 43 | qmname: ALL_QMGRS 44 | state: stopped 45 | register: testout_2 46 | failed_when: false 47 | 48 | - name: Dump stop output 49 | debug: 50 | msg: "{{ testout_2 }}" 51 | 52 | - name: Test stop output 53 | assert: 54 | that: 55 | - testout_2.state == 'stopped' 56 | - testout_2.rc == 0 57 | - testout_2.msg == "Quiesce request accepted. The queue manager will stop when all outstanding work\nis complete.\n" 58 | fail_msg: '<> {{testout_2.msg}}' 59 | success_msg: '<> {{testout_2.msg}}' 60 | 61 | - name: Can delete when present 62 | queue_manager: 63 | qmname: ALL_QMGRS 64 | state: absent 65 | register: testout_3 66 | failed_when: false 67 | 68 | - name: Dump delete output 69 | debug: 70 | msg: "{{ testout_3 }}" 71 | 72 | - name: Test delete output 73 | assert: 74 | that: 75 | - testout_3.state == 'absent' 76 | - testout_3.rc == 0 77 | - testout_3.msg == "IBM MQ queue manager 'qm2_all' deleted." 78 | fail_msg: '<> {{testout_3.msg}}' 79 | success_msg: '<> {{testout_3.msg}}' 80 | -------------------------------------------------------------------------------- /tests/playbooks/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | host_key_checking = false 3 | roles_path = ../../roles -------------------------------------------------------------------------------- /tests/playbooks/main_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: MQ-Ansible testing framework 3 | hosts: all 4 | 5 | - name: Testing - Windows 6 | import_playbook: tests_windows.yml 7 | when: ansible_facts['os_family'] == "Windows" 8 | 9 | - name: Testing - Ubuntu, RedHat, AIX 10 | import_playbook: tests_unix_based.yml 11 | when: (ansible_facts['os_family'] == "RedHat") or (ansible_facts['os_family'] == "AIX" ) or (ansible_facts['distribution'] == "Ubuntu") 12 | 13 | -------------------------------------------------------------------------------- /tests/playbooks/mqsc_display: -------------------------------------------------------------------------------- 1 | DISPLAY QMGR QMNAME -------------------------------------------------------------------------------- /tests/playbooks/test_windows_install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Test downloading and installing MQ - Windows 4 | hosts: all 5 | become: false 6 | 7 | tasks: 8 | 9 | - name: Test MQ download zip exists 10 | ansible.windows.win_stat: 11 | path: C:\Users\Administrator\mq.zip 12 | register: mq_zip 13 | failed_when: mq_zip.stat.exists == false 14 | 15 | - name: Test MQ unzipped file exists 16 | ansible.windows.win_stat: 17 | path: C:\Users\Administrator\mq-install\MQServer 18 | register: mq_unzipped 19 | failed_when: mq_unzipped.stat.exists == false 20 | 21 | - name: Get groups 22 | ansible.windows.win_shell: Get-LocalGroup 23 | register: windows_groups 24 | changed_when: false 25 | 26 | - name: Test if mqm group exists 27 | ansible.builtin.assert: 28 | that: 29 | - "'mqm' in windows_groups.stdout" 30 | fail_msg: "<> mqm group does not exist." 31 | success_msg: "<> mqm group exists." 32 | 33 | - name: Get users 34 | ansible.windows.win_shell: Get-LocalUser 35 | register: windows_users 36 | changed_when: false 37 | 38 | - name: Test if mqmuser exists 39 | ansible.builtin.assert: 40 | that: 41 | - "'mqmuser' in windows_users.stdout" 42 | fail_msg: "<> mqm user does not exist." 43 | success_msg: "<> mqm user exists." 44 | 45 | - name: Get MQ version 46 | ansible.windows.win_command: dspmqver 47 | register: dspmqver_results 48 | changed_when: false 49 | 50 | - name: Test MQ version 51 | ansible.builtin.assert: 52 | that: 53 | - "'Version: 9.3.0.0' in dspmqver_results.stdout_lines" 54 | fail_msg: "<> incorrect MQ version." 55 | success_msg: "<> correct MQ version" 56 | 57 | 58 | -------------------------------------------------------------------------------- /tests/playbooks/test_windows_webconsole.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Test configuration and start of web console - Windows 4 | hosts: all 5 | become: false 6 | 7 | tasks: 8 | 9 | - name: test that existing config file is mqwebuser.xml 10 | ansible.windows.win_stat: 11 | path: C:\ProgramData\IBM\MQ\web\installations\Installation1\servers\mqweb\mqwebuser.xml 12 | register: mqwebuser 13 | failed_when: mqwebuser.stat.exists == false 14 | 15 | # - name: test that web console is configured for remote connections 16 | 17 | - name: display web console status 18 | ansible.windows.win_command: 19 | cmd: .\dspmqweb.bat 20 | chdir: C:\Program Files\IBM\MQ\bin 21 | register: webconsole_status 22 | changed_when: false 23 | ignore_errors: true 24 | 25 | - name: test web console is running 26 | ansible.builtin.assert: 27 | that: '" is running." in webconsole_status.stdout' 28 | fail_msg: "<> MQ web console is not running." 29 | success_msg: "<> MQ web console running" 30 | -------------------------------------------------------------------------------- /tests/playbooks/tests_unix_based.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Testing - Ubuntu, RedHat, AIX 3 | hosts: all 4 | 5 | - name: Test install - Ubuntu, RedHat, AIX 6 | import_playbook: 1_test_install.yml 7 | 8 | - name: Set up for testing 9 | import_playbook: 2_setup_test.yml 10 | 11 | # - name: Test queue manager module functionalities 12 | - name: Test absent queue manager 13 | import_playbook: 3_test_absent_qmgr.yml 14 | 15 | - name: Test present queue manager 16 | import_playbook: 4_test_present_qmgr.yml 17 | 18 | - name: Test running queue manager 19 | import_playbook: 5_test_running_qmgr.yml 20 | 21 | - name: Test queue manager (miscellaneous) 22 | import_playbook: 6_test_misc.yml 23 | 24 | - name: Test web console 25 | import_playbook: 7_test_web_console.yml 26 | 27 | - name: Clean up after testing 28 | import_playbook: 8_cleanup_test.yml 29 | 30 | - name: Test ALL_QMGRS 31 | import_playbook: 9_test_all_qmgrs.yml -------------------------------------------------------------------------------- /tests/playbooks/tests_windows.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Testing - Windows 3 | hosts: all 4 | 5 | - name: Test install - Windows 6 | import_playbook: test_windows_install.yml 7 | 8 | - name: Test web console 9 | import_playbook: test_windows_webconsole.yml 10 | -------------------------------------------------------------------------------- /tests/unit/test_queue_manager.py: -------------------------------------------------------------------------------- 1 | import json 2 | import unittest 3 | 4 | from ansible.module_utils import basic 5 | from ansible.module_utils.common.text.converters import to_bytes 6 | from ansible_collections.ibm.ibmmq.library import queue_manager 7 | 8 | # Ideal final solution: We'd like to import this way but neither these nor "units.compat" 9 | # can find the ansible test directory. Right now, just use the code below 10 | # 11 | # We might not actually need all these modules but if we need them, setting up the 12 | # environment properly may require the env-setup.sh file. 13 | # from ansible.test.units.compat import unittest 14 | # from ansible.test.units.compat.mock import patch 15 | from unittest.mock import patch 16 | 17 | 18 | def set_module_args(args): 19 | """prepare arguments so that they will be picked up during module creation""" 20 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 21 | basic._ANSIBLE_ARGS = to_bytes(args) 22 | 23 | 24 | class AnsibleExitJson(Exception): 25 | """Exception class to be raised by module.exit_json and caught by the test case""" 26 | pass 27 | 28 | 29 | class AnsibleFailJson(Exception): 30 | """Exception class to be raised by module.fail_json and caught by the test case""" 31 | pass 32 | 33 | 34 | def exit_json(*args, **kwargs): 35 | """function to patch over exit_json; package return data into an exception""" 36 | if 'changed' not in kwargs: 37 | kwargs['changed'] = False 38 | raise AnsibleExitJson(kwargs) 39 | 40 | 41 | def fail_json(*args, **kwargs): 42 | """function to patch over fail_json; package return data into an exception""" 43 | kwargs['failed'] = True 44 | raise AnsibleFailJson(kwargs) 45 | 46 | 47 | class TestQueueManager(unittest.TestCase): 48 | 49 | def setUp(self): 50 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 51 | exit_json=exit_json, 52 | fail_json=fail_json, 53 | ) 54 | self.mock_module_helper.start() 55 | self.addCleanup(self.mock_module_helper.stop) 56 | 57 | def test_module_fail_when_required_args_missing(self): 58 | with self.assertRaises(AnsibleFailJson): 59 | set_module_args({}) 60 | queue_manager.main() 61 | 62 | def test_module_fail_when_name_missing(self): 63 | with self.assertRaises(AnsibleFailJson): 64 | set_module_args({ 65 | 'state': 'test' 66 | }) 67 | queue_manager.main() 68 | 69 | def test_module_fail_when_state_missing(self): 70 | with self.assertRaises(AnsibleFailJson): 71 | set_module_args({ 72 | 'qmname': 'qm1' 73 | }) 74 | queue_manager.main() 75 | 76 | def test_create_qm(self): 77 | set_module_args({ 78 | 'qmname': 'qm1', 79 | 'state': 'present', 80 | 'description': 'testing', 81 | 'unit_test': True 82 | }) 83 | with self.assertRaises(AnsibleExitJson) as result: 84 | queue_manager.main() 85 | self.assertEquals(result.exception.args[0]['state'], 'present') 86 | 87 | def test_delete_qm(self): 88 | set_module_args({ 89 | 'qmname': 'qm1', 90 | 'state': 'absent', 91 | 'description': 'testing', 92 | 'unit_test': True 93 | }) 94 | with self.assertRaises(AnsibleExitJson) as result: 95 | queue_manager.main() 96 | self.assertEquals(result.exception.args[0]['state'], 'absent') 97 | self.assertEquals(result.exception.args[0]['msg'], 'IBM MQ queue manager deleted.') 98 | 99 | def test_start_qmgr(self): 100 | set_module_args({ 101 | 'qmname': 'qm1', 102 | 'state': 'running', 103 | 'description': 'testing', 104 | 'unit_test': True 105 | }) 106 | with self.assertRaises(AnsibleExitJson) as result: 107 | queue_manager.main() 108 | self.assertEquals(result.exception.args[0]['state'], 'running') 109 | self.assertEquals(result.exception.args[0]['msg'], 'IBM MQ queue manager \'qm1\' started') 110 | self.assertEquals(result.exception.args[0]['rc'], 0) 111 | 112 | def test_runmqsc_on_qmgr(self): 113 | set_module_args({ 114 | 'qmname': 'qm1', 115 | 'state': 'present', 116 | 'description': 'testing', 117 | 'mqsc_file': 'testing_file', 118 | 'unit_test': True 119 | }) 120 | with self.assertRaises(AnsibleExitJson) as result: 121 | queue_manager.main() 122 | self.assertEquals(result.exception.args[0]['state'], 'present') 123 | self.assertEquals(result.exception.args[0]['msg'], 'runmqsc command ran successfully') 124 | self.assertEquals(result.exception.args[0]['rc'], 0) 125 | -------------------------------------------------------------------------------- /tmp/args.json: -------------------------------------------------------------------------------- 1 | { 2 | "ANSIBLE_MODULE_ARGS": { 3 | "qmname": "qm1", 4 | "state": "started" 5 | } 6 | } --------------------------------------------------------------------------------