├── .ansible-lint ├── .github ├── CODEOWNERS ├── Contributers_guide.md ├── ISSUE_TEMPLATE │ ├── ask-a-question.md │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── pull_request_template.md └── workflows │ └── ansible-test.yml ├── .gitignore ├── CHANGELOG.rst ├── LICENSE ├── README.md ├── catalog-info.yaml ├── changelogs ├── changelog.yaml └── config.yaml ├── codecov.yml ├── docs ├── ADOPTERS.md ├── ATTRIBUTION.md ├── BRANCHING.md ├── CODE_OF_CONDUCT.md ├── COMMITTER_GUIDE.md ├── CONTRIBUTING.md ├── INSTALLATION.md ├── ISSUE_TRIAGE.md ├── MAINTAINERS.md ├── MAINTAINER_GUIDE.md ├── RELEASE_NOTES.md ├── SECURITY.md ├── SUPPORT.md └── modules │ ├── accesszone.rst │ ├── ads.rst │ ├── alert_channel.rst │ ├── alert_rule.rst │ ├── alert_settings.rst │ ├── filepoolpolicy.rst │ ├── filesystem.rst │ ├── group.rst │ ├── groupnet.rst │ ├── info.rst │ ├── ldap.rst │ ├── networkpool.rst │ ├── networkrule.rst │ ├── networksettings.rst │ ├── nfs.rst │ ├── nfs_alias.rst │ ├── nfs_default_settings.rst │ ├── nfs_global_settings.rst │ ├── nfs_zone_settings.rst │ ├── node.rst │ ├── role.rst │ ├── s3_bucket.rst │ ├── server_certificate.rst │ ├── settings.rst │ ├── smartpoolsettings.rst │ ├── smartquota.rst │ ├── smb.rst │ ├── smb_file.rst │ ├── smb_global_settings.rst │ ├── snapshot.rst │ ├── snapshotschedule.rst │ ├── snmp_settings.rst │ ├── storagepooltier.rst │ ├── subnet.rst │ ├── support_assist.rst │ ├── synciq_global_settings.rst │ ├── synciqcertificate.rst │ ├── synciqjob.rst │ ├── synciqpolicy.rst │ ├── synciqreports.rst │ ├── synciqrules.rst │ ├── synciqtargetreports.rst │ ├── user.rst │ ├── user_mapping_rule.rst │ └── writable_snapshots.rst ├── galaxy.yml ├── meta ├── execution-environment.yml └── runtime.yml ├── playbooks └── modules │ ├── accesszone.yml │ ├── ads.yml │ ├── alert_channel.yml │ ├── alert_rule.yml │ ├── alert_settings.yml │ ├── filepoolpolicy.yml │ ├── filesystem.yml │ ├── group.yml │ ├── groupnet.yml │ ├── info.yml │ ├── ldap.yml │ ├── networkpool.yml │ ├── networkrule.yml │ ├── networksettings.yml │ ├── nfs.yml │ ├── nfs_alias.yml │ ├── nfs_default_settings.yml │ ├── nfs_global_settings.yml │ ├── nfs_zone_settings.yml │ ├── node.yml │ ├── role.yml │ ├── s3_bucket.yml │ ├── server_certificate.yml │ ├── settings.yml │ ├── smartpoolsettings.yml │ ├── smartquota.yml │ ├── smb.yml │ ├── smb_file.yml │ ├── smb_global_settings.yml │ ├── snapshot.yml │ ├── snapshotschedule.yml │ ├── snmp_settings.yml │ ├── storagepooltier.yml │ ├── subnet.yml │ ├── support_assist.yml │ ├── synciq_global_settings.yml │ ├── synciqcertificate.yml │ ├── synciqjobs.yml │ ├── synciqpolicy.yml │ ├── synciqreports.yml │ ├── synciqrules.yml │ ├── synciqtargetreports.yml │ ├── user.yml │ ├── user_mapping_rules.yml │ └── writable_snapshots.yml ├── plugins ├── doc_fragments │ └── powerscale.py ├── module_utils │ └── storage │ │ └── dell │ │ ├── __init__.py │ │ ├── logging_handler.py │ │ ├── nwpool_utils.py │ │ ├── shared_library │ │ ├── __init__.py │ │ ├── auth.py │ │ ├── certificate.py │ │ ├── cluster.py │ │ ├── events.py │ │ ├── namespace.py │ │ ├── powerscale_base.py │ │ ├── protocol.py │ │ ├── quota.py │ │ ├── snapshot.py │ │ ├── support_assist.py │ │ ├── synciq.py │ │ └── zones_summary.py │ │ └── utils.py └── modules │ ├── accesszone.py │ ├── ads.py │ ├── alert_channel.py │ ├── alert_rule.py │ ├── alert_settings.py │ ├── filepoolpolicy.py │ ├── filesystem.py │ ├── group.py │ ├── groupnet.py │ ├── info.py │ ├── ldap.py │ ├── networkpool.py │ ├── networkrule.py │ ├── networksettings.py │ ├── nfs.py │ ├── nfs_alias.py │ ├── nfs_default_settings.py │ ├── nfs_global_settings.py │ ├── nfs_zone_settings.py │ ├── node.py │ ├── role.py │ ├── s3_bucket.py │ ├── server_certificate.py │ ├── settings.py │ ├── smartpoolsettings.py │ ├── smartquota.py │ ├── smb.py │ ├── smb_file.py │ ├── smb_global_settings.py │ ├── snapshot.py │ ├── snapshotschedule.py │ ├── snmp_settings.py │ ├── storagepooltier.py │ ├── subnet.py │ ├── support_assist.py │ ├── synciq_global_settings.py │ ├── synciqcertificate.py │ ├── synciqjob.py │ ├── synciqpolicy.py │ ├── synciqreports.py │ ├── synciqrules.py │ ├── synciqtargetreports.py │ ├── user.py │ ├── user_mapping_rule.py │ └── writable_snapshots.py ├── requirements.txt ├── requirements.yml └── tests ├── config.yml └── unit ├── __init__.py ├── plugins ├── __init__ ├── __init__.py ├── module_utils │ ├── mock_accesszone_api.py │ ├── mock_ads_api.py │ ├── mock_alert_channel_api.py │ ├── mock_alert_rule_api.py │ ├── mock_alert_settings_api.py │ ├── mock_api_exception.py │ ├── mock_filepoolpolicy_api.py │ ├── mock_filesystem_api.py │ ├── mock_group_api.py │ ├── mock_groupnet_api.py │ ├── mock_info_api.py │ ├── mock_ldap_api.py │ ├── mock_networkpool_api.py │ ├── mock_networkrule_api.py │ ├── mock_networksettings_api.py │ ├── mock_nfs_alias_api.py │ ├── mock_nfs_export_api.py │ ├── mock_nfs_global_settings_api.py │ ├── mock_nfs_zone_settings.py │ ├── mock_nfsdefaultsettings_api.py │ ├── mock_node_api.py │ ├── mock_role_api.py │ ├── mock_s3_bucket_api.py │ ├── mock_sdk_response.py │ ├── mock_server_certificate_api.py │ ├── mock_settings_api.py │ ├── mock_smartpoolsettings_api.py │ ├── mock_smartquota_api.py │ ├── mock_smb_api.py │ ├── mock_smb_file_api.py │ ├── mock_smb_global_settings_api.py │ ├── mock_snapshot_api.py │ ├── mock_snmp_settings_api.py │ ├── mock_storagepooltier_api.py │ ├── mock_subnet_api.py │ ├── mock_support_assist_api.py │ ├── mock_synciq_global_settings_api.py │ ├── mock_synciqcertificate_api.py │ ├── mock_synciqjob_api.py │ ├── mock_synciqpolicy_api.py │ ├── mock_user_api.py │ ├── mock_usermappingrules_api.py │ ├── mock_writable_snapshots_api.py │ ├── shared_library │ │ ├── __init__.py │ │ ├── initial_mock.py │ │ └── powerscale_unit_base.py │ └── test_utils.py └── modules │ ├── __init__ │ ├── __init__.py │ ├── test_accesszone.py │ ├── test_ads.py │ ├── test_alert_channel.py │ ├── test_alert_rule.py │ ├── test_alert_settings.py │ ├── test_filepoolpolicy.py │ ├── test_filesystem.py │ ├── test_group.py │ ├── test_groupnet.py │ ├── test_info.py │ ├── test_ldap.py │ ├── test_networkpool.py │ ├── test_networkrule.py │ ├── test_networksettings.py │ ├── test_nfs.py │ ├── test_nfs_alias.py │ ├── test_nfs_global_settings.py │ ├── test_nfs_zone_settings.py │ ├── test_nfsdefaultsettings.py │ ├── test_node.py │ ├── test_role.py │ ├── test_s3_bucket.py │ ├── test_server_certificate.py │ ├── test_settings.py │ ├── test_smartpoolsettings.py │ ├── test_smartquota.py │ ├── test_smb.py │ ├── test_smb_file.py │ ├── test_smb_global_settings.py │ ├── test_snapshot.py │ ├── test_snmp_settings.py │ ├── test_storagepooltier.py │ ├── test_subnet.py │ ├── test_support_assist.py │ ├── test_synciq_global_settings.py │ ├── test_synciqcertificate.py │ ├── test_synciqjob.py │ ├── test_synciqpolicy.py │ ├── test_user.py │ ├── test_usermappingrules.py │ └── test_writable_snapshots.py └── requirements.txt /.ansible-lint: -------------------------------------------------------------------------------- 1 | exclude_paths: 2 | - .github/ 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODEOWNERS 2 | # 3 | # documentation for this file can be found at: 4 | # https://help.github.com/en/articles/about-code-owners 5 | 6 | # These are the default owners for the code and will 7 | # be requested for review when someone opens a pull request. 8 | # order is alphabetical for easier maintenance. 9 | # 10 | # Bhavneet Sharma (Bhavneet-Sharma) 11 | # Meenakshi Dembi (meenakshidembi691) 12 | # Trisha Datta (trisha-dell) 13 | # Forrest Xia (forrestxia) 14 | # Yiming Bao (baoy1) 15 | # Tao He (taohe1012) 16 | # Peter Cao (P-Cao) 17 | # Haiming Tan (tanh17) 18 | # Ray Liu (RayLiu7) 19 | # Luis Liu (vangork) 20 | 21 | # for all files: 22 | * @Bhavneet-Sharma @meenakshidembi691 @trisha-dell @forrestxia @baoy1 @taohe1012 @P-Cao @tanh17 @RayLiu7 @vangork 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ask-a-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask a question 3 | about: Ask a question. 4 | title: "[QUESTION]:" 5 | labels: type/question 6 | assignees: '' 7 | 8 | --- 9 | ### How can the Team help you today? 10 | 11 | **Details: ?** 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]:" 5 | labels: type/bug, needs-triage 6 | assignees: '' 7 | 8 | --- 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 1. Step 1 ... 15 | 2. Step 2 ... 16 | 3. Step 3 ... 17 | ... 18 | n. Step n See error 19 | 20 | **Expected behavior** 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. 25 | 26 | **Logs** 27 | If applicable, submit logs or stack traces from the affected services 28 | 29 | **System Information (please complete the following information):** 30 | - OS/Version: [e.g. RHEL 7.6] 31 | - Ansible Version [e.g. 2.12] 32 | - Python Version [e.g. 3.9] 33 | - Additional Information... 34 | 35 | **Additional context** 36 | Add any other context about the problem here. 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ansible mailing list 4 | alias: ansible.team@dell.com 5 | about: Please ask and answer usage questions and report security issues here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]:" 5 | labels: type/feature-request, needs-triage 6 | assignees: '' 7 | 8 | --- 9 | **Describe the solution you'd like** 10 | A clear and concise description of what you want to happen. 11 | 12 | **Describe alternatives you've considered** 13 | A clear and concise description of any alternative solutions or features you've considered. 14 | 15 | **Additional context** 16 | Add any other context or screenshots about the feature request here. 17 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | A few sentences describing the overall goals of the pull request's commits. 3 | 4 | # GitHub Issues 5 | List the GitHub issues impacted by this PR: 6 | 7 | | GitHub Issue # | 8 | | -------------- | 9 | | | 10 | 11 | # Checklist: 12 | 13 | - [ ] I have performed a self-review of my own code to ensure there are no formatting, pep8, linting, or security issues 14 | - [ ] I have performed Ansible Sanity test using --docker default 15 | - [ ] I have verified that new and existing unit tests pass locally with my changes 16 | - [ ] I have not allowed coverage numbers to degenerate 17 | - [ ] I have maintained at least 90% code coverage 18 | - [ ] I have commented my code, particularly in hard-to-understand areas 19 | - [ ] I have made corresponding changes to the documentation 20 | - [ ] I have added tests that prove my fix is effective or that my feature works 21 | - [ ] Backward compatibility is not broken 22 | 23 | # How Has This Been Tested? 24 | Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration 25 | 26 | - [ ] Test A 27 | - [ ] Test B 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | test.py 3 | .env 4 | .coverage 5 | output 6 | __pycache__/ 7 | *.log 8 | dellemc-powerscale*.tar.gz 9 | -------------------------------------------------------------------------------- /catalog-info.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # nonk8s 3 | apiVersion: backstage.io/v1alpha1 4 | kind: Component 5 | metadata: 6 | name: dell-ansible-powerscale 7 | description: "PowerScale (Isilon) Ansible modules" 8 | tags: 9 | - ansible 10 | - automation 11 | - storage 12 | - isilon 13 | - onefs 14 | - dellemc 15 | - powerscale 16 | annotations: 17 | backstage.io/techdocs-ref: dir:. 18 | github.com/project-slug: dell/ansible-powerscale 19 | links: 20 | - url: 'https://galaxy.ansible.com/dellemc/powerscale' 21 | title: 'Ansible Galaxy' 22 | icon: 'web' 23 | - url: 'https://console.redhat.com/ansible/automation-hub/repo/published/dellemc/powerscale' 24 | title: 'Automation Hub' 25 | icon: 'web' 26 | - url: 'https://github.com/dell/ansible-powerscale/issues' 27 | title: 'Contact Technical Support' 28 | icon: 'help' 29 | spec: 30 | type: service 31 | lifecycle: production 32 | owner: user:default/gokul-srivathsan 33 | visibility: all 34 | -------------------------------------------------------------------------------- /changelogs/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | changelog_filename_template: ../CHANGELOG.rst 3 | changelog_filename_version_depth: 0 4 | changes_file: changelog.yaml 5 | changes_format: combined 6 | ignore_other_fragment_extensions: true 7 | keep_fragments: false 8 | mention_ancestor: true 9 | new_plugins_after_name: removed_features 10 | notesdir: fragments 11 | prelude_section_name: release_summary 12 | prelude_section_title: Release Summary 13 | sanitize_changelog: true 14 | sections: 15 | - - major_changes 16 | - Major Changes 17 | - - minor_changes 18 | - Minor Changes 19 | - - breaking_changes 20 | - Breaking Changes / Porting Guide 21 | - - deprecated_features 22 | - Deprecated Features 23 | - - removed_features 24 | - Removed Features (previously deprecated) 25 | - - security_fixes 26 | - Security Fixes 27 | - - bugfixes 28 | - Bugfixes 29 | - - known_issues 30 | - Known Issues 31 | title: Dellemc.Powerscale 32 | trivial_section_name: trivial 33 | use_fqcn: true 34 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - "/ansible_collections/dellemc/powerscale/::" 4 | -------------------------------------------------------------------------------- /docs/ADOPTERS.md: -------------------------------------------------------------------------------- 1 | # List of adopters 2 | -------------------------------------------------------------------------------- /docs/ATTRIBUTION.md: -------------------------------------------------------------------------------- 1 | OpenSource Licenses for Dell PowerScale Ansible Modules 2 | ======================================================================= 3 | 4 | *** 5 | Package: Python SDK for Dell PowerScale. 6 | Version: 0.3.0.1 7 | Copyright: Copyright (c) 2018 Dell EMC Isilon. 8 | License: [MIT](https://github.com/Isilon/isilon_sdk_python/blob/d079c07611b5b43206f7f167d3c059b880ab3e50/isilon_sdk/setup.py#L33C5-L33C19) 9 | Repository: "https://github.com/Isilon/isilon_sdk_python" 10 | 11 | *** -------------------------------------------------------------------------------- /docs/BRANCHING.md: -------------------------------------------------------------------------------- 1 | # Branching strategy 2 | 3 | Ansible modules for Dell PowerScale follows a scaled trunk branching strategy where short-lived branches are created off of the main branch. When coding is complete, the branch is merged back into main after being approved in a pull request code review. 4 | 5 | ## Branch naming convention 6 | 7 | | Branch Type | Example | Comment | 8 | |--------------|-----------------------------------|-------------------------------------------| 9 | | main | main | | 10 | | Release | release-1.0 | hotfix: release-1.1 patch: release-1.0.1 | 11 | | Feature | feature-9-vol-support | "9" referring to GitHub issue ID | 12 | | Bug Fix | bugfix-110-fix-duplicates-issue | "110" referring to GitHub issue ID | 13 | 14 | 15 | ## Steps for working on a release branch 16 | 17 | 1. Fork the repository. 18 | 2. Create a branch off of the main branch. The branch name should follow [branch naming convention](#branch-naming-convention). 19 | 3. Make your changes and commit them to your branch. 20 | 4. If other code changes have merged into the upstream main branch, perform a rebase of those changes into your branch. 21 | 5. Open a [pull request](https://github.com/dell/ansible-powerscale/pulls) between your branch and the upstream main branch. 22 | 6. Once your pull request has merged, your branch can be deleted. 23 | -------------------------------------------------------------------------------- /docs/COMMITTER_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Committer guidelines 2 | 3 | These are the guidelines for people with commit privileges on the GitHub repository. Committers act as members of the Core Team and not necessarily employees of Dell. 4 | 5 | These guidelines apply to everyone and as Committers you have been given access to commit changes because you exhibit good judgment and have demonstrated your commitment to the vision of the project. We trust that you will use these privileges wisely and not abuse it. 6 | 7 | If these privileges are abused in any way and the quality of the project is compromised, our trust will be diminished and you may be asked to not commit or lose these privileges all together. 8 | 9 | ## General rules 10 | 11 | ### Don't 12 | 13 | * Break the build. 14 | * Commit directly. 15 | * Compromise backward compatibility. 16 | * Disrespect your Community Team members. Help them grow. 17 | * Think it is someone elses job to test your code. Write tests for all the code you produce. 18 | * Forget to keep thing simple. 19 | * Create technical debt. Fix-in-place and make it the highest priority above everything else. 20 | 21 | ### Do 22 | 23 | * Keep it simple. 24 | * Good work, your best every time. 25 | * Keep the design of your software clean and maintainable. 26 | * Squash your commits, avoid merges. 27 | * Be active. Committers that are not active may have their permissions suspended. 28 | * Write tests for all your deliverables. 29 | * Automate everything. 30 | * Maintain a high code coverage. 31 | * Keep an open communication with other Committers. 32 | * Ask questions. 33 | * Document your contributions and remember to keep it simple. 34 | 35 | ## People 36 | 37 | | Name | GitHub ID | Nickname | 38 | |-------|-------------|------------| 39 | | | | | 40 | -------------------------------------------------------------------------------- /docs/INSTALLATION.md: -------------------------------------------------------------------------------- 1 | # Installation and execution of Ansible modules for Dell PowerScale 2 | 3 | ## Installation of sdk 4 | Use this procedure to install SDK: 5 | 6 | pip install isilon-sdk 7 | 8 | ## Building collections 9 | 1. Use this command to build the collection from source code: 10 | 11 | ansible-galaxy collection build 12 | 13 | For more details on how to build a tar ball, please refer: [Building the collection](https://docs.ansible.com/ansible/latest/dev_guide/developing_collections_distributing.html#building-your-collection-tarball) 14 | 15 | 16 | ## Installing collections 17 | #### Online installation of collections 18 | 1. Use this command to install the latest collection hosted in galaxy: 19 | 20 | ansible-galaxy collection install dellemc.powerscale -p 21 | 22 | #### Offline installation of collections 23 | 1. Download the latest tar build from either of the available distribution channels [Ansible Galaxy](https://galaxy.ansible.com/dellemc/powerscale) /[Automation Hub](https://console.redhat.com/ansible/automation-hub/repo/published/dellemc/powerscale) and use this command to install the collection anywhere in your system: 24 | 25 | ansible-galaxy collection install dellemc-powerscale-3.8.1.tar.gz -p 26 | 27 | 2. Set the environment variable: 28 | 29 | export ANSIBLE_COLLECTIONS_PATHS=$ANSIBLE_COLLECTIONS_PATHS: 30 | 31 | ## Using collections 32 | 33 | * In order to use any Ansible module, ensure that the importing of proper FQCN (Fully Qualified Collection Name) must be embedded in the playbook. 34 | Refer to this example: 35 | 36 | collections: 37 | - dellemc.powerscale 38 | 39 | * In order to use an installed collection specific to the task use a proper FQCN (Fully Qualified Collection Name). Refer to this example: 40 | 41 | tasks: 42 | - name: Get filesystem details 43 | dellemc.powerscale.filesystem 44 | 45 | * For generating Ansible documentation for a specific module, embed the FQCN before the module name. Refer to this example: 46 | 47 | ansible-doc dellemc.powerscale.info 48 | 49 | 50 | ## Ansible modules execution 51 | 52 | The Ansible server must be configured with Python library for OneFS to run the Ansible playbooks. The [Documents](https://github.com/dell/ansible-powerscale/blob/main/docs) provide information on different Ansible modules along with their functions and syntax. The parameters table in the Product Guide provides information on various parameters which need to be configured before running the modules. 53 | 54 | ## SSL certificate validation 55 | 56 | * Export the SSL certificate using KeyStore Explorer tool or from the browser in .crt format. 57 | * Append the SSL certificate to the Certifi package file cacert.pem. 58 | * For Python 3.6 : cat <> >> /usr/local/lib/python3.6/dist-packages/certifi/cacert.pem 59 | 60 | ## Results 61 | Each module returns the updated state and details of the entity. 62 | For example, if you are using the group module, all calls will return the updated details of the group. 63 | Sample result is shown in each module's documentation. 64 | 65 | ## Idempotency 66 | The modules are written in such a way that all requests are idempotent and hence fault-tolerant. It essentially means that the result of a successfully performed request is independent of the number of times it is executed. 67 | 68 | ## Ansible execution environment 69 | 70 | Ansible can also be installed in a container environment. Ansible Builder provides the ability to create reproducible, self-contained environments as container images that can be run as Ansible execution environments. 71 | * Install the ansible builder package using: 72 | 73 | pip3 install ansible-builder 74 | 75 | * Ensure the execution-environment.yml is at the root of collection and create the execution environment using: 76 | 77 | ansible-builder build --tag --container-runtime docker 78 | 79 | * After the image is built, run the container using: 80 | 81 | docker run -it /bin/bash 82 | 83 | * Verify collection installation using command: 84 | 85 | ansible-galaxy collection list 86 | 87 | * The playbook can be run on the container using: 88 | 89 | docker run --rm -v $(pwd):/runner ansible-playbook info_tests.yml 90 | -------------------------------------------------------------------------------- /docs/MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # Maintainers 2 | 3 | * Ananthu Kuttattu (kuttattz) 4 | * Bhavneet Sharma (Bhavneet-Sharma) 5 | * Jennifer John (Jennifer-John) 6 | * Meenakshi Dembi (meenakshidembi691) 7 | * Pavan Mudunuri (Pavan-Mudunuri) 8 | * Trisha Datta (trisha-dell) 9 | * Sachin Apagundi (sachin-apa) 10 | * Felix Stephen (felixs88) 11 | -------------------------------------------------------------------------------- /docs/MAINTAINER_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Maintainer guidelines 2 | 3 | As a Maintainer of this project you have the responsibility of keeping true to the vision of the project with a high-degree quality. Being part of this group is a privilege that requires dedication and time to attend to the daily activities that are associated with the maintenance of this project. 4 | 5 | ## Becoming a maintainer 6 | 7 | Most Maintainers started as Contributors that have demonstrated their commitment to the success of the project. Contributors wishing to become Maintainers, must demonstrate commitment to the success of the project by contributing code, reviewing others' work, and triaging issues on a regular basis for at least three months. 8 | 9 | The contributions alone don't make you a Maintainer. You need to earn the trust of the current Maintainers and other project Contributors, that your decisions and actions are in the best interest of the project. 10 | 11 | Periodically, the existing Maintainers curate a list of Contributors who have shown regular activity on the project over the prior months. It is from this list that Maintainer candidates are selected. 12 | 13 | After a candidate is selected, the existing Maintainers discuss the candidate over the next 5 business days, provide feedback, and vote. At least 75% of the current Maintainers must vote in the affirmative for a candidate to be moved to the role of Maintainer. 14 | 15 | If a candidate is approved, a Maintainer contacts the candidate to invite them to open a pull request that adds the contributor to the MAINTAINERS file. The candidate becomes a Maintainer once the pull request is merged. 16 | 17 | ## Maintainer policies 18 | 19 | * Lead by example 20 | * Follow the [Code of Conduct](https://github.com/dell/ansible-powerscale/blob/main/docs/CODE_OF_CONDUCT.md) and the guidelines in the [Contributing](https://github.com/dell/ansible-powerscale/blob/main/docs/CONTRIBUTING.md) and [Committer](https://github.com/dell/ansible-powerscale/blob/main/docs/COMMITTER_GUIDE.md) guides 21 | * Promote a friendly and collaborative environment within our community 22 | * Be actively engaged in discussions, answering questions, updating defects, and reviewing pull requests 23 | * Criticize code, not people. Ideally, tell the contributor a better way to do what they need. 24 | * Clearly mark optional suggestions as such. Best practice, start your comment with *At your option: …* 25 | 26 | ## Project decision making 27 | 28 | All project decisions should contribute to successfully executing on the project roadmap. Project milestones are established for each release. -------------------------------------------------------------------------------- /docs/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security policy 2 | 3 | The Ansible modules for Dell PowerScale repository is inspected for security vulnerabilities via blackduck scans and static code analysis. 4 | 5 | In addition to this, there are various security checks that get executed against a branch when a pull request is created/updated. Please refer to [pull request](https://github.com/dell/ansible-powerscale/blob/main/docs/CONTRIBUTING.md#Pull-requests) for more information. 6 | 7 | ## Reporting a vulnerability 8 | 9 | Have you discovered a security vulnerability in this project? 10 | We ask you to alert the maintainers by sending an email, describing the issue, impact, and fix - if applicable. 11 | 12 | You can reach the Ansible modules for Dell PowerScale maintainers at ansible.team@dell.com. 13 | -------------------------------------------------------------------------------- /docs/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | For all your support needs you can interact with us on [GitHub](https://github.com/dell/ansible-powerscale) by creating a [GitHub Issue](https://github.com/dell/ansible-powerscale/issues) or through the [Ansible Community](https://www.dell.com/community/Automation/bd-p/Automation). 4 | -------------------------------------------------------------------------------- /docs/modules/networksettings.rst: -------------------------------------------------------------------------------- 1 | .. _networksettings_module: 2 | 3 | 4 | networksettings -- Manages Network Settings on PowerScale Storage System 5 | ======================================================================== 6 | 7 | .. contents:: 8 | :local: 9 | :depth: 1 10 | 11 | 12 | Synopsis 13 | -------- 14 | 15 | Managing Network Settings on the PowerScale Storage System includes modifying and retrieving details of network settings. 16 | 17 | 18 | 19 | Requirements 20 | ------------ 21 | The below requirements are needed on the host that executes this module. 22 | 23 | - A Dell PowerScale Storage system. 24 | - Ansible-core 2.16 or later. 25 | - Python 3.10, 3.11 or 3.12. 26 | 27 | 28 | 29 | Parameters 30 | ---------- 31 | 32 | enable_source_routing (optional, bool, None) 33 | The value for enabling or disabling source based routing. 34 | 35 | 36 | state (True, str, None) 37 | State of network settings. 38 | 39 | 40 | onefs_host (True, str, None) 41 | IP address or FQDN of the PowerScale cluster. 42 | 43 | 44 | port_no (False, str, 8080) 45 | Port number of the PowerScale cluster.It defaults to 8080 if not specified. 46 | 47 | 48 | verify_ssl (True, bool, None) 49 | boolean variable to specify whether to validate SSL certificate or not. 50 | 51 | \ :literal:`true`\ - indicates that the SSL certificate should be verified. 52 | 53 | \ :literal:`false`\ - indicates that the SSL certificate should not be verified. 54 | 55 | 56 | api_user (True, str, None) 57 | username of the PowerScale cluster. 58 | 59 | 60 | api_password (True, str, None) 61 | the password of the PowerScale cluster. 62 | 63 | 64 | 65 | 66 | 67 | Notes 68 | ----- 69 | 70 | .. note:: 71 | - The \ :emphasis:`check\_mode`\ is not supported. 72 | - The modules present in this collection named as 'dellemc.powerscale' are built to support the Dell PowerScale storage platform. 73 | 74 | 75 | 76 | 77 | Examples 78 | -------- 79 | 80 | .. code-block:: yaml+jinja 81 | 82 | 83 | - name: Get Network settings 84 | dellemc.powerscale.networksettings: 85 | onefs_host: "{{onefs_host}}" 86 | api_user: "{{api_user}}" 87 | api_password: "{{api_password}}" 88 | verify_ssl: "{{verify_ssl}}" 89 | state: "{{state_present}}" 90 | 91 | - name: Enable source based routing 92 | dellemc.powerscale.networksettings: 93 | onefs_host: "{{onefs_host}}" 94 | api_user: "{{api_user}}" 95 | api_password: "{{api_password}}" 96 | verify_ssl: "{{verify_ssl}}" 97 | enable_source_routing: true 98 | state: "{{state_present}}" 99 | 100 | - name: Disable source based routing 101 | dellemc.powerscale.networksettings: 102 | onefs_host: "{{onefs_host}}" 103 | api_user: "{{api_user}}" 104 | api_password: "{{api_password}}" 105 | verify_ssl: "{{verify_ssl}}" 106 | enable_source_routing: false 107 | state: "{{state_present}}" 108 | 109 | 110 | 111 | Return Values 112 | ------------- 113 | 114 | changed (always, bool, false) 115 | Whether or not the resource has changed. 116 | 117 | 118 | network_settings (always, complex, {'settings': {'default_groupnet': 'groupnet0', 'sbr': 'false', 'sc_rebalance_delay': '0', 'tcp_ports': ['2049', '445']}}) 119 | Details of the network settings. 120 | 121 | 122 | default_groupnet (, str, ) 123 | Default client-side DNS settings for non-multitenancy aware programs. 124 | 125 | 126 | sbr (, str, ) 127 | Enable or disable source based routing. 128 | 129 | 130 | sc_rebalance_delay (, int, ) 131 | Delay in seconds for IP rebalance. 132 | 133 | 134 | tcp_ports (, list, ) 135 | List of client TCP ports. 136 | 137 | 138 | 139 | 140 | 141 | 142 | Status 143 | ------ 144 | 145 | 146 | 147 | 148 | 149 | Authors 150 | ~~~~~~~ 151 | 152 | - Meenakshi Dembi (@dembim) 153 | 154 | -------------------------------------------------------------------------------- /docs/modules/node.rst: -------------------------------------------------------------------------------- 1 | .. _node_module: 2 | 3 | 4 | node -- Get node info of PowerScale Storage System 5 | ================================================== 6 | 7 | .. contents:: 8 | :local: 9 | :depth: 1 10 | 11 | 12 | Synopsis 13 | -------- 14 | 15 | Get information of a node belonging to the PowerScale cluster. 16 | 17 | 18 | 19 | Requirements 20 | ------------ 21 | The below requirements are needed on the host that executes this module. 22 | 23 | - A Dell PowerScale Storage system. 24 | - Ansible-core 2.16 or later. 25 | - Python 3.10, 3.11 or 3.12. 26 | 27 | 28 | 29 | Parameters 30 | ---------- 31 | 32 | node_id (True, int, None) 33 | The Logical node Number of a PowerScale cluster node. 34 | 35 | 36 | state (True, str, None) 37 | Defines whether the node should exist or not. 38 | 39 | 40 | onefs_host (True, str, None) 41 | IP address or FQDN of the PowerScale cluster. 42 | 43 | 44 | port_no (False, str, 8080) 45 | Port number of the PowerScale cluster.It defaults to 8080 if not specified. 46 | 47 | 48 | verify_ssl (True, bool, None) 49 | boolean variable to specify whether to validate SSL certificate or not. 50 | 51 | \ :literal:`true`\ - indicates that the SSL certificate should be verified. 52 | 53 | \ :literal:`false`\ - indicates that the SSL certificate should not be verified. 54 | 55 | 56 | api_user (True, str, None) 57 | username of the PowerScale cluster. 58 | 59 | 60 | api_password (True, str, None) 61 | the password of the PowerScale cluster. 62 | 63 | 64 | 65 | 66 | 67 | Notes 68 | ----- 69 | 70 | .. note:: 71 | - The \ :emphasis:`check\_mode`\ is not supported. 72 | - The modules present in this collection named as 'dellemc.powerscale' are built to support the Dell PowerScale storage platform. 73 | 74 | 75 | 76 | 77 | Examples 78 | -------- 79 | 80 | .. code-block:: yaml+jinja 81 | 82 | 83 | - name: Get node info of the PowerScale cluster node 84 | dellemc.powerscale.node: 85 | onefs_host: "{{onefs_host}}" 86 | verify_ssl: "{{verify_ssl}}" 87 | api_user: "{{api_user}}" 88 | api_password: "{{api_password}}" 89 | node_id: "{{cluster_node_id}}" 90 | state: "present" 91 | 92 | 93 | 94 | Return Values 95 | ------------- 96 | 97 | changed (always, bool, false) 98 | Whether or not the resource has changed. 99 | 100 | 101 | cluster_node_details (When cluster node exists, dict, {'id': 1, 'lnn': 1, 'partitions': {'count': 1, 'partitions': [{'block_size': 1024, 'capacity': 1957516, 'component_devices': 'ada0p2', 'mount_point': '/', 'percent_used': '50%', 'statfs': {'f_namemax': 255, 'f_owner': 0, 'f_type': 53, 'f_version': 538182936}, 'used': 909066}]}}) 102 | The cluster node details. 103 | 104 | 105 | id (, int, ) 106 | Node id (device number) of a node. 107 | 108 | 109 | lnn (, int, ) 110 | Logical Node Number (LNN) of a node. 111 | 112 | 113 | partitions (, complex, ) 114 | Node partition information. 115 | 116 | 117 | count (, int, ) 118 | Count of how many partitions are included. 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | Status 127 | ------ 128 | 129 | 130 | 131 | 132 | 133 | Authors 134 | ~~~~~~~ 135 | 136 | - Ganesh Prabhu(@prabhg5) > 137 | 138 | -------------------------------------------------------------------------------- /docs/modules/smb_file.rst: -------------------------------------------------------------------------------- 1 | .. _smb_file_module: 2 | 3 | 4 | smb_file -- Manage SMB files on a PowerScale Storage System 5 | =========================================================== 6 | 7 | .. contents:: 8 | :local: 9 | :depth: 1 10 | 11 | 12 | Synopsis 13 | -------- 14 | 15 | Managing SMB files on a PowerScale Storage System includes getting details of all SMB open files and closing SMB files. 16 | 17 | 18 | 19 | Requirements 20 | ------------ 21 | The below requirements are needed on the host that executes this module. 22 | 23 | - A Dell PowerScale Storage system. 24 | - Ansible-core 2.16 or later. 25 | - Python 3.10, 3.11 or 3.12. 26 | 27 | 28 | 29 | Parameters 30 | ---------- 31 | 32 | file_id (optional, int, None) 33 | Unique id of SMB open file. Mutually exclusive with \ :emphasis:`file\_path`\ . 34 | 35 | 36 | file_path (optional, str, None) 37 | Path of SMB file. Mutually exclusive with \ :emphasis:`file\_id`\ . 38 | 39 | If file path is provided all the open file sessions in the path will be closed. 40 | 41 | 42 | state (optional, str, present) 43 | Defines the state of SMB file. 44 | 45 | \ :literal:`present`\ indicates that the SMB file should exist in system. 46 | 47 | \ :literal:`absent`\ indicates that the SMB file is closed in system. 48 | 49 | 50 | onefs_host (True, str, None) 51 | IP address or FQDN of the PowerScale cluster. 52 | 53 | 54 | port_no (False, str, 8080) 55 | Port number of the PowerScale cluster.It defaults to 8080 if not specified. 56 | 57 | 58 | verify_ssl (True, bool, None) 59 | boolean variable to specify whether to validate SSL certificate or not. 60 | 61 | \ :literal:`true`\ - indicates that the SSL certificate should be verified. 62 | 63 | \ :literal:`false`\ - indicates that the SSL certificate should not be verified. 64 | 65 | 66 | api_user (True, str, None) 67 | username of the PowerScale cluster. 68 | 69 | 70 | api_password (True, str, None) 71 | the password of the PowerScale cluster. 72 | 73 | 74 | 75 | 76 | 77 | Notes 78 | ----- 79 | 80 | .. note:: 81 | - The \ :emphasis:`check\_mode`\ is supported. 82 | - If \ :emphasis:`state`\ is \ :literal:`absent`\ , the file will be closed. 83 | - The modules present in this collection named as 'dellemc.powerscale' are built to support the Dell PowerScale storage platform. 84 | 85 | 86 | 87 | 88 | Examples 89 | -------- 90 | 91 | .. code-block:: yaml+jinja 92 | 93 | 94 | - name: Get list of SMB files of the PowerScale cluster 95 | dellemc.powerscale.smb_file: 96 | onefs_host: "{{onefs_host}}" 97 | verify_ssl: "{{verify_ssl}}" 98 | api_user: "{{api_user}}" 99 | api_password: "{{api_password}}" 100 | state: "present" 101 | 102 | - name: Close SMB file of the PowerScale cluster 103 | dellemc.powerscale.smb_file: 104 | onefs_host: "{{onefs_host}}" 105 | verify_ssl: "{{verify_ssl}}" 106 | api_user: "{{api_user}}" 107 | api_password: "{{api_password}}" 108 | file_id: xxx 109 | state: "absent" 110 | 111 | - name: Close smb file of the PowerScale cluster 112 | dellemc.powerscale.smb_file: 113 | onefs_host: "{{onefs_host}}" 114 | verify_ssl: "{{verify_ssl}}" 115 | api_user: "{{api_user}}" 116 | api_password: "{{api_password}}" 117 | file_path: "/ifs/ATest" 118 | state: "absent" 119 | 120 | 121 | 122 | Return Values 123 | ------------- 124 | 125 | changed (always, bool, false) 126 | A boolean indicating if the task had to make changes. 127 | 128 | 129 | smb_file_details (always, dict, {'smb_file_details': [{'file': 'C:\\ifs', 'id': 1370, 'locks': 0, 'permissions': ['read'], 'user': 'admin'}]}) 130 | The SMB file details. 131 | 132 | 133 | file (, str, C:\\ifs) 134 | Path of file within /ifs. 135 | 136 | 137 | id (, int, 950) 138 | The ID of the SMB open file. 139 | 140 | 141 | locks (, int, 3) 142 | The number of locks user holds on file. 143 | 144 | 145 | permissions (, list, ['read']) 146 | The user's permissions on file. 147 | 148 | 149 | user (, str, admin) 150 | User holding file open 151 | 152 | 153 | 154 | 155 | 156 | 157 | Status 158 | ------ 159 | 160 | 161 | 162 | 163 | 164 | Authors 165 | ~~~~~~~ 166 | 167 | - Pavan Mudunuri(@Pavan-Mudunuri) 168 | 169 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | ### REQUIRED 2 | --- 3 | # The namespace of the collection. 4 | # This can be a company/brand/organization or product namespace under 5 | # which all content lives. 6 | # May only contain alphanumeric lowercase characters and underscores. 7 | # Namespaces cannot start with 8 | # underscores or numbers and cannot contain consecutive underscores. 9 | namespace: dellemc 10 | 11 | # The name of the collection. 12 | # Has the same character restrictions as 'namespace' 13 | name: powerscale 14 | 15 | # The version of the collection. 16 | # Must be compatible with semantic versioning 17 | version: 3.8.1 18 | 19 | # The path to the Markdown (.md) readme file. 20 | # This path is relative to the root of the collection. 21 | readme: README.md 22 | 23 | # A list of the collection's content authors. 24 | # Can be just the name or in the format 'Full Name (url) 25 | # @nicks:irc/im.site#channel' 26 | authors: 27 | - Akash Shendge 28 | - Ambuj Dubey 29 | - Arindam Datta 30 | - Manisha Agrawal 31 | - P Srinivas Rao 32 | - Prashant Rakheja 33 | - Rajshree Khare 34 | - Ganesh Ashok Prabhu 35 | - Jennifer John 36 | - Spandita Panigrahi 37 | - Meenakshi Dembi 38 | - Trisha Datta 39 | - Bhavneet Sharma 40 | - Pavan Mudunuri 41 | - Sachin Apagundi 42 | - Kritika Bhateja 43 | 44 | ### OPTIONAL but strongly recommended 45 | 46 | # A short summary description of the collection 47 | description: Ansible modules for PowerScale 48 | 49 | # Either a single license or a list of licenses for content inside of 50 | # a collection. Ansible Galaxy currently only accepts 51 | # L(SPDX,https://spdx.org/licenses/) licenses. 52 | # This key is mutually exclusive with 'license_file' 53 | license: 54 | - GPL-3.0-or-later 55 | 56 | # A list of tags you want to associate with the collection for 57 | # indexing/searching. A tag name has the same character 58 | # requirements as 'namespace' and 'name' 59 | tags: [storage] 60 | 61 | # Collections that this collection requires to be installed for it to 62 | # be usable. The key of the dict is the collection label 'namespace.name'. 63 | # The value is a version range L(specifiers, 64 | # https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). 65 | # Multiple version range specifiers can be set and are separated by ',' 66 | dependencies: {} 67 | 68 | # The URL of the originating SCM repository 69 | repository: https://github.com/dell/ansible-powerscale/tree/main 70 | 71 | # The URL to any online docs 72 | documentation: https://github.com/dell/ansible-powerscale/tree/main/docs 73 | 74 | # The URL to the homepage of the collection/project 75 | homepage: https://github.com/dell/ansible-powerscale/tree/main 76 | 77 | # The URL to the collection issue tracker 78 | issues: https://www.dell.com/community/Automation/bd-p/Automation 79 | 80 | # A list of file glob-like patterns used to filter any files or directories 81 | # that should not be included in the build artifact. A pattern is matched from 82 | # the relative path of the file or directory of the collection directory. 83 | # This uses 'fnmatch' to match the files or directories. Some directories and 84 | # files like 'galaxy.yml', '*.pyc', '*.retry', and '.git' are always filtered 85 | build_ignore: 86 | - codecov.yml 87 | -------------------------------------------------------------------------------- /meta/execution-environment.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1 3 | dependencies: 4 | galaxy: requirements.yml 5 | python: requirements.txt 6 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | --- 2 | requires_ansible: ">=2.15.0" 3 | plugin_routing: 4 | modules: 5 | dellemc_powerscale_accesszone: 6 | tombstone: 7 | removal_date: "2024-03-25" 8 | warning_text: Use accesszone instead. 9 | dellemc_powerscale_ads: 10 | tombstone: 11 | removal_date: "2024-03-25" 12 | warning_text: Use ads instead. 13 | dellemc_powerscale_filesystem: 14 | tombstone: 15 | removal_date: "2024-03-25" 16 | warning_text: Use filesystem instead. 17 | dellemc_powerscale_group: 18 | tombstone: 19 | removal_date: "2024-03-25" 20 | warning_text: Use group instead. 21 | dellemc_powerscale_groupnet: 22 | tombstone: 23 | removal_date: "2024-03-25" 24 | warning_text: Use groupnet instead. 25 | dellemc_powerscale_gatherfacts: 26 | tombstone: 27 | removal_date: "2024-03-25" 28 | warning_text: Use info instead. 29 | dellemc_powerscale_ldap: 30 | tombstone: 31 | removal_date: "2024-03-25" 32 | warning_text: Use ldap instead. 33 | dellemc_powerscale_networkpool: 34 | tombstone: 35 | removal_date: "2024-03-25" 36 | warning_text: Use networkpool instead. 37 | dellemc_powerscale_networkrule: 38 | tombstone: 39 | removal_date: "2024-03-25" 40 | warning_text: Use networkrule instead. 41 | dellemc_powerscale_networksettings: 42 | tombstone: 43 | removal_date: "2024-03-25" 44 | warning_text: Use networksettings instead. 45 | dellemc_powerscale_nfs: 46 | tombstone: 47 | removal_date: "2024-03-25" 48 | warning_text: Use nfs instead. 49 | dellemc_powerscale_node: 50 | tombstone: 51 | removal_date: "2024-03-25" 52 | warning_text: Use node instead. 53 | dellemc_powerscale_settings: 54 | tombstone: 55 | removal_date: "2024-03-25" 56 | warning_text: Use settings instead. 57 | dellemc_powerscale_smartquota: 58 | tombstone: 59 | removal_date: "2024-03-25" 60 | warning_text: Use smartquota instead. 61 | dellemc_powerscale_smb: 62 | tombstone: 63 | removal_date: "2024-03-25" 64 | warning_text: Use smb instead. 65 | dellemc_powerscale_snapshot: 66 | tombstone: 67 | removal_date: "2024-03-25" 68 | warning_text: Use snapshot instead. 69 | dellemc_powerscale_snapshotschedule: 70 | tombstone: 71 | removal_date: "2024-03-25" 72 | warning_text: Use snapshotschedule instead. 73 | dellemc_powerscale_subnet: 74 | tombstone: 75 | removal_date: "2024-03-25" 76 | warning_text: Use subnet instead. 77 | dellemc_powerscale_synciqjob: 78 | tombstone: 79 | removal_date: "2024-03-25" 80 | warning_text: Use synciqjob instead. 81 | dellemc_powerscale_synciqpolicy: 82 | tombstone: 83 | removal_date: "2024-03-25" 84 | warning_text: Use synciqpolicy instead. 85 | dellemc_powerscale_synciqreports: 86 | tombstone: 87 | removal_date: "2024-03-25" 88 | warning_text: Use synciqreports instead. 89 | dellemc_powerscale_synciqtargetreports: 90 | tombstone: 91 | removal_date: "2024-03-25" 92 | warning_text: Use synciqtargetreports instead. 93 | dellemc_powerscale_user: 94 | tombstone: 95 | removal_date: "2024-03-25" 96 | warning_text: Use user instead. 97 | dellemc_powerscale_synciqrules: 98 | tombstone: 99 | removal_date: "2024-03-25" 100 | warning_text: Use synciqrules instead. 101 | -------------------------------------------------------------------------------- /playbooks/modules/alert_channel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Alert Channel Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "x.x.x.x" 7 | api_user: "user" 8 | api_password: "xxxx" 9 | verify_ssl: false 10 | channel_smtp: "sample_event_channel" 11 | channel_connectemc: "connect_emc_alert_channel" 12 | 13 | tasks: 14 | - name: Create the SMTP alert channel 15 | dellemc.powerscale.alert_channel: 16 | onefs_host: "{{ onefs_host }}" 17 | port_no: "{{ port_no }}" 18 | api_user: "{{ api_user }}" 19 | api_password: "{{ api_password }}" 20 | verify_ssl: "{{ verify_ssl }}" 21 | name: "{{ channel_smtp }}" 22 | enabled: true 23 | type: "smtp" 24 | allowed_nodes: 25 | - 1 26 | excluded_nodes: 27 | - 2 28 | smtp_parameters: 29 | address: 30 | - "powerscale@sample.com" 31 | send_as: "smtp_alert_channel@sample.com" 32 | subject: "SMTP event channel" 33 | smtp_host: "powerscale.sample.com" 34 | smtp_port: 25 35 | batch: "ALL" 36 | batch_period: 120 37 | smtp_use_auth: false 38 | update_password: "on_create" 39 | 40 | - name: Create the ConnectEMC channel 41 | dellemc.powerscale.alert_channel: 42 | onefs_host: "{{ onefs_host }}" 43 | port_no: "{{ port_no }}" 44 | api_user: "{{ api_user }}" 45 | api_password: "{{ api_password }}" 46 | verify_ssl: "{{ verify_ssl }}" 47 | name: "{{ channel_connectemc }}" 48 | enabled: true 49 | type: "connectemc" 50 | allowed_nodes: 51 | - 1 52 | excluded_nodes: 53 | - 2 54 | 55 | - name: Get the alert channel details 56 | dellemc.powerscale.alert_channel: 57 | onefs_host: "{{ onefs_host }}" 58 | port_no: "{{ port_no }}" 59 | api_user: "{{ api_user }}" 60 | api_password: "{{ api_password }}" 61 | verify_ssl: "{{ verify_ssl }}" 62 | name: "sample_event_channel" 63 | state: "present" 64 | 65 | - name: Modify the alert channel 66 | dellemc.powerscale.alert_channel: 67 | onefs_host: "{{ onefs_host }}" 68 | port_no: "{{ port_no }}" 69 | api_user: "{{ api_user }}" 70 | api_password: "{{ api_password }}" 71 | verify_ssl: "{{ verify_ssl }}" 72 | name: "sample_event_channel" 73 | enabled: false 74 | allowed_nodes: 75 | - 2 76 | - 3 77 | excluded_nodes: 78 | - 1 79 | 80 | - name: Send the test alert message 81 | dellemc.powerscale.alert_channel: 82 | onefs_host: "{{ onefs_host }}" 83 | port_no: "{{ port_no }}" 84 | api_user: "{{ api_user }}" 85 | api_password: "{{ api_password }}" 86 | verify_ssl: "{{ verify_ssl }}" 87 | name: "{{ channel_smtp }}" 88 | send_test_alert: true 89 | 90 | - name: Delete the alert channel 91 | dellemc.powerscale.alert_channel: 92 | onefs_host: "{{ onefs_host }}" 93 | port_no: "{{ port_no }}" 94 | api_user: "{{ api_user }}" 95 | api_password: "{{ api_password }}" 96 | verify_ssl: "{{ verify_ssl }}" 97 | name: "sample_event_channel" 98 | state: "absent" 99 | -------------------------------------------------------------------------------- /playbooks/modules/alert_rule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Alert Rule operations on PowerScale Array 3 | hosts: localhost 4 | connection: local 5 | 6 | tasks: 7 | 8 | - name: Get the alert channel and alert group details 9 | dellemc.powerscale.info: 10 | onefs_host: "{{ onefs_host }}" 11 | api_user: "{{ api_user }}" 12 | api_password: "{{ api_password }}" 13 | verify_ssl: "{{ verify_ssl }}" 14 | port: "{{ port }}" 15 | gather_subset: 16 | - alert_channels 17 | - event_group 18 | register: result_info 19 | 20 | - name: Create alert rule with basic options 21 | dellemc.powerscale.alert_rule: 22 | onefs_host: "{{ onefs_host }}" 23 | api_user: "{{ api_user }}" 24 | api_password: "{{ api_password }}" 25 | verify_ssl: "{{ verify_ssl }}" 26 | port: "{{ port }}" 27 | state: present 28 | name: test_alert_rule 29 | categories: [] 30 | channels: 31 | - "{{ result_info.alert_channels[0]['channels'][0].name }}" 32 | condition: "NEW" 33 | eventgroup_ids: 34 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][0].id }}" 35 | exclude_eventgroup_ids: [] 36 | interval: 0 37 | limit: 0 38 | severities: [] 39 | transient: 0 40 | 41 | - name: Create alert rule with all options 42 | dellemc.powerscale.alert_rule: 43 | onefs_host: "{{ onefs_host }}" 44 | api_user: "{{ api_user }}" 45 | api_password: "{{ api_password }}" 46 | verify_ssl: "{{ verify_ssl }}" 47 | port: "{{ port }}" 48 | state: present 49 | name: test_rule_new 50 | condition: "NEW" 51 | categories: 52 | - all 53 | channels: 54 | - "{{ result_info.alert_channels[0]['channels'][0].name }}" 55 | eventgroup_ids: 56 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][0].id }}" 57 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][1].id }}" 58 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][2].id }}" 59 | exclude_eventgroup_ids: 60 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][3].id }}" 61 | interval: 11 62 | transient: 10 63 | limit: 10 64 | severities: 65 | - emergency 66 | - critical 67 | 68 | - name: Update alert rule 69 | dellemc.powerscale.alert_rule: 70 | onefs_host: "{{ onefs_host }}" 71 | api_user: "{{ api_user }}" 72 | api_password: "{{ api_password }}" 73 | verify_ssl: "{{ verify_ssl }}" 74 | port: "{{ port }}" 75 | state: present 76 | name: test_rule_new 77 | condition: "NEW" 78 | categories: 79 | - SYS_DISK_EVENTS 80 | - NODE_STATUS_EVENTS 81 | channels: 82 | - "{{ result_info.alert_channels[0]['channels'][0].name }}" 83 | eventgroup_ids: 84 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][0].id }}" 85 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][1].id }}" 86 | exclude_eventgroup_ids: 87 | - "{{ result_info.event_groups[0]['eventgroup_definitions'][3].id }}" 88 | interval: 11 89 | transient: 10 90 | limit: 10 91 | severities: 92 | - emergency 93 | - critical 94 | 95 | - name: Delete alert rule 96 | dellemc.powerscale.alert_rule: 97 | onefs_host: "{{ onefs_host }}" 98 | api_user: "{{ api_user }}" 99 | api_password: "{{ api_password }}" 100 | verify_ssl: "{{ verify_ssl }}" 101 | port: "{{ port }}" 102 | state: absent 103 | name: test_rule_new 104 | -------------------------------------------------------------------------------- /playbooks/modules/alert_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Alert Settings Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "x.x.x.x" 7 | api_user: "user" 8 | api_password: "xxxx" 9 | verify_ssl: false 10 | timestamp: 1720091148 11 | timestamp_converted: "{{ '%Y-%m-%d %H:%M:%S'|strftime(timestamp) }}" 12 | 13 | tasks: 14 | - name: Enable celog maintenance mode 15 | dellemc.powerscale.alert_settings: 16 | onefs_host: "{{ onefs_host }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | verify_ssl: "{{ verify_ssl }}" 20 | enable_celog_maintenance_mode: true 21 | 22 | - name: Disable and prune all history of maintenance mode 23 | dellemc.powerscale.alert_settings: 24 | onefs_host: "{{ onefs_host }}" 25 | api_user: "{{ api_user }}" 26 | api_password: "{{ api_password }}" 27 | verify_ssl: "{{ verify_ssl }}" 28 | enable_celog_maintenance_mode: false 29 | prune: 0 30 | 31 | # Use this task to convert start or end timestamp to date 32 | - name: Convert Unix timestamp to date 33 | ansible.builtin.debug: 34 | msg: "{{ timestamp_converted }}" 35 | -------------------------------------------------------------------------------- /playbooks/modules/groupnet.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Groupnet Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'password' 10 | groupnet_name: 'groupnet_test' 11 | new_groupnet_name: 'groupnet_test_rename' 12 | state_present: 'present' 13 | state_absent: 'absent' 14 | 15 | tasks: 16 | - name: Create a groupnet 17 | dellemc.powerscale.groupnet: 18 | onefs_host: "{{ onefs_host }}" 19 | api_user: "{{ api_user }}" 20 | api_password: "{{ api_password }}" 21 | verify_ssl: "{{ verify_ssl }}" 22 | groupnet_name: "{{ groupnet_name }}" 23 | description: "Test Groupnet" 24 | dns_servers: 25 | - '10.**.**.10' 26 | - '10.**.**.11' 27 | dns_server_state: 'add' 28 | dns_search_suffix: 29 | - test.com 30 | - ansibleneo1.com 31 | dns_search_suffix_state: 'add' 32 | state: "{{ state_present }}" 33 | 34 | - name: Create a groupnet Idempotency case 35 | dellemc.powerscale.groupnet: 36 | onefs_host: "{{ onefs_host }}" 37 | api_user: "{{ api_user }}" 38 | api_password: "{{ api_password }}" 39 | verify_ssl: "{{ verify_ssl }}" 40 | groupnet_name: "{{ groupnet_name }}" 41 | description: "Test Groupnet" 42 | dns_servers: 43 | - '10.**.**.10' 44 | - '10.**.**.11' 45 | dns_server_state: 'add' 46 | dns_search_suffix: 47 | - test.com 48 | - ansibleneo1.com 49 | dns_search_suffix_state: 'add' 50 | state: "{{ state_present }}" 51 | 52 | - name: Get groupnet details 53 | dellemc.powerscale.groupnet: 54 | onefs_host: "{{ onefs_host }}" 55 | api_user: "{{ api_user }}" 56 | api_password: "{{ api_password }}" 57 | verify_ssl: "{{ verify_ssl }}" 58 | groupnet_name: "{{ groupnet_name }}" 59 | state: "{{ state_present }}" 60 | 61 | - name: Modify groupnet details 62 | dellemc.powerscale.groupnet: 63 | onefs_host: "{{ onefs_host }}" 64 | api_user: "{{ api_user }}" 65 | api_password: "{{ api_password }}" 66 | verify_ssl: "{{ verify_ssl }}" 67 | groupnet_name: "{{ groupnet_name }}" 68 | description: "Test Groupnet desc" 69 | dns_servers: 70 | - '10.**.**.12' 71 | dns_server_state: 'add' 72 | dns_search_suffix: 73 | - ansibleneo1.com 74 | dns_search_suffix_state: 'remove' 75 | state: "{{ state_present }}" 76 | 77 | - name: Modify groupnet details Idempotency case 78 | dellemc.powerscale.groupnet: 79 | onefs_host: "{{ onefs_host }}" 80 | api_user: "{{ api_user }}" 81 | api_password: "{{ api_password }}" 82 | verify_ssl: "{{ verify_ssl }}" 83 | groupnet_name: "{{ groupnet_name }}" 84 | description: "Test Groupnet desc" 85 | dns_servers: 86 | - '10.**.**.12' 87 | dns_server_state: 'add' 88 | dns_search_suffix: 89 | - ansibleneo1.com 90 | dns_search_suffix_state: 'remove' 91 | state: "{{ state_present }}" 92 | 93 | - name: Rename a groupnet 94 | dellemc.powerscale.groupnet: 95 | onefs_host: "{{ onefs_host }}" 96 | api_user: "{{ api_user }}" 97 | api_password: "{{ api_password }}" 98 | verify_ssl: "{{ verify_ssl }}" 99 | groupnet_name: "{{ groupnet_name }}" 100 | new_groupnet_name: "{{ new_groupnet_name }}" 101 | state: "{{ state_present }}" 102 | 103 | - name: Delete a groupnet 104 | dellemc.powerscale.groupnet: 105 | onefs_host: "{{ onefs_host }}" 106 | api_user: "{{ api_user }}" 107 | api_password: "{{ api_password }}" 108 | verify_ssl: "{{ verify_ssl }}" 109 | groupnet_name: "{{ new_groupnet_name }}" 110 | state: "{{ state_absent }}" 111 | 112 | - name: Delete a groupnet Idempotency case 113 | dellemc.powerscale.groupnet: 114 | onefs_host: "{{ onefs_host }}" 115 | api_user: "{{ api_user }}" 116 | api_password: "{{ api_password }}" 117 | verify_ssl: "{{ verify_ssl }}" 118 | groupnet_name: "{{ new_groupnet_name }}" 119 | state: "{{ state_absent }}" 120 | -------------------------------------------------------------------------------- /playbooks/modules/networkpool.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Network pool Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'Password' 10 | state_present: 'present' 11 | state_absent: 'absent' 12 | access_zone: 'System' 13 | access_zone_modify: "test" 14 | groupnet_name: 'groupnet0' 15 | subnet_name: 'subnet0' 16 | description: "pool Created by Ansible" 17 | new_pool_name: "rename_Test_pool_1" 18 | 19 | tasks: 20 | - name: Create Network pool 21 | dellemc.powerscale.networkpool: 22 | onefs_host: "{{ onefs_host }}" 23 | api_user: "{{ api_user }}" 24 | api_password: "{{ api_password }}" 25 | verify_ssl: "{{ verify_ssl }}" 26 | access_zone: "{{ access_zone }}" 27 | groupnet_name: "{{ groupnet_name }}" 28 | subnet_name: "{{ subnet_name }}" 29 | pool_name: "Test_pool_1" 30 | state: "{{ state_present }}" 31 | 32 | - name: Get Network pool 33 | dellemc.powerscale.networkpool: 34 | onefs_host: "{{ onefs_host }}" 35 | api_user: "{{ api_user }}" 36 | api_password: "{{ api_password }}" 37 | verify_ssl: "{{ verify_ssl }}" 38 | groupnet_name: "{{ groupnet_name }}" 39 | subnet_name: "{{ subnet_name }}" 40 | pool_name: "pool0" 41 | state: "{{ state_present }}" 42 | 43 | - name: Modify Network pool 44 | dellemc.powerscale.networkpool: 45 | onefs_host: "{{ onefs_host }}" 46 | api_user: "{{ api_user }}" 47 | api_password: "{{ api_password }}" 48 | verify_ssl: "{{ verify_ssl }}" 49 | groupnet_name: "{{ groupnet_name }}" 50 | subnet_name: "{{ subnet_name }}" 51 | pool_name: "Test_pool_1" 52 | sc_params: 53 | sc_dns_zone: "10.**.**.169" 54 | sc_connect_policy: "round_robin" 55 | sc_failover_policy: "round_robin" 56 | rebalance_policy: "auto" 57 | alloc_method: "static" 58 | sc_auto_unsuspend_delay: 0 59 | sc_ttl: 0 60 | aggregation_mode: "roundrobin" 61 | sc_dns_zone_aliases: 62 | - "Test" 63 | static_routes: 64 | - gateway: "10.**.**.**" 65 | prefix_len: 21 66 | subnet: "10.**.**.**" 67 | route_state: "add" 68 | - gateway: "11.**.**.**" 69 | prefix_len: 24 70 | subnet: "11.**.**.**" 71 | route_state: "add" 72 | description: "pool_name Created by Ansible Modify" 73 | additional_pool_params: 74 | ranges: 75 | - low: "10.**.**.176" 76 | high: "10.**.**.178" 77 | range_state: "add" 78 | ifaces: 79 | - iface: "ext-1" 80 | lnn: 1 81 | - iface: "ext-2" 82 | lnn: 1 83 | iface_state: "add" 84 | state: "{{ state_present }}" 85 | 86 | - name: Rename a network Pool 87 | dellemc.powerscale.networkpool: 88 | onefs_host: "{{ onefs_host }}" 89 | api_user: "{{ api_user }}" 90 | api_password: "{{ api_password }}" 91 | verify_ssl: "{{ verify_ssl }}" 92 | groupnet_name: "{{ groupnet_name }}" 93 | subnet_name: "{{ subnet_name }}" 94 | pool_name: "Test_Pool" 95 | new_pool_name: "Test_Pool_Rename" 96 | state: "{{ state_present }}" 97 | 98 | - name: Delete Network pool 99 | dellemc.powerscale.networkpool: 100 | onefs_host: "{{ onefs_host }}" 101 | api_user: "{{ api_user }}" 102 | api_password: "{{ api_password }}" 103 | verify_ssl: "{{ verify_ssl }}" 104 | groupnet_name: "{{ groupnet_name }}" 105 | subnet_name: "{{ subnet_name }}" 106 | pool_name: "Test_pool_1" 107 | state: "{{ state_absent }}" 108 | -------------------------------------------------------------------------------- /playbooks/modules/networksettings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Network Settings Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**169' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'password' 10 | state_present: 'present' 11 | state_absent: 'absent' 12 | 13 | tasks: 14 | - name: Get Network settings 15 | dellemc.powerscale.networksettings: 16 | onefs_host: "{{ onefs_host }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | verify_ssl: "{{ verify_ssl }}" 20 | state: "{{ state_present }}" 21 | 22 | - name: Enable source based routing 23 | dellemc.powerscale.networksettings: 24 | onefs_host: "{{ onefs_host }}" 25 | api_user: "{{ api_user }}" 26 | api_password: "{{ api_password }}" 27 | verify_ssl: "{{ verify_ssl }}" 28 | enable_source_routing: true 29 | state: "{{ state_present }}" 30 | 31 | - name: Enable source based routing - Idempotency 32 | dellemc.powerscale.networksettings: 33 | onefs_host: "{{ onefs_host }}" 34 | api_user: "{{ api_user }}" 35 | api_password: "{{ api_password }}" 36 | verify_ssl: "{{ verify_ssl }}" 37 | enable_source_routing: true 38 | state: "{{ state_present }}" 39 | 40 | - name: Disable source based routing 41 | dellemc.powerscale.networksettings: 42 | onefs_host: "{{ onefs_host }}" 43 | api_user: "{{ api_user }}" 44 | api_password: "{{ api_password }}" 45 | verify_ssl: "{{ verify_ssl }}" 46 | enable_source_routing: false 47 | state: "{{ state_present }}" 48 | 49 | - name: Disable source based routing - Idempotency 50 | dellemc.powerscale.networksettings: 51 | onefs_host: "{{ onefs_host }}" 52 | api_user: "{{ api_user }}" 53 | api_password: "{{ api_password }}" 54 | verify_ssl: "{{ verify_ssl }}" 55 | enable_source_routing: false 56 | state: "{{ state_present }}" 57 | -------------------------------------------------------------------------------- /playbooks/modules/nfs_alias.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Collect set of facts in PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.25' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'Password' 10 | access_zone: 'System' 11 | include_all_access_zones: true 12 | 13 | tasks: 14 | - name: Create NFS alias - check mode 15 | register: result 16 | dellemc.powerscale.nfs_alias: 17 | onefs_host: "{{ onefs_host }}" 18 | verify_ssl: "{{ verify_ssl }}" 19 | api_user: "{{ api_user }}" 20 | api_password: "{{ api_password }}" 21 | nfs_alias_name: "/sample_alias_2" 22 | path: "/ifs" 23 | access_zone: 'System' 24 | state: "present" 25 | check_mode: true 26 | 27 | - name: Create NFS alias 28 | register: result 29 | dellemc.powerscale.nfs_alias: 30 | onefs_host: "{{ onefs_host }}" 31 | verify_ssl: "{{ verify_ssl }}" 32 | api_user: "{{ api_user }}" 33 | api_password: "{{ api_password }}" 34 | nfs_alias_name: "/sample_alias_2" 35 | path: "/ifs" 36 | state: "present" 37 | 38 | - name: Create NFS alias - Idempotency 39 | dellemc.powerscale.nfs_alias: 40 | onefs_host: "{{ onefs_host }}" 41 | verify_ssl: "{{ verify_ssl }}" 42 | api_user: "{{ api_user }}" 43 | api_password: "{{ api_password }}" 44 | nfs_alias_name: "{{ result.nfs_alias_details.name }}" 45 | path: "/ifs" 46 | access_zone: 'System' 47 | state: "present" 48 | 49 | - name: Get NFS alias by name 50 | dellemc.powerscale.nfs_alias: 51 | onefs_host: "{{ onefs_host }}" 52 | verify_ssl: "{{ verify_ssl }}" 53 | api_user: "{{ api_user }}" 54 | api_password: "{{ api_password }}" 55 | nfs_alias_name: "{{ result.nfs_alias_details.name }}" 56 | 57 | - name: Modify NFS alias- check mode 58 | dellemc.powerscale.nfs_alias: 59 | onefs_host: "{{ onefs_host }}" 60 | verify_ssl: "{{ verify_ssl }}" 61 | api_user: "{{ api_user }}" 62 | api_password: "{{ api_password }}" 63 | nfs_alias_name: "{{ result.nfs_alias_details.name }}" 64 | new_alias_name: "/Renamed_alias_2" 65 | path: "/ifs/Test" 66 | state: "present" 67 | check_mode: true 68 | 69 | - name: Modify NFS alias 70 | dellemc.powerscale.nfs_alias: 71 | onefs_host: "{{ onefs_host }}" 72 | verify_ssl: "{{ verify_ssl }}" 73 | api_user: "{{ api_user }}" 74 | api_password: "{{ api_password }}" 75 | nfs_alias_name: "{{ result.nfs_alias_details.name }}" 76 | new_alias_name: "/Renamed_alias_2" 77 | path: "/ifs/Test" 78 | state: "present" 79 | 80 | - name: Modify NFS alias - Idempotency 81 | dellemc.powerscale.nfs_alias: 82 | onefs_host: "{{ onefs_host }}" 83 | verify_ssl: "{{ verify_ssl }}" 84 | api_user: "{{ api_user }}" 85 | api_password: "{{ api_password }}" 86 | nfs_alias_name: "/Renamed_alias_2" 87 | new_alias_name: "/Renamed_alias_2" 88 | path: "/ifs/Test" 89 | state: "present" 90 | 91 | - name: Delete NFS alias - check mode 92 | dellemc.powerscale.nfs_alias: 93 | onefs_host: "{{ onefs_host }}" 94 | verify_ssl: "{{ verify_ssl }}" 95 | api_user: "{{ api_user }}" 96 | api_password: "{{ api_password }}" 97 | nfs_alias_name: "/Renamed_alias_2" 98 | state: "absent" 99 | check_mode: true 100 | 101 | - name: Delete NFS alias 102 | dellemc.powerscale.nfs_alias: 103 | onefs_host: "{{ onefs_host }}" 104 | verify_ssl: "{{ verify_ssl }}" 105 | api_user: "{{ api_user }}" 106 | api_password: "{{ api_password }}" 107 | nfs_alias_name: "/Renamed_alias_2" 108 | state: "absent" 109 | 110 | - name: Delete NFS alias - Idempotency 111 | dellemc.powerscale.nfs_alias: 112 | onefs_host: "{{ onefs_host }}" 113 | verify_ssl: "{{ verify_ssl }}" 114 | api_user: "{{ api_user }}" 115 | api_password: "{{ api_password }}" 116 | nfs_alias_name: /Renamed_alias_2" 117 | state: "absent" 118 | -------------------------------------------------------------------------------- /playbooks/modules/nfs_default_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: NFS default settings module on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "10.**.**.**" 7 | api_user: "***" 8 | api_password: "****" 9 | verify_ssl: false 10 | access_zone: "sample-zone" 11 | 12 | tasks: 13 | - name: Get details of NFS default settings 14 | dellemc.powerscale.nfs_default_settings: 15 | onefs_host: "{{ onefs_host }}" 16 | api_user: "{{ api_user }}" 17 | api_password: "{{ api_password }}" 18 | verify_ssl: "{{ verify_ssl }}" 19 | access_zone: "{{ access_zone }}" 20 | 21 | - name: Update the NFS default settings 22 | dellemc.powerscale.nfs_default_settings: 23 | onefs_host: "{{ onefs_host }}" 24 | api_user: "{{ api_user }}" 25 | api_password: "{{ api_password }}" 26 | verify_ssl: "{{ verify_ssl }}" 27 | access_zone: "{{ access_zone }}" 28 | block_size: 29 | size_value: 5 30 | size_unit: 'KB' 31 | commit_asynchronous: false 32 | encoding: 'UTF8' 33 | map_root: 34 | enabled: true 35 | primary_group: 'group_1' 36 | secondary_groups: 37 | - name: 'group_2' 38 | - name: 'group_3' 39 | state: 'absent' 40 | user: 'ntpd' 41 | readdirplus: true 42 | time_delta: 43 | time_value: 5 44 | time_unit: 'seconds' 45 | write_filesync_action: 'DATASYNC' 46 | security_flavors: 47 | - unix 48 | - kerberos 49 | -------------------------------------------------------------------------------- /playbooks/modules/nfs_global_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: NFS Global Settings Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "10.**.**.**" 7 | port_no: "1234" 8 | api_user: "user" 9 | api_password: "password" 10 | verify_ssl: false 11 | 12 | tasks: 13 | - name: Get NFS global settings 14 | dellemc.powerscale.nfs_global_settings: 15 | onefs_host: "{{ onefs_host }}" 16 | port_no: "{{ port_no }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | verify_ssl: "{{ verify_ssl }}" 20 | 21 | - name: Update service of NFS global settings 22 | dellemc.powerscale.nfs_global_settings: 23 | onefs_host: "{{ onefs_host }}" 24 | port_no: "{{ port_no }}" 25 | api_user: "{{ api_user }}" 26 | api_password: "{{ api_password }}" 27 | verify_ssl: "{{ verify_ssl }}" 28 | service: true 29 | nfsv3: 30 | nfsv3_enabled: false 31 | nfsv4: 32 | nfsv40_enabled: true 33 | nfsv41_enabled: true 34 | nfsv42_enabled: false 35 | rpc_minthreads: 17 36 | rpc_maxthreads: 20 37 | rquota_enabled: true 38 | 39 | - name: Update service of NFS global settings - Idempotency 40 | dellemc.powerscale.nfs_global_settings: 41 | onefs_host: "{{ onefs_host }}" 42 | port_no: "{{ port_no }}" 43 | api_user: "{{ api_user }}" 44 | api_password: "{{ api_password }}" 45 | verify_ssl: "{{ verify_ssl }}" 46 | service: true 47 | nfsv3: 48 | nfsv3_enabled: false 49 | nfsv4: 50 | nfsv40_enabled: true 51 | nfsv41_enabled: true 52 | nfsv42_enabled: false 53 | rpc_minthreads: 17 54 | rpc_maxthreads: 20 55 | rquota_enabled: true 56 | -------------------------------------------------------------------------------- /playbooks/modules/nfs_zone_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: NFS zone settings module on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "xx.xx.xx.xx" 7 | port_no: "000" 8 | api_user: "user" 9 | api_password: "pass" 10 | verify_ssl: false 11 | access_zone: "sample-zone" 12 | 13 | tasks: 14 | - name: Get details of NFS zone settings 15 | dellemc.powerscale.nfs_zone_settings: 16 | onefs_host: "{{ onefs_host }}" 17 | port_no: "{{ port_no }}" 18 | api_user: "{{ api_user }}" 19 | api_password: "{{ api_password }}" 20 | verify_ssl: "{{ verify_ssl }}" 21 | access_zone: "{{ access_zone }}" 22 | 23 | - name: Update the NFS zone settings - check mode 24 | dellemc.powerscale.nfs_zone_settings: 25 | onefs_host: "{{ onefs_host }}" 26 | port_no: "{{ port_no }}" 27 | api_user: "{{ api_user }}" 28 | api_password: "{{ api_password }}" 29 | verify_ssl: "{{ verify_ssl }}" 30 | access_zone: "{{ access_zone }}" 31 | nfsv4_allow_numeric_ids: false 32 | nfsv4_domain: "example.com" 33 | nfsv4_no_domain: false 34 | nfsv4_no_domain_uids: false 35 | nfsv4_no_names: false 36 | nfsv4_replace_domain: false 37 | check_mode: true 38 | 39 | - name: Update the NFS zone settings 40 | dellemc.powerscale.nfs_zone_settings: 41 | onefs_host: "{{ onefs_host }}" 42 | port_no: "{{ port_no }}" 43 | api_user: "{{ api_user }}" 44 | api_password: "{{ api_password }}" 45 | verify_ssl: "{{ verify_ssl }}" 46 | access_zone: "{{ access_zone }}" 47 | nfsv4_allow_numeric_ids: false 48 | nfsv4_domain: "example.com" 49 | nfsv4_no_domain: false 50 | nfsv4_no_domain_uids: false 51 | nfsv4_no_names: false 52 | nfsv4_replace_domain: false 53 | -------------------------------------------------------------------------------- /playbooks/modules/node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Sample playbook to get Powerscale Cluster Node information 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.157' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'Password' 10 | node_id: '1' 11 | 12 | tasks: 13 | - name: Get node info of the PowerScale cluster node 14 | dellemc.powerscale.node: 15 | onefs_host: "{{ onefs_host }}" 16 | verify_ssl: "{{ verify_ssl }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | node_id: "{{ node_id }}" 20 | state: "present" 21 | -------------------------------------------------------------------------------- /playbooks/modules/role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "10.**.**.**" 7 | port_no: "8080" 8 | api_user: "******" 9 | api_password: "p******" 10 | verify_ssl: false 11 | access_zone: "System" 12 | 13 | tasks: 14 | - name: Create Role 15 | dellemc.powerscale.role: 16 | onefs_host: "{{ onefs_host }}" 17 | port_no: "{{ port_no }}" 18 | api_user: "{{ api_user }}" 19 | api_password: "{{ api_password }}" 20 | verify_ssl: "{{ verify_ssl }}" 21 | role_name: "Test_Role" 22 | description: "Description" 23 | access_zone: "System" 24 | privileges: 25 | - name: "Audit" 26 | permission: "w" 27 | state: "present" 28 | - name: "Backup" 29 | permission: "r" 30 | state: "present" 31 | members: 32 | - name: "Everyone" 33 | type: "wellknown" 34 | state: "present" 35 | state: "present" 36 | 37 | - name: Copy Role 38 | dellemc.powerscale.role: 39 | onefs_host: "{{ onefs_host }}" 40 | port_no: "{{ port_no }}" 41 | api_user: "{{ api_user }}" 42 | api_password: "{{ api_password }}" 43 | verify_ssl: "{{ verify_ssl }}" 44 | role_name: "Test_Role" 45 | description: "Copy Role via Ansible" 46 | copy_role: true 47 | new_role_name: "" 48 | access_zone: "{{ access_zone }}" 49 | privileges: 50 | - name: "Cluster" 51 | permission: "r" 52 | state: "present" 53 | state: "present" 54 | 55 | - name: Get role details 56 | dellemc.powerscale.role: 57 | onefs_host: "{{ onefs_host }}" 58 | port_no: "{{ port_no }}" 59 | api_user: "{{ api_user }}" 60 | api_password: "{{ api_password }}" 61 | verify_ssl: "{{ verify_ssl }}" 62 | role_name: "Test_Role" 63 | access_zone: "{{ access_zone }}" 64 | 65 | - name: Modify Role 66 | dellemc.powerscale.role: 67 | onefs_host: "{{ onefs_host }}" 68 | port_no: "{{ port_no }}" 69 | api_user: "{{ api_user }}" 70 | api_password: "{{ api_password }}" 71 | verify_ssl: "{{ verify_ssl }}" 72 | role_name: "Test_Role" 73 | new_role_name: "Test_Copy_Modify" 74 | description: "Test_Description_Modify12" 75 | access_zone: "System" 76 | privileges: 77 | - name: "Audit" 78 | permission: "w" 79 | state: "present" 80 | members: 81 | - name: "esa" 82 | provider_type: "local" 83 | type: "user" 84 | state: "absent" 85 | state: "present" 86 | 87 | - name: Delete Role 88 | dellemc.powerscale.role: 89 | onefs_host: "{{ onefs_host }}" 90 | api_user: "{{ api_user }}" 91 | api_password: "{{ api_password }}" 92 | verify_ssl: "{{ verify_ssl }}" 93 | role_name: "Test_Role" 94 | state: "absent" 95 | access_zone: "{{ access_zone }}" 96 | -------------------------------------------------------------------------------- /playbooks/modules/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Manage Setting Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.242' 7 | verify_ssl: false 8 | api_user: '***' 9 | api_password: '***' 10 | state_present: 'present' 11 | state_absent: 'absent' 12 | mail_relay: 'mailrelay.itp11.dell.com' 13 | mail_sender: 'lab-a21@dell.com' 14 | mail_subject: 'alerts11' 15 | ntp_servers_add: 16 | - '10.**.**.21' 17 | - '10.**.**.22' 18 | - '10.**.**.23' 19 | ntp_servers_remove: 20 | - '10.**.**.29' 21 | ntp_server_id: "10.10.230.21" 22 | 23 | tasks: 24 | - name: Update cluster settings 25 | dellemc.powerscale.settings: 26 | onefs_host: "{{ onefs_host }}" 27 | api_user: "{{ api_user }}" 28 | api_password: "{{ api_password }}" 29 | verify_ssl: "{{ verify_ssl }}" 30 | state: "{{ state_present }}" 31 | ntp_servers: "{{ ntp_servers_add }}" 32 | mail_relay: "{{ mail_relay }}" 33 | mail_sender: "{{ mail_sender }}" 34 | mail_subject: "{{ mail_subject }}" 35 | name: "PIE-IsilonS-24241-Cluster" 36 | description: "This is new description for the cluster" 37 | logon_details: 38 | message_title: "This is the new title" 39 | description: "This is new description" 40 | company: "Test company" 41 | location: "Test location" 42 | primary_contact: 43 | name: "primary_name11" 44 | phone1: "primary_phone11" 45 | phone2: "primary_phone21" 46 | email: "primary_email1@email.com" 47 | secondary_contact: 48 | name: "secondary_name11" 49 | phone1: "secondary_phone11" 50 | phone2: "secondary_phone21" 51 | email: "secondary_email1@email.com" 52 | 53 | - name: Get cluster settings 54 | dellemc.powerscale.settings: 55 | onefs_host: "{{ onefs_host }}" 56 | api_user: "{{ api_user }}" 57 | api_password: "{{ api_password }}" 58 | verify_ssl: "{{ verify_ssl }}" 59 | 60 | - name: Remove NTP server 61 | dellemc.powerscale.settings: 62 | onefs_host: "{{ onefs_host }}" 63 | api_user: "{{ api_user }}" 64 | api_password: "{{ api_password }}" 65 | verify_ssl: "{{ verify_ssl }}" 66 | ntp_servers: "{{ ntp_servers_remove }}" 67 | state: "{{ state_absent }}" 68 | -------------------------------------------------------------------------------- /playbooks/modules/smartpoolsettings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Smartpool Settings Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'root' 9 | api_password: 'pancake' 10 | state_present: 'present' 11 | 12 | tasks: 13 | - name: Get Smartpool settings 14 | dellemc.powerscale.smartpoolsettings: 15 | onefs_host: "{{ onefs_host }}" 16 | api_user: "{{ api_user }}" 17 | api_password: "{{ api_password }}" 18 | verify_ssl: "{{ verify_ssl }}" 19 | state: "{{ state_present }}" 20 | 21 | - name: Modify Smartpool settings 22 | dellemc.powerscale.smartpoolsettings: 23 | onefs_host: "{{ onefs_host }}" 24 | api_user: "{{ api_user }}" 25 | api_password: "{{ api_password }}" 26 | verify_ssl: "{{ verify_ssl }}" 27 | virtual_hot_spare_limit_percent: 20 28 | virtual_hot_spare_hide_spare: true 29 | state: "{{ state_present }}" 30 | 31 | - name: Modify Smartpool settings - Idempotency 32 | dellemc.powerscale.smartpoolsettings: 33 | onefs_host: "{{ onefs_host }}" 34 | api_user: "{{ api_user }}" 35 | api_password: "{{ api_password }}" 36 | verify_ssl: "{{ verify_ssl }}" 37 | virtual_hot_spare_limit_percent: 20 38 | virtual_hot_spare_hide_spare: true 39 | state: "{{ state_present }}" 40 | 41 | - name: Modify Smartpool settings 42 | dellemc.powerscale.smartpoolsettings: 43 | onefs_host: "{{ onefs_host }}" 44 | api_user: "{{ api_user }}" 45 | api_password: "{{ api_password }}" 46 | verify_ssl: "{{ verify_ssl }}" 47 | virtual_hot_spare_limit_percent: 10 48 | virtual_hot_spare_hide_spare: false 49 | state: "{{ state_present }}" 50 | -------------------------------------------------------------------------------- /playbooks/modules/smb_file.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SMB file operations on PowerScale array 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'password' 10 | 11 | tasks: 12 | - name: Get list of smb open files of the PowerScale cluster 13 | dellemc.powerscale.smb_file: 14 | onefs_host: "{{ onefs_host }}" 15 | verify_ssl: "{{ verify_ssl }}" 16 | api_user: "{{ api_user }}" 17 | api_password: "{{ api_password }}" 18 | state: "present" 19 | 20 | - name: Close smb file of the PowerScale cluster 21 | dellemc.powerscale.smb_file: 22 | onefs_host: "{{ onefs_host }}" 23 | verify_ssl: "{{ verify_ssl }}" 24 | api_user: "{{ api_user }}" 25 | api_password: "{{ api_password }}" 26 | file_path: "/ifs" 27 | state: "absent" 28 | 29 | - name: Close smb open file of the PowerScale cluster 30 | dellemc.powerscale.smb_file: 31 | onefs_host: "{{ onefs_host }}" 32 | verify_ssl: "{{ verify_ssl }}" 33 | api_user: "{{ api_user }}" 34 | api_password: "{{ api_password }}" 35 | file_id: 2281 36 | state: "absent" 37 | -------------------------------------------------------------------------------- /playbooks/modules/smb_global_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SMB Global Settings Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "10.**.**.**" 7 | port_no: "1234" 8 | api_user: "user" 9 | api_password: "password" 10 | verify_ssl: false 11 | 12 | tasks: 13 | - name: Get SMB global settings 14 | dellemc.powerscale.smb_global_settings: 15 | onefs_host: "{{ onefs_host }}" 16 | port_no: "{{ port_no }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | verify_ssl: "{{ verify_ssl }}" 20 | 21 | - name: Update SMB global settings 22 | dellemc.powerscale.smb_global_settings: 23 | onefs_host: "{{ onefs_host }}" 24 | port_no: "{{ port_no }}" 25 | api_user: "{{ api_user }}" 26 | api_password: "{{ api_password }}" 27 | verify_ssl: "{{ verify_ssl }}" 28 | access_based_share_enum: true 29 | dot_snap_accessible_child: true 30 | dot_snap_accessible_root: false 31 | dot_snap_visible_child: false 32 | dot_snap_visible_root: true 33 | enable_security_signatures: true 34 | guest_user: user 35 | ignore_eas: false 36 | onefs_cpu_multiplier: 2 37 | onefs_num_workers: 4 38 | reject_unencrypted_access: true 39 | require_security_signatures: true 40 | server_side_copy: true 41 | server_string: 'PowerScale Server' 42 | service: false 43 | support_multichannel: true 44 | support_netbios: true 45 | support_smb2: true 46 | support_smb3_encryption: false 47 | -------------------------------------------------------------------------------- /playbooks/modules/snmp_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SNMP Settings Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "**.**.**.**" 7 | port_no: "0000" 8 | api_user: "user" 9 | api_password: "pass" 10 | verify_ssl: false 11 | 12 | tasks: 13 | - name: Get SNMP settings 14 | dellemc.powerscale.snmp_settings: 15 | onefs_host: "{{ onefs_host }}" 16 | api_user: "{{ api_user }}" 17 | api_password: "{{ api_password }}" 18 | verify_ssl: "{{ verify_ssl }}" 19 | 20 | - name: Update SNMP settings - Check_mode 21 | dellemc.powerscale.snmp_settings: 22 | onefs_host: "{{ onefs_host }}" 23 | api_user: "{{ api_user }}" 24 | api_password: "{{ api_password }}" 25 | verify_ssl: "{{ verify_ssl }}" 26 | read_only_community: "community-name" 27 | snmp_v3: 28 | access: true 29 | auth_protocol: "SHA" 30 | privacy_password: "password" 31 | password: "auth_password" 32 | privacy_protocol: "AES" 33 | security_level: "noAuthNoPriv" 34 | read_only_user: "user" 35 | system_contact: "contact@domain.com" 36 | system_location: "Enabled SNMP" 37 | check_mode: true 38 | 39 | - name: Update SNMP settings 40 | dellemc.powerscale.snmp_settings: 41 | onefs_host: "{{ onefs_host }}" 42 | api_user: "{{ api_user }}" 43 | api_password: "{{ api_password }}" 44 | verify_ssl: "{{ verify_ssl }}" 45 | read_only_community: "community-name" 46 | snmp_v3: 47 | access: true 48 | auth_protocol: "SHA" 49 | privacy_password: "password" 50 | password: "auth_password" 51 | privacy_protocol: "AES" 52 | security_level: "noAuthNoPriv" 53 | read_only_user: "user" 54 | system_contact: "contact@domain.com" 55 | system_location: "Enabled SNMP" 56 | -------------------------------------------------------------------------------- /playbooks/modules/storagepooltier.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Manage storage pool tier Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'password' 10 | state_present: 'present' 11 | state_absent: 'absent' 12 | 13 | tasks: 14 | - name: Create a storage pool tier 15 | dellemc.powerscale.storagepooltier: 16 | onefs_host: "{{ onefs_host }}" 17 | verify_ssl: "{{ verify_ssl }}" 18 | api_user: "{{ api_user }}" 19 | api_password: "{{ api_password }}" 20 | tier_name: "test_tier" 21 | nodepools: 22 | - "test_nodepool" 23 | state: 'present' 24 | 25 | - name: Create a storage pool tier - Ideompotency 26 | dellemc.powerscale.storagepooltier: 27 | onefs_host: "{{ onefs_host }}" 28 | verify_ssl: "{{ verify_ssl }}" 29 | api_user: "{{ api_user }}" 30 | api_password: "{{ api_password }}" 31 | tier_name: "test_tier" 32 | nodepools: 33 | - "test_nodepool" 34 | state: 'present' 35 | 36 | - name: Get storage pool tier details 37 | dellemc.powerscale.storagepooltier: 38 | onefs_host: "{{ onefs_host }}" 39 | verify_ssl: "{{ verify_ssl }}" 40 | api_user: "{{ api_user }}" 41 | api_password: "{{ api_password }}" 42 | tier_name: "test_tier" 43 | state: 'present' 44 | 45 | - name: Delete a storage pool tier 46 | dellemc.powerscale.storagepooltier: 47 | onefs_host: "{{ onefs_host }}" 48 | verify_ssl: "{{ verify_ssl }}" 49 | api_user: "{{ api_user }}" 50 | api_password: "{{ api_password }}" 51 | tier_name: "test_tier" 52 | state: 'absent' 53 | -------------------------------------------------------------------------------- /playbooks/modules/support_assist.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Support assist Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "10.XX.XX.XX" 7 | port_no: "8080" 8 | api_user: "user" 9 | api_password: "password" 10 | verify_ssl: false 11 | 12 | tasks: 13 | - name: Accept support assist terms 14 | dellemc.powerscale.support_assist: 15 | onefs_host: "{{ onefs_host }}" 16 | port_no: "{{ port_no }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | verify_ssl: "{{ verify_ssl }}" 20 | accepted_terms: true 21 | 22 | - name: Get support assist settings 23 | dellemc.powerscale.support_assist: 24 | onefs_host: "{{ onefs_host }}" 25 | port_no: "{{ port_no }}" 26 | api_user: "{{ api_user }}" 27 | api_password: "{{ api_password }}" 28 | verify_ssl: "{{ verify_ssl }}" 29 | 30 | - name: Update support assist settings 31 | dellemc.powerscale.support_assist: 32 | onefs_host: "{{ onefs_host }}" 33 | port_no: "{{ port_no }}" 34 | api_user: "{{ api_user }}" 35 | api_password: "{{ api_password }}" 36 | verify_ssl: "{{ verify_ssl }}" 37 | enable_download: false 38 | enable_remote_support: false 39 | automatic_case_creation: false 40 | connection: 41 | gateway_endpoints: 42 | - enabled: true 43 | gateway_host: "XX.XX.XX.XX" 44 | gateway_port: 9443 45 | priority: 2 46 | use_proxy: false 47 | validate_ssl: false 48 | network_pools: 49 | - pool_name: "subnet0:pool0" 50 | state: absent 51 | - pool_name: "subnet0:pool2" 52 | state: present 53 | contact: 54 | primary: 55 | first_name: "Eric" 56 | last_name: "Nam" 57 | email: "eric.nam@example.com" 58 | phone: "1234567890" 59 | secondary: 60 | first_name: "Daniel" 61 | last_name: "Kang" 62 | email: "kangD@example.com" 63 | phone: "1234567891" 64 | telemetry: 65 | offline_collection_period: 60 66 | telemetry_enabled: true 67 | telemetry_persist: true 68 | telemetry_threads: 10 69 | -------------------------------------------------------------------------------- /playbooks/modules/synciq_global_settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SyncIQ Global Settings Module Operations on PowerScale Storage 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: "10.**.**.**" 7 | port_no: "1234" 8 | api_user: "user" 9 | api_password: "password" 10 | verify_ssl: false 11 | 12 | tasks: 13 | - name: Get SyncIQ global settings 14 | dellemc.powerscale.synciq_global_settings: 15 | onefs_host: "{{ onefs_host }}" 16 | port_no: "{{ port_no }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | verify_ssl: "{{ verify_ssl }}" 20 | 21 | - name: Update service of SyncIQ global settings 22 | dellemc.powerscale.synciq_global_settings: 23 | onefs_host: "{{ onefs_host }}" 24 | port_no: "{{ port_no }}" 25 | api_user: "{{ api_user }}" 26 | api_password: "{{ api_password }}" 27 | verify_ssl: "{{ verify_ssl }}" 28 | service: "on" 29 | encryption_required: true 30 | -------------------------------------------------------------------------------- /playbooks/modules/synciqcertificate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SyncIQ Target Cluster Certificates Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.243' 7 | port_no: '8080' 8 | verify_ssl: false 9 | api_user: '**' 10 | api_password: '**' 11 | 12 | tasks: 13 | - name: Import SyncIQ certificate 14 | dellemc.powerscale.synciqcertificate: 15 | onefs_host: "{{ onefs_host }}" 16 | verify_ssl: "{{ verify_ssl }}" 17 | api_user: "{{ api_user }}" 18 | api_password: "{{ api_password }}" 19 | certificate_file: "/ifs/server.crt" 20 | description: "From Module" 21 | alias_name: "Test_1" 22 | state: 'present' 23 | 24 | - name: Get SyncIQ certificate details 25 | dellemc.powerscale.synciqcertificate: 26 | onefs_host: "{{ onefs_host }}" 27 | api_user: "{{ api_user }}" 28 | api_password: "{{ api_password }}" 29 | verify_ssl: "{{ verify_ssl }}" 30 | certificate_id: "xyz" 31 | state: "present" 32 | 33 | - name: Modify SyncIQ certificate details 34 | dellemc.powerscale.synciqcertificate: 35 | onefs_host: "{{ onefs_host }}" 36 | api_user: "{{ api_user }}" 37 | api_password: "{{ api_password }}" 38 | verify_ssl: "{{ verify_ssl }}" 39 | certificate_id: "xyz" 40 | description: "From python modify" 41 | new_alias_name: "Test_1_modify" 42 | state: "present" 43 | 44 | - name: Delete SyncIQ certificate details 45 | dellemc.powerscale.synciqcertificate: 46 | onefs_host: "{{ onefs_host }}" 47 | api_user: "{{ api_user }}" 48 | api_password: "{{ api_password }}" 49 | verify_ssl: "{{ verify_ssl }}" 50 | alias_name: "Test_1_modify" 51 | state: "absent" 52 | -------------------------------------------------------------------------------- /playbooks/modules/synciqjobs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SyncIQ Job Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'password' 10 | job_id: 'Test_SSL' 11 | state_present: 'present' 12 | state_absent: 'absent' 13 | 14 | tasks: 15 | - name: Get SyncIQ job details 16 | dellemc.powerscale.synciqjob: 17 | onefs_host: "{{ onefs_host }}" 18 | api_user: "{{ api_user }}" 19 | api_password: "{{ api_password }}" 20 | verify_ssl: "{{ verify_ssl }}" 21 | job_id: "{{ job_id }}" 22 | state: "{{ state_present }}" 23 | 24 | - name: Resume a SyncIQ job when in paused state 25 | dellemc.powerscale.synciqjob: 26 | onefs_host: "{{ onefs_host }}" 27 | api_user: "{{ api_user }}" 28 | api_password: "{{ api_password }}" 29 | verify_ssl: "{{ verify_ssl }}" 30 | job_id: "{{ job_id }}" 31 | job_state: "run" 32 | state: "{{ state_present }}" 33 | 34 | - name: Resume a SyncIQ job when in paused state Idempotency case 35 | dellemc.powerscale.synciqjob: 36 | onefs_host: "{{ onefs_host }}" 37 | api_user: "{{ api_user }}" 38 | api_password: "{{ api_password }}" 39 | verify_ssl: "{{ verify_ssl }}" 40 | job_id: "{{ job_id }}" 41 | job_state: "run" 42 | state: "{{ state_present }}" 43 | 44 | - name: Pause a SyncIQ job when in running state 45 | dellemc.powerscale.synciqjob: 46 | onefs_host: "{{ onefs_host }}" 47 | api_user: "{{ api_user }}" 48 | api_password: "{{ api_password }}" 49 | verify_ssl: "{{ verify_ssl }}" 50 | job_id: "{{ job_id }}" 51 | job_state: "pause" 52 | state: "{{ state_present }}" 53 | 54 | - name: Pause a SyncIQ job when in running state Idempotency case 55 | dellemc.powerscale.synciqjob: 56 | onefs_host: "{{ onefs_host }}" 57 | api_user: "{{ api_user }}" 58 | api_password: "{{ api_password }}" 59 | verify_ssl: "{{ verify_ssl }}" 60 | job_id: "{{ job_id }}" 61 | job_state: "pause" 62 | state: "{{ state_present }}" 63 | 64 | - name: Cancel a SyncIQ job 65 | dellemc.powerscale.synciqjob: 66 | onefs_host: "{{ onefs_host }}" 67 | api_user: "{{ api_user }}" 68 | api_password: "{{ api_password }}" 69 | verify_ssl: "{{ verify_ssl }}" 70 | job_id: "{{ job_id }}" 71 | job_state: "cancel" 72 | state: "{{ state_absent }}" 73 | 74 | - name: Cancel a SyncIQ job Idempotency case 75 | dellemc.powerscale.synciqjob: 76 | onefs_host: "{{ onefs_host }}" 77 | api_user: "{{ api_user }}" 78 | api_password: "{{ api_password }}" 79 | verify_ssl: "{{ verify_ssl }}" 80 | job_id: "{{ job_id }}" 81 | job_state: "cancel" 82 | state: "{{ state_absent }}" 83 | -------------------------------------------------------------------------------- /playbooks/modules/synciqreports.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SyncIQ Reports on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | port_no: '8080' 8 | verify_ssl: false 9 | api_user: 'user' 10 | api_password: 'password' 11 | state_present: 'present' 12 | id: '1-Test_syncIQ_policy' 13 | report_name: 'Test_snap_schedule_123' 14 | name1: 'Test_syncIQ_policy' 15 | sub_report_id: 1 16 | include_sub_reports: true 17 | 18 | tasks: 19 | - name: Get a single SyncIQ report with id 20 | register: result 21 | dellemc.powerscale.synciqreports: 22 | onefs_host: "{{ onefs_host }}" 23 | api_user: "{{ api_user }}" 24 | api_password: "{{ api_password }}" 25 | verify_ssl: "{{ verify_ssl }}" 26 | id: "{{ id }}" 27 | state: "{{ state_present }}" 28 | 29 | - name: Get a single SyncIQ report with name 30 | register: result 31 | dellemc.powerscale.synciqreports: 32 | onefs_host: "{{ onefs_host }}" 33 | api_user: "{{ api_user }}" 34 | api_password: "{{ api_password }}" 35 | verify_ssl: "{{ verify_ssl }}" 36 | name: "{{ report_name }}" 37 | state: "{{ state_present }}" 38 | 39 | - name: Get all SyncIQ sub-reports with report id 40 | register: result 41 | dellemc.powerscale.synciqreports: 42 | onefs_host: "{{ onefs_host }}" 43 | api_user: "{{ api_user }}" 44 | api_password: "{{ api_password }}" 45 | verify_ssl: "{{ verify_ssl }}" 46 | id: "{{ id }}" 47 | include_sub_reports: "{{ include_sub_reports }}" 48 | state: "{{ state_present }}" 49 | 50 | - name: Get all SyncIQ sub-reports with report name 51 | register: result 52 | dellemc.powerscale.synciqreports: 53 | onefs_host: "{{ onefs_host }}" 54 | api_user: "{{ api_user }}" 55 | api_password: "{{ api_password }}" 56 | verify_ssl: "{{ verify_ssl }}" 57 | name: "{{ name1 }}" 58 | include_sub_reports: "{{ include_sub_reports }}" 59 | state: "{{ state_present }}" 60 | 61 | - name: Get a single SyncIQ sub-report with sub-report id and report id 62 | register: result 63 | dellemc.powerscale.synciqreports: 64 | onefs_host: "{{ onefs_host }}" 65 | api_user: "{{ api_user }}" 66 | api_password: "{{ api_password }}" 67 | verify_ssl: "{{ verify_ssl }}" 68 | id: "{{ id }}" 69 | sub_report_id: "{{ sub_report_id }}" 70 | state: "{{ state_present }}" 71 | 72 | - name: Get a single SyncIQ sub-report with sub-report id and report name 73 | register: result 74 | dellemc.powerscale.synciqreports: 75 | onefs_host: "{{ onefs_host }}" 76 | api_user: "{{ api_user }}" 77 | api_password: "{{ api_password }}" 78 | verify_ssl: "{{ verify_ssl }}" 79 | name: "{{ report_name }}" 80 | sub_report_id: "{{ sub_report_id }}" 81 | state: "{{ state_present }}" 82 | -------------------------------------------------------------------------------- /playbooks/modules/synciqrules.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SyncIQ Performance Rules Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | port_no: '8080' 8 | verify_ssl: false 9 | api_user: 'user' 10 | api_password: 'password' 11 | 12 | tasks: 13 | - name: Create SyncIQ performance rule 14 | register: result 15 | dellemc.powerscale.synciqrules: 16 | onefs_host: "{{ onefs_host }}" 17 | verify_ssl: "{{ verify_ssl }}" 18 | api_user: "{{ api_user }}" 19 | api_password: "{{ api_password }}" 20 | enabled: true 21 | description: "New Performance rule" 22 | schedule: 23 | end: '20:00' 24 | begin: '10:00' 25 | days_of_week: 26 | - monday 27 | - tuesday 28 | - sunday 29 | - friday 30 | limit: 90 31 | rule_type: 'worker' 32 | state: 'present' 33 | 34 | - name: Create SyncIQ performance rule -- Idempotency 35 | dellemc.powerscale.synciqrules: 36 | onefs_host: "{{ onefs_host }}" 37 | verify_ssl: "{{ verify_ssl }}" 38 | api_user: "{{ api_user }}" 39 | api_password: "{{ api_password }}" 40 | enabled: true 41 | schedule: 42 | end: '20:00' 43 | begin: '10:00' 44 | days_of_week: 45 | - monday 46 | - tuesday 47 | - sunday 48 | - friday 49 | limit: 90 50 | rule_type: 'worker' 51 | state: 'present' 52 | 53 | - name: Get SyncIQ rule details 54 | dellemc.powerscale.synciqrules: 55 | onefs_host: "{{ onefs_host }}" 56 | verify_ssl: "{{ verify_ssl }}" 57 | api_user: "{{ api_user }}" 58 | api_password: "{{ api_password }}" 59 | sync_rule_id: "{{ result.synciq_rule_details.id }}" 60 | state: 'present' 61 | 62 | - name: Modify a SyncIQ rule 63 | dellemc.powerscale.synciqrules: 64 | onefs_host: "{{ onefs_host }}" 65 | verify_ssl: "{{ verify_ssl }}" 66 | api_user: "{{ api_user }}" 67 | api_password: "{{ api_password }}" 68 | sync_rule_id: "{{ result.synciq_rule_details.id }}" 69 | limit: 95 70 | description: "Modify rule" 71 | enabled: false 72 | state: 'present' 73 | 74 | - name: Modify a SyncIQ rule -- Idempotency 75 | dellemc.powerscale.synciqrules: 76 | onefs_host: "{{ onefs_host }}" 77 | verify_ssl: "{{ verify_ssl }}" 78 | api_user: "{{ api_user }}" 79 | api_password: "{{ api_password }}" 80 | sync_rule_id: "{{ result.synciq_rule_details.id }}" 81 | limit: 95 82 | description: "Modify rule" 83 | enabled: false 84 | state: 'present' 85 | 86 | - name: Delete a SyncIQ rule 87 | dellemc.powerscale.synciqrules: 88 | onefs_host: "{{ onefs_host }}" 89 | verify_ssl: "{{ verify_ssl }}" 90 | api_user: "{{ api_user }}" 91 | api_password: "{{ api_password }}" 92 | sync_rule_id: "{{ result.synciq_rule_details.id }}" 93 | enabled: false 94 | schedule: 95 | end: '20:00' 96 | begin: '10:00' 97 | days_of_week: 98 | - monday 99 | - tuesday 100 | - sunday 101 | - friday 102 | limit: 95 103 | rule_type: "worker" 104 | state: "absent" 105 | 106 | - name: Delete a SyncIQ rule -- Idempotency 107 | dellemc.powerscale.synciqrules: 108 | onefs_host: "{{ onefs_host }}" 109 | verify_ssl: "{{ verify_ssl }}" 110 | api_user: "{{ api_user }}" 111 | api_password: "{{ api_password }}" 112 | sync_rule_id: "{{ result.synciq_rule_details.id }}" 113 | enabled: false 114 | schedule: 115 | end: '20:00' 116 | begin: '10:00' 117 | days_of_week: 118 | - monday 119 | - tuesday 120 | - sunday 121 | - friday 122 | limit: 95 123 | rule_type: "worker" 124 | state: "absent" 125 | -------------------------------------------------------------------------------- /playbooks/modules/synciqtargetreports.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: SyncIQ Target Reports on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | port_no: '8080' 8 | verify_ssl: false 9 | api_user: 'user' 10 | api_password: 'password' 11 | state_present: 'present' 12 | id: '2-sample_policy' 13 | target_report_name: 'sample_policy' 14 | sub_report_id: 1 15 | include_sub_reports: true 16 | 17 | tasks: 18 | - name: Get a single SyncIQ target report with id 19 | dellemc.powerscale.synciqtargetreports: 20 | onefs_host: "{{ onefs_host }}" 21 | api_user: "{{ api_user }}" 22 | api_password: "{{ api_password }}" 23 | verify_ssl: "{{ verify_ssl }}" 24 | id: "{{ id }}" 25 | state: "{{ state_present }}" 26 | 27 | - name: Get a single SyncIQ target report with name 28 | dellemc.powerscale.synciqtargetreports: 29 | onefs_host: "{{ onefs_host }}" 30 | api_user: "{{ api_user }}" 31 | api_password: "{{ api_password }}" 32 | verify_ssl: "{{ verify_ssl }}" 33 | name: "{{ target_report_name }}" 34 | state: "{{ state_present }}" 35 | 36 | - name: Get all SyncIQ target sub-reports with report id 37 | dellemc.powerscale.synciqtargetreports: 38 | onefs_host: "{{ onefs_host }}" 39 | api_user: "{{ api_user }}" 40 | api_password: "{{ api_password }}" 41 | verify_ssl: "{{ verify_ssl }}" 42 | id: "{{ id }}" 43 | include_sub_reports: "{{ include_sub_reports }}" 44 | state: "{{ state_present }}" 45 | 46 | - name: Get all SyncIQ target sub-reports with report name 47 | dellemc.powerscale.synciqtargetreports: 48 | onefs_host: "{{ onefs_host }}" 49 | api_user: "{{ api_user }}" 50 | api_password: "{{ api_password }}" 51 | verify_ssl: "{{ verify_ssl }}" 52 | name: "{{ target_report_name }}" 53 | include_sub_reports: "{{ include_sub_reports }}" 54 | state: "{{ state_present }}" 55 | 56 | - name: Get a single SyncIQ target sub-report with sub-report id and report id 57 | dellemc.powerscale.synciqtargetreports: 58 | onefs_host: "{{ onefs_host }}" 59 | api_user: "{{ api_user }}" 60 | api_password: "{{ api_password }}" 61 | verify_ssl: "{{ verify_ssl }}" 62 | id: "{{ id }}" 63 | sub_report_id: "{{ sub_report_id }}" 64 | state: "{{ state_present }}" 65 | 66 | - name: Get a single SyncIQ target sub-report with sub-report id and report name 67 | dellemc.powerscale.synciqtargetreports: 68 | onefs_host: "{{ onefs_host }}" 69 | api_user: "{{ api_user }}" 70 | api_password: "{{ api_password }}" 71 | verify_ssl: "{{ verify_ssl }}" 72 | name: "{{ target_report_name }}" 73 | sub_report_id: "{{ sub_report_id }}" 74 | state: "{{ state_present }}" 75 | -------------------------------------------------------------------------------- /playbooks/modules/user_mapping_rules.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Manage user mapping rule Operations on PowerScale 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: '**' 9 | api_password: '**' 10 | 11 | tasks: 12 | - name: Get a user mapping rule 13 | dellemc.powerscale.user_mapping_rule: 14 | onefs_host: "{{ onefs_host }}" 15 | verify_ssl: "{{ verify_ssl }}" 16 | api_user: "{{ api_user }}" 17 | api_password: "{{ api_password }}" 18 | apply_order: 8 19 | 20 | - name: Create a user mapping rule 21 | dellemc.powerscale.user_mapping_rule: 22 | onefs_host: "{{ onefs_host }}" 23 | verify_ssl: "{{ verify_ssl }}" 24 | api_user: "{{ api_user }}" 25 | api_password: "{{ api_password }}" 26 | rule: 27 | operator: "insert" 28 | options: 29 | break_on_match: true 30 | group: true 31 | groups: true 32 | user: true 33 | user1: 34 | domain: "ansibleneo.com" 35 | user: "test_ans_user" 36 | user2: 37 | user: "Test_userAnand" 38 | 39 | - name: Apply a new order to the user mapping rule 40 | dellemc.powerscale.user_mapping_rule: 41 | onefs_host: "{{ onefs_host }}" 42 | verify_ssl: "{{ verify_ssl }}" 43 | api_user: "{{ api_user }}" 44 | api_password: "{{ api_password }}" 45 | apply_order: 20 46 | new_order: 0 47 | state: 'present' 48 | 49 | - name: Modify a user mapping rule 50 | dellemc.powerscale.user_mapping_rule: 51 | onefs_host: "{{ onefs_host }}" 52 | verify_ssl: "{{ verify_ssl }}" 53 | api_user: "{{ api_user }}" 54 | api_password: "{{ api_password }}" 55 | apply_order: 7 56 | rule: 57 | operator: "insert" 58 | options: 59 | break_on_match: true 60 | group: true 61 | groups: true 62 | user: true 63 | user1: 64 | user: "Test_userAnand" 65 | user2: 66 | user: "test_ans_user" 67 | state: 'present' 68 | 69 | - name: Delete a user mapping rule 70 | dellemc.powerscale.user_mapping_rule: 71 | onefs_host: "{{ onefs_host }}" 72 | verify_ssl: "{{ verify_ssl }}" 73 | api_user: "{{ api_user }}" 74 | api_password: "{{ api_password }}" 75 | apply_order: 19 76 | state: 'absent' 77 | -------------------------------------------------------------------------------- /playbooks/modules/writable_snapshots.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Sample playbook for managing Snapshots on Dell PowerScale. 3 | hosts: localhost 4 | connection: local 5 | vars: 6 | onefs_host: '10.**.**.**' 7 | verify_ssl: false 8 | api_user: 'user' 9 | api_password: 'password' 10 | owner: 'ansible_owner' 11 | group: 'ansible_group' 12 | access_control: 'private_read' 13 | dst_path1: "/ifs/test_one" 14 | dst_path2: "/ifs/test_two" 15 | src_snap_id: 2 16 | src_snap_name: "Snapshot: 2024Apr15, 4:40 PM" 17 | state_present: 'present' 18 | state_absent: 'absent' 19 | 20 | tasks: 21 | - name: Create a writable snapshot using ID 22 | dellemc.powerscale.writable_snapshots: 23 | onefs_host: "{{ onefs_host }}" 24 | verify_ssl: "{{ verify_ssl }}" 25 | api_user: "{{ api_user }}" 26 | api_password: "{{ api_password }}" 27 | writable_snapshots: 28 | - dst_path: "{{ dst_path1 }}" 29 | src_snap: "{{ src_snap_id }}" 30 | state: "{{ state_present }}" 31 | - dst_path: "{{ dst_path2 }}" 32 | src_snap: "{{ src_snap_id }}" 33 | state: "{{ state_present }}" 34 | 35 | - name: Create a writable snapshot using Name. 36 | dellemc.powerscale.writable_snapshots: 37 | onefs_host: "{{ onefs_host }}" 38 | verify_ssl: "{{ verify_ssl }}" 39 | api_user: "{{ api_user }}" 40 | api_password: "{{ api_password }}" 41 | writable_snapshots: 42 | - dst_path: "{{ dst_path1 }}" 43 | src_snap: "{{ src_snap_name }}" 44 | state: "{{ state_present }}" 45 | - dst_path: "{{ dst_path2 }}" 46 | src_snap: "{{ src_snap_name }}" 47 | state: "{{ state_present }}" 48 | 49 | - name: Delete writable snapshot. 50 | dellemc.powerscale.writable_snapshots: 51 | onefs_host: "{{ onefs_host }}" 52 | verify_ssl: "{{ verify_ssl }}" 53 | api_user: "{{ api_user }}" 54 | api_password: "{{ api_password }}" 55 | writable_snapshots: 56 | - dst_path: "{{ dst_path1 }}" 57 | state: "{{ state_absent }}" 58 | - dst_path: "{{ dst_path2 }}" 59 | state: "{{ state_absent }}" 60 | 61 | - name: Create and delete writable snapshot 62 | dellemc.powerscale.writable_snapshots: 63 | onefs_host: "{{ onefs_host }}" 64 | verify_ssl: "{{ verify_ssl }}" 65 | api_user: "{{ api_user }}" 66 | api_password: "{{ api_password }}" 67 | writable_snapshots: 68 | - dst_path: "{{ dst_path2 }}" 69 | src_snap: "{{ src_snap_id }}" 70 | state: "{{ state_present }}" 71 | - dst_path: "{{ dst_path1 }}" 72 | state: "{{ state_absent }}" 73 | -------------------------------------------------------------------------------- /plugins/doc_fragments/powerscale.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright: (c) 2019-2024, Dell Technologies 3 | 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | 8 | class ModuleDocFragment(object): 9 | # Documentation fragment for PowerScale (powerscale) 10 | DOCUMENTATION = r''' 11 | options: 12 | onefs_host: 13 | description: 14 | - IP address or FQDN of the PowerScale cluster. 15 | type: str 16 | required: true 17 | port_no: 18 | description: 19 | - Port number of the PowerScale cluster.It defaults to 8080 if 20 | not specified. 21 | type: str 22 | required: false 23 | default: '8080' 24 | verify_ssl: 25 | description: 26 | - boolean variable to specify whether to validate SSL 27 | certificate or not. 28 | - C(true) - indicates that the SSL certificate should be 29 | verified. 30 | - C(false) - indicates that the SSL certificate should not be 31 | verified. 32 | type: bool 33 | required: true 34 | choices: [true, false] 35 | api_user: 36 | type: str 37 | description: 38 | - username of the PowerScale cluster. 39 | required: true 40 | api_password: 41 | type: str 42 | description: 43 | - the password of the PowerScale cluster. 44 | required: true 45 | requirements: 46 | - A Dell PowerScale Storage system. 47 | - Ansible-core 2.16 or later. 48 | - Python 3.10, 3.11 or 3.12. 49 | notes: 50 | - The modules present in this collection named as 'dellemc.powerscale' 51 | are built to support the Dell PowerScale storage platform. 52 | ''' 53 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/plugins/module_utils/storage/dell/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/logging_handler.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Custom rotating file handler for PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | __metaclass__ = type 9 | 10 | from datetime import datetime 11 | from logging.handlers import RotatingFileHandler 12 | 13 | 14 | class CustomRotatingFileHandler(RotatingFileHandler): 15 | def rotation_filename(self, default_name): 16 | """ 17 | Modify the filename of a log file when rotating. 18 | :param default_name: The default name of the log file. 19 | """ 20 | src_file_name = default_name.split('.') 21 | dest_file_name = "{0}_{1}.{2}.{3}".format( 22 | src_file_name[0], '{0:%Y%m%d}'.format(datetime.now()), 23 | src_file_name[1], src_file_name[2] 24 | ) 25 | return dest_file_name 26 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/plugins/module_utils/storage/dell/shared_library/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/certificate.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('certificate') 13 | 14 | 15 | class Certificate: 16 | 17 | '''Class with shared Certificate operations''' 18 | 19 | def __init__(self, certificate_api, module): 20 | """ 21 | Initialize the certificate class 22 | :param certificate_api: The certificate sdk instance 23 | :param module: Ansible module object 24 | """ 25 | self.certificate_api = certificate_api 26 | self.module = module 27 | 28 | def get_server_certificate_with_default(self): 29 | """ 30 | Get details of Server certificate. 31 | """ 32 | try: 33 | certificate = self.certificate_api.list_certificate_server().to_dict() 34 | default_certificate = self.certificate_api.get_certificate_settings().to_dict() 35 | if certificate and default_certificate: 36 | for each_cert in certificate['certificates']: 37 | if each_cert['id'] == default_certificate['settings']['default_https_certificate']: 38 | each_cert['certificate_monitor_enabled'] = default_certificate['settings']['certificate_monitor_enabled'] 39 | each_cert['certificate_pre_expiration_threshold'] = \ 40 | default_certificate['settings']['certificate_pre_expiration_threshold'] 41 | break 42 | msg = f"Server certificate details are: {certificate}" 43 | LOG.info(msg) 44 | return certificate['certificates'] 45 | except Exception as e: 46 | error_msg = f"Got error {utils.determine_error(e)} while getting Server certificate details." 47 | LOG.error(error_msg) 48 | self.module.fail_json(msg=error_msg) 49 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/cluster.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('cluster') 13 | 14 | 15 | class Cluster: 16 | 17 | '''Class with shared Cluster operations''' 18 | 19 | def __init__(self, cluster_api, module): 20 | """ 21 | Initialize the cluster class 22 | :param cluster_api: The cluster sdk instance 23 | :param module: Ansible module object 24 | """ 25 | self.cluster_api = cluster_api 26 | self.module = module 27 | 28 | def get_email_settings(self): 29 | """ 30 | Get cluster email settings 31 | :return: Cluster email settings. 32 | """ 33 | try: 34 | email_details = self.cluster_api.get_cluster_email() 35 | return email_details.to_dict() 36 | except Exception as e: 37 | error_message = f"Failed to get the details of email settings with error: {utils.determine_error(e)}" 38 | LOG.error(error_message) 39 | self.module.fail_json(msg=error_message) 40 | 41 | def get_cluster_identity_details(self): 42 | """ 43 | Get cluster email settings 44 | :return: Cluster identity details. 45 | """ 46 | try: 47 | cluster_identity = self.cluster_api.get_cluster_identity() 48 | return cluster_identity.to_dict() 49 | except Exception as e: 50 | error_message = f"Failed to get the details of cluster identity details with error: {utils.determine_error(e)}" 51 | LOG.error(error_message) 52 | self.module.fail_json(msg=error_message) 53 | 54 | def get_cluster_owner_details(self): 55 | """ 56 | Get cluster email settings 57 | :return: Cluster owner details. 58 | """ 59 | try: 60 | cluster_owner = self.cluster_api.get_cluster_owner() 61 | return cluster_owner.to_dict() 62 | except Exception as e: 63 | error_message = f"Failed to get the details of cluster owner details with error: {utils.determine_error(e)}" 64 | LOG.error(error_message) 65 | self.module.fail_json(msg=error_message) 66 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/namespace.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('namespace') 13 | 14 | 15 | class Namespace: 16 | 17 | '''Class with shared namespace operations''' 18 | 19 | def __init__(self, namespace_api, module): 20 | """ 21 | Initialize the namespace class 22 | :param namespace_api: The namespace sdk instance 23 | :param module: Ansible module object 24 | """ 25 | self.namespace_api = namespace_api 26 | self.module = module 27 | 28 | def get_filesystem(self, path): 29 | """Gets a FileSystem on PowerScale.""" 30 | try: 31 | resp = self.namespace_api.get_directory_metadata( 32 | path, 33 | metadata=True) 34 | return resp.to_dict() 35 | except utils.ApiException as e: 36 | self.handle_apiexception(path, e) 37 | except Exception as e: 38 | error_message = "Failed to get details of Filesystem {0} with" \ 39 | " error {1} ".format(path, str(e)) 40 | self.handle_exception(error_message) 41 | 42 | def list_all_filesystem_from_directory(self, path): 43 | """Lists all filesystems in a directory""" 44 | try: 45 | resp = self.namespace_api.get_directory_contents(directory_path=path) 46 | return resp.to_dict() 47 | except utils.ApiException as e: 48 | self.handle_apiexception(path, e) 49 | except Exception as e: 50 | error_message = "Failed to get details of Filesystem {0} with" \ 51 | " error {1} ".format(path, str(e)) 52 | self.handle_exception(error_message) 53 | 54 | def get_acl(self, effective_path): 55 | """Retrieves ACL rights of filesystem""" 56 | try: 57 | if not self.module.check_mode: 58 | filesystem_acl = \ 59 | (self.namespace_api.get_acl(effective_path, 60 | acl=True)).to_dict() 61 | return filesystem_acl 62 | return True 63 | except Exception as e: 64 | error_message = 'Error %s while retrieving the access control list for ' \ 65 | 'namespace object.' % utils.determine_error(error_obj=e) 66 | self.handle_exception(error_message) 67 | 68 | def handle_apiexception(self, path, e): 69 | if str(e.status) == "404": 70 | log_msg = "Filesystem {0} status is \ 71 | {1}.format(path, e.status)" 72 | LOG.info(log_msg) 73 | return None 74 | else: 75 | error_msg = utils.determine_error(error_obj=e) 76 | error_message = "Failed to get details of Filesystem \ 77 | {0} with error {1} ".format(path, 78 | str(error_msg)) 79 | LOG.error(error_message) 80 | self.module.fail_json(msg=error_message) 81 | 82 | def handle_exception(self, error_message): 83 | LOG.error(error_message) 84 | self.module.fail_json(msg=error_message) 85 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/quota.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('quota') 13 | 14 | 15 | class Quota: 16 | 17 | '''Class with shared quota operations''' 18 | 19 | def __init__(self, quota_api, module): 20 | """ 21 | Initialize the quota class 22 | :param quota_api: The quota sdk instance 23 | :param module: Ansible module object 24 | """ 25 | self.quota_api = quota_api 26 | self.module = module 27 | 28 | def get_quota(self, effective_path): 29 | """Gets Quota details""" 30 | # On a single path , you can create multiple Quotas of 31 | # different types (directory, user etc) 32 | # We are filtering Quotas on the path and the type (directory). 33 | # On a given path, there can be only One Quota of a given type. 34 | try: 35 | filesystem_quota = self.quota_api.list_quota_quotas( 36 | path='/' + effective_path, 37 | type='directory') 38 | return filesystem_quota.to_dict() 39 | except Exception: 40 | error_message = 'Unable to get Quota details on ' \ 41 | 'path {0}'.format(effective_path) 42 | LOG.info(error_message) 43 | return None 44 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/snapshot.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('snapshot') 13 | 14 | 15 | class Snapshot: 16 | 17 | '''Class with shared snapshot operations''' 18 | 19 | def __init__(self, snapshot_api, module): 20 | """ 21 | Initialize the snapshot class 22 | :param snapshot_api: The snapshot sdk instance 23 | :param module: Ansible module object 24 | """ 25 | self.snapshot_api = snapshot_api 26 | self.module = module 27 | 28 | def get_filesystem_snapshots(self, effective_path): 29 | """Get snapshots for a given filesystem""" 30 | try: 31 | snapshots = [] 32 | filtered_snapshots = [] 33 | snapshot_list = \ 34 | self.snapshot_api.list_snapshot_snapshots().to_dict() 35 | snapshots.extend(snapshot_list['snapshots']) 36 | resume = snapshot_list['resume'] 37 | while resume: 38 | snapshot_list = \ 39 | self.snapshot_api.list_snapshot_snapshots( 40 | resume=resume).to_dict() 41 | snapshots.extend(snapshot_list['snapshots']) 42 | resume = snapshot_list['resume'] 43 | for snap in snapshot_list['snapshots']: 44 | if snap['path'] == '/' + effective_path: 45 | filtered_snapshots.append(snap) 46 | return filtered_snapshots 47 | except Exception as e: 48 | error_msg = utils.determine_error(error_obj=e) 49 | error_message = 'Failed to get filesystem snapshots ' \ 50 | 'due to error {0}'.format((str(error_msg))) 51 | LOG.error(error_message) 52 | self.module.fail_json(msg=error_message) 53 | 54 | def list_writable_snapshots(self): 55 | """ 56 | List the writable snapshots. 57 | 58 | :param filter: The filter for the list. 59 | :type filter: dict 60 | :returns: The list of snapshots. 61 | :rtype: list 62 | """ 63 | try: 64 | query_params = self.module.params.get('query_parameters') 65 | writable_snapshot_query_params = query_params.get('writable_snapshots', []) if query_params else [] 66 | filter_params = {} 67 | if writable_snapshot_query_params: 68 | if "wspath" in writable_snapshot_query_params: 69 | return self.get_writable_snapshot_by_wspath(wspath=writable_snapshot_query_params.get("wspath")) 70 | else: 71 | filter_params = dict(writable_snapshot_query_params.items()) 72 | writable_snapshots = [] 73 | snapshot_list = \ 74 | self.snapshot_api.list_snapshot_writable(**filter_params).to_dict() 75 | writable_snapshots.extend(snapshot_list['writable']) 76 | return writable_snapshots 77 | except Exception as e: 78 | error_msg = utils.determine_error(error_obj=e) 79 | error_message = 'Failed to get writeable snapshots ' \ 80 | 'due to error {0}'.format((str(error_msg))) 81 | LOG.error(error_message) 82 | self.module.fail_json(msg=error_message) 83 | 84 | def get_writable_snapshot_by_wspath(self, wspath): 85 | try: 86 | return self.snapshot_api.get_snapshot_writable_wspath( 87 | snapshot_writable_wspath=wspath 88 | ).to_dict().get("writable") 89 | except utils.ApiException as e: 90 | return {} 91 | except Exception as e: 92 | error_msg = utils.determine_error(error_obj=e) 93 | error_message = 'Failed to get writeable snapshot ' \ 94 | 'due to error {0}'.format((str(error_msg))) 95 | LOG.error(error_message) 96 | self.module.fail_json(msg=error_message) 97 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/support_assist.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('support_assist') 13 | 14 | 15 | class SupportAssist: 16 | 17 | '''Class with shared support assist operations''' 18 | 19 | def __init__(self, support_assist_api, module): 20 | """ 21 | Initialize the support assist class 22 | :param support_assist_api: The support assist SDK instance 23 | :param module: Ansible module object 24 | """ 25 | self.support_assist_api = support_assist_api 26 | self.module = module 27 | 28 | def get_support_assist_settings(self): 29 | """ 30 | Get details of support assist settings 31 | """ 32 | msg = "Getting support assist settings details" 33 | LOG.info(msg) 34 | try: 35 | support_assist_obj = self.support_assist_api.get_supportassist_settings().to_dict() 36 | if support_assist_obj: 37 | msg = f"support assist settings details are: {support_assist_obj}" 38 | LOG.info(msg) 39 | return support_assist_obj 40 | 41 | except Exception as e: 42 | error_msg = f"Got error {utils.determine_error(e)} while getting" \ 43 | f" support assist settings details " 44 | LOG.error(error_msg) 45 | self.module.fail_json(msg=error_msg) 46 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/synciq.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('synciq') 13 | 14 | 15 | class SyncIQ: 16 | 17 | '''Class with shared Sync operations''' 18 | 19 | def __init__(self, synciq_api, module): 20 | """ 21 | Initialize the synciq class 22 | :param synciq_api: The sync sdk instance 23 | :param module: Ansible module object 24 | """ 25 | self.synciq_api = synciq_api 26 | self.module = module 27 | 28 | def get_synciq_global_settings(self): 29 | """ 30 | Get details of SyncIQ global settings 31 | """ 32 | try: 33 | synciq_global_obj = self.synciq_api.get_sync_settings() 34 | if synciq_global_obj: 35 | msg = f"SyncIQ global settings details are: {synciq_global_obj.settings.to_dict()}" 36 | LOG.info(msg) 37 | return synciq_global_obj.settings.to_dict() 38 | 39 | except Exception as e: 40 | error_msg = f"Got error {utils.determine_error(e)} while getting" \ 41 | f" SyncIQ global setings details " 42 | LOG.error(error_msg) 43 | self.module.fail_json(msg=error_msg) 44 | -------------------------------------------------------------------------------- /plugins/module_utils/storage/dell/shared_library/zones_summary.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | LOG = utils.get_logger('zones_summary') 13 | 14 | 15 | class ZonesSummary: 16 | '''Class with methods to get zones summary details''' 17 | 18 | def __init__(self, zones_summary_api, module): 19 | """ 20 | Initialize the zones_summary class 21 | :param zones_summary_api: The zones_summary sdk instance 22 | :param module: Ansible module object 23 | """ 24 | self.zones_summary_api = zones_summary_api 25 | self.module = module 26 | 27 | def get_zone_base_path(self, access_zone): 28 | """ 29 | Get the zone base path 30 | :param access_zone: The access zone name 31 | :return: zone base path 32 | :rtype: dict 33 | """ 34 | try: 35 | msg = f"Getting zone base path for {access_zone} access zone" 36 | LOG.info(msg) 37 | zone_path = (self.zones_summary_api.get_zones_summary_zone(access_zone)).to_dict() 38 | # returning access zone base path 39 | if zone_path: 40 | path_msg = f"Zone base path is: {zone_path['summary']['path']}" 41 | LOG.info(path_msg) 42 | return zone_path['summary']['path'] 43 | except Exception as e: 44 | error_msg = utils.determine_error(error_obj=e) 45 | error_message = f'Fetching zone base path for access zone' \ 46 | f' {access_zone} is failed with error: {error_msg}' 47 | LOG.error(error_message) 48 | self.module.fail_json(msg=error_message) 49 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | isilon-sdk==0.3.0.1 2 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: dellemc.powerscale 4 | -------------------------------------------------------------------------------- /tests/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | modules: 3 | python_requires: '>=3.9' 4 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/tests/unit/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/__init__: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/tests/unit/plugins/__init__ -------------------------------------------------------------------------------- /tests/unit/plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/tests/unit/plugins/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_alert_channel_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Alert channel module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.smb.utils' 12 | 13 | 14 | class MockAlertChannelApi: 15 | 16 | CHANNEL_NAME = "test" 17 | ENABLED = True 18 | ALERT_COMMON_ARGS = { 19 | "state": "present", 20 | "enabled": None, 21 | "name": None, 22 | "type": None, 23 | "allowed_nodes": None, 24 | "excluded_nodes": None, 25 | "send_test_alert": None, 26 | "smtp_parameters": None 27 | } 28 | 29 | SMTP_ARGS = { 30 | "send_to": ["powerscale@sample.com"], 31 | "send_from": "powerscale@sample.com", 32 | "smtp_port": 25, 33 | "subject": "test subject", 34 | "smtp_host": "sample.com", 35 | "batch": "ALL", 36 | "batch_period": 3600, 37 | "smtp_use_auth": True, 38 | "smtp_username": "powerscale", 39 | "smtp_password": "powerscale", 40 | "smtp_security": "STARTTLS", 41 | "update_password": "on_create" 42 | } 43 | 44 | INVALID_USE_AUTH = { 45 | "smtp_use_auth": True 46 | } 47 | 48 | SMTP_ARGS2 = { 49 | "smtp_use_auth": True, 50 | "smtp_username": "powerscale1", 51 | "smtp_password": "powerscale1", 52 | "update_password": "always" 53 | } 54 | 55 | CHANNEL_DETAILS = { 56 | "channels": [ 57 | { 58 | "allowed_nodes": [1], 59 | "enabled": "false", 60 | "excluded_nodes": [2], 61 | "id": "1", 62 | "name": CHANNEL_NAME, 63 | "parameters": { 64 | "address": ["sample1@sample.com"], 65 | "batch": "ALL", 66 | "batch_period": 3600, 67 | "send_as": "sample1@sample.com", 68 | "smtp_port": 587, 69 | "smtp_host": "pscalehost.com", 70 | "smtp_use_auth": False, 71 | "smtp_username": "pscle_user", 72 | "subject": "sample subject", 73 | "smtp_security": "NONE" 74 | }, 75 | "rules": [], 76 | "type": "smtp" 77 | } 78 | ] 79 | } 80 | 81 | @staticmethod 82 | def get_alert_channel_exception(response_type): 83 | err_msg_dict = { 84 | 'get_alert': "Fetching alert channel failed with error: SDK Error message", 85 | 'create_exp': "Failed to create alert channel test with error: SDK Error message", 86 | 'test_alert_exp': "Failed to send test alert for alert channel test with error: SDK Error message", 87 | 'delete_exp': "Failed to delete alert channel test with error: SDK Error messag", 88 | 'modify_exp': "Failed to modify alert channel test with error: SDK Error message", 89 | 'invalid_name1': "Invalid alert channel name. Provide valid name", 90 | 'invalid_name2': "Invalid alert channel name. Name cannot contain slashes. Provide valid name", 91 | 'smtp_auth_err': "smtp_username is required while enabling smtp_use_auth. Provide valid smtp_username" 92 | } 93 | return err_msg_dict.get(response_type) 94 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_alert_rule_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of alert rule module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockAlertRuleApi: 13 | 14 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 15 | 16 | ALERT_RULE_COMMON_ARGS = { 17 | "onefs_host": "***.***.***.***", 18 | "validate_certs": False, 19 | "state": 'present', 20 | "name": "alert_rule", 21 | "categories": [], 22 | "channels": ["SupportAssist"], 23 | "condition": "NEW", 24 | "eventgroup_ids": ["100010001"], 25 | "exclude_eventgroup_ids": [], 26 | "interval": 0, 27 | "limit": 0, 28 | "severities": [], 29 | "transient": 0, 30 | } 31 | 32 | UPDATE_ALERT_RULE_OPTIONS = { 33 | "state": 'present', 34 | "name": "alert_rule", 35 | "categories": ["SYS_DISK_EVENTS", "NODE_STATUS_EVENTS"], 36 | "channels": ["SupportAssist"], 37 | "condition": "NEW", 38 | "eventgroup_ids": ["100010001", "100010002", "100010003"], 39 | "exclude_eventgroup_ids": ["100010005"], 40 | "interval": 10, 41 | "limit": 10, 42 | "severities": ["emergency", "critical"], 43 | "transient": 10, 44 | } 45 | 46 | EXISTING_ALERT_RULE_OPTIONS = { 47 | "state": 'present', 48 | "name": "alert_rule", 49 | "id": "alert_rule", 50 | "categories": ["SYS_DISK_EVENTS"], 51 | "channels": ["SupportAssist"], 52 | "condition": "NEW", 53 | "eventgroup_ids": ["100010001", "100010002"], 54 | "exclude_eventgroup_ids": ["100010005"], 55 | "interval": 10, 56 | "limit": 10, 57 | "severities": ["emergency"], 58 | "transient": 10, 59 | } 60 | 61 | GET_EXISTING_ALERT_RULE_OPTIONS = [ 62 | { 63 | "alert_conditions": [{ 64 | "state": 'present', 65 | "name": "alert_rule", 66 | "id": "alert_rule", 67 | "categories": ["100000000"], 68 | "channels": ["SupportAssist"], 69 | "condition": "NEW", 70 | "eventgroup_ids": ["100010001", "100010002"], 71 | "exclude_eventgroup_ids": ["100010005"], 72 | "interval": 10, 73 | "limit": 10, 74 | "severities": ["emergency"], 75 | "transient": 10}]}] 76 | 77 | DELETE_EXISTING_ALERT_RULE_OPTIONS = { 78 | "name": "alert_rule", 79 | "id": "alert_rule", 80 | "categories": ["SYS_DISK_EVENTS"], 81 | "channels": ["SupportAssist"], 82 | "condition": "NEW", 83 | "eventgroup_ids": ["100010001", "100010002"], 84 | "exclude_eventgroup_ids": ["100010005"], 85 | "interval": 10, 86 | "limit": 10, 87 | "severities": ["emergency"], 88 | "transient": 10, 89 | } 90 | 91 | DELETE_ALERT_RULE_OPTIONS = { 92 | "state": 'absent', 93 | "name": "alert_rule" 94 | } 95 | 96 | EVENT_CATEGORY = { 97 | 'categories': [ 98 | {'id': '100000000', 'id_name': 'SYS_DISK_EVENTS'}, 99 | {'id': '1100000000', 'id_name': 'CPOOL_EVENTS'}, 100 | {'id': '200000000', 'id_name': 'NODE_STATUS_EVENTS'}, 101 | {'id': '300000000', 'id_name': 'REBOOT_EVENTS'}, 102 | {'id': '400000000', 'id_name': 'SW_EVENTS'}, 103 | {'id': '500000000', 'id_name': 'QUOTA_EVENTS'}, 104 | {'id': '600000000', 'id_name': 'SNAP_EVENTS'}, 105 | {'id': '700000000', 'id_name': 'WINNET_EVENTS'}, 106 | {'id': '800000000', 'id_name': 'FILESYS_EVENTS'}, 107 | {'id': '900000000', 'id_name': 'HW_EVENTS'}]} 108 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_alert_settings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Alert Settings module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.smb.utils' 12 | 13 | 14 | class MockAlertSettingsApi: 15 | 16 | ALERT_COMMON_ARGS = { 17 | "enable_celog_maintenance_mode": None 18 | } 19 | 20 | SETTING_DETAILS = { 21 | "history": { 22 | "end": 0, 23 | "start": 1719831994 24 | }, 25 | "maintenance": "false" 26 | } 27 | 28 | @staticmethod 29 | def get_alert_exception_response(response_type): 30 | err_msg_dict = { 31 | 'get_alert': "Fetching maintenance events failed with error", 32 | 'modify_exp': "Modify alert settings failed with error: SDK Error message" 33 | } 34 | return err_msg_dict.get(response_type) 35 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_api_exception.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock ApiException for PowerScale Test modules""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockApiException(Exception): 13 | def __init__(self, status=500, body="SDK Error message"): 14 | self.status = status 15 | self.body = body 16 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_groupnet_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Groupnet Api for Groupnet Test module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | GENERIC_FAILURE_MSG = " failed with error" 11 | 12 | 13 | def get_groupnet_details(groupnet_name): 14 | if groupnet_name == 'new_groupnet': 15 | return None 16 | else: 17 | return {'groupnets': [{'allow_wildcard_subdomains': True, 18 | 'description': 'Test Groupnet', 19 | 'dns_cache_enabled': True, 20 | 'dns_options': [], 21 | 'dns_search': "['test.com']", 22 | 'dns_servers': ['10.*.*.*', '10.*.*.*'], 23 | 'id': 'groupnet3', 24 | 'name': 'groupnet3', 25 | 'server_side_dns_search': False, 26 | 'subnets': ['subnet12']}]} 27 | 28 | 29 | def get_invalid_groupnet(): 30 | return "The value for groupnet_name is invalid" 31 | 32 | 33 | def get_invalid_groupnet_len(): 34 | return "The maximum length for groupnet_name is 32" 35 | 36 | 37 | def get_invalid_dns(): 38 | return "The value for dns_servers is invalid" 39 | 40 | 41 | def get_groupnet_ex_msg(groupnet_name): 42 | return "Getting details of groupnet " + groupnet_name + GENERIC_FAILURE_MSG 43 | 44 | 45 | def modify_groupnet_ex_msg(groupnet_name): 46 | return "Modifying groupnet " + groupnet_name + GENERIC_FAILURE_MSG 47 | 48 | 49 | def delete_groupnet_ex_msg(groupnet_name): 50 | return "Deleting groupnet " + groupnet_name + GENERIC_FAILURE_MSG 51 | 52 | 53 | def create_groupnet_ex_msg(groupnet_name): 54 | return "Creating groupnet " + groupnet_name + GENERIC_FAILURE_MSG 55 | 56 | 57 | def get_invalid_desc(): 58 | return "The maximum length for description is 128" 59 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_ldap_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2025, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale LDAP module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.ldap.utils' 12 | 13 | LDAP = {'ldap': [{ 14 | "linked_access_zones": [ 15 | "System" 16 | ], 17 | "base_dn": "dc=sample,dc=ldap,dc=domain,dc=com", 18 | "bind_dn": "cn=administrator,dc=sample,dc=ldap,dc=domain,dc=com", 19 | "groupnet": "groupnet", 20 | "name": "sample-ldap", 21 | "server_uris": "ldap://xx.xx.xx.xx", 22 | "status": "online" 23 | } 24 | ] 25 | } 26 | 27 | 28 | def create_ldap_failed_msg(): 29 | return 'Add an LDAP provider failed' 30 | 31 | 32 | def modify_ldap_failed_msg(): 33 | return 'Modifying LDAP provider failed' 34 | 35 | 36 | def delete_ldap_failed_msg(): 37 | return 'Deleting LDAP provider failed' 38 | 39 | 40 | def invalid_server_uri_failed_msg(): 41 | return 'The value for server_uris is invalid' 42 | 43 | 44 | def no_server_uri_msg(): 45 | return 'The parameter server_uris is mandatory while creating' 46 | 47 | 48 | def invalid_server_uri_state_msg(): 49 | return 'Please specify the server_uri_state as present-in-ldap.' 50 | 51 | 52 | def no_base_dn_msg(): 53 | return 'The parameter base_dn is mandatory while creating' 54 | 55 | 56 | def ldap_access_msg(): 57 | return 'Update LDAP with access zone details' 58 | 59 | 60 | def ldap_exception_msg(): 61 | return 'SDK Error message' 62 | 63 | 64 | def ldap_exception2_msg(): 65 | return 'failed with error' 66 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_networkpool_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Network Pool module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.networkpool.utils' 12 | 13 | RANGE1 = "1.1.1.1" 14 | RANGE2 = "2.2.2.2" 15 | 16 | GET_NETWORK_POOLS = {"pools": [{"access_zone": "ansible-neo", 17 | "groupnet": "groupnet0", 18 | "name": "Test_pool1", 19 | "subnet": "subnet0", 20 | "ranges": [""], 21 | "ifaces": [""], 22 | "static_routes": [], 23 | "sc_dns_zone_aliases": []}]} 24 | 25 | CREATE_NETWORK_POOL = {"pools": [{"access_zone": "ansible-neo", 26 | "groupnet": "groupnet0", 27 | "name": "Test_pool1", 28 | "subnet": "subnet0", 29 | "description": "Test_pool1", 30 | "ranges": [{"low": RANGE1, 31 | "high": RANGE1}], 32 | "ifaces": [{"iface": "ext-1", 33 | "lnn": 4}], 34 | "static_routes": [{"gateway": RANGE1, 35 | "prefixlen": 4, 36 | "subnet": RANGE1}], 37 | "sc_dns_zone": RANGE1, 38 | "sc_connect_policy": "throughput", 39 | "sc_failover_policy": "throughput", 40 | "rebalance_policy": "auto", 41 | "alloc_method": "dynamic", 42 | "sc_auto_unsuspend_delay": 200, 43 | "sc_ttl": 300, 44 | "aggregation_mode": "lacp", 45 | "sc_subnet": "subnet_test", 46 | "sc_dns_zone_aliases": ["smartconn-zone"]}]} 47 | 48 | 49 | def get_networkpool_failed_msg(pool_name): 50 | return 'Unable to get network pool ' + pool_name + ' failed with error:' 51 | 52 | 53 | def create_networkpool_failed_msg(pool_name): 54 | return 'Unable to create network pool ' + pool_name 55 | 56 | 57 | def modify_networkpool_failed_msg(pool_name): 58 | return 'Failed to update network pool: ' + pool_name + ' with error' 59 | 60 | 61 | def delete_networkpool_failed_msg(pool_name): 62 | return 'Failed to delete network pool: ' + pool_name + ' with error' 63 | 64 | 65 | def network_pool_failed_msg(response_type): 66 | if response_type == 'invalid_pool_name': 67 | return 'The value for pool_name is invalid' 68 | elif response_type == 'invalid_pool_description': 69 | return 'The maximum length for description is 128' 70 | elif response_type == 'invalid_ip_range': 71 | return 'The value for IP range is invalid' 72 | elif response_type == 'invalid_iface': 73 | return 'Please enter valid value for iface' 74 | elif response_type == 'invalid_route': 75 | return 'Invalid static route value' 76 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_networkrule_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Network Rule module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.networkrule.utils' 12 | 13 | NETWORK_RULES = {'rules': [{'description': '', 14 | 'groupnet': 'groupnet0', 15 | 'id': 'groupnet0.subnet1.pool1.rule1', 16 | 'iface': 'ext-1', 17 | 'name': 'rule1', 18 | 'node_type': 'any', 19 | 'pool': 'pool1', 20 | 'subnet': 'subnet1'}] 21 | } 22 | 23 | 24 | def create_rule_failed_msg(rule_name): 25 | return 'Unable to create network rule ' + rule_name + '. failed with error:' 26 | 27 | 28 | def modify_rule_failed_msg(rule_name): 29 | return 'Unable to modify settings for rule ' + rule_name + '. failed with error' 30 | 31 | 32 | def delete_rule_failed_msg(rule_name): 33 | return 'Unable to delete network rule ' + rule_name + '. failed with error:' 34 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_networksettings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Network Settings module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.networksettings.utils' 12 | 13 | GET_NETWORK_SETTINGS = {"network_settings": [{"default_groupnet": "groupnet0", 14 | "sbr": True, 15 | "sc_rebalance_delay": 0, 16 | "tcp_ports": [2049, 445, 20, 21, 80]}]} 17 | 18 | UPDATE_NETWORK_SETTINGS = {"network_settings": [{"enable_source_routing": True, "state": "present"}]} 19 | 20 | 21 | def get_networksettings_failed_msg(): 22 | return 'Retrieving details of network settings failed with error:' 23 | 24 | 25 | def modify_networksettings_failed_msg(): 26 | return 'Modifying network settings failed with error:' 27 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_nfs_alias_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale NFS Alias module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.nfs_alias.utils' 12 | 13 | NFS_ALIAS = {'aliases': [{'health': 'unknown', 14 | 'id': '/test_alias_1', 15 | 'name': '/test_alias_1', 16 | 'path': '/ifs/Test', 17 | 'zone': 'System'}]} 18 | 19 | CREATE_NFS_ALIAS_PARAMS = {"name": "/test_alias_1", 20 | "path": "/ifs/Test"} 21 | 22 | MODIFY_NFS_ALIAS_PARAMS = {"name": "/Renamed_test_alias_1", 23 | "path": "/ifs/Test/sample1"} 24 | 25 | 26 | def create_nfs_alias_failed_msg(): 27 | return 'failed with error:' 28 | 29 | 30 | def modify_nfs_alias_failed_msg(): 31 | return 'failed with error:' 32 | 33 | 34 | def space_in_nfs_alias_name_msg(): 35 | return 'Spaces are not allowed in NFS alias name. Provide a valid nfs_alias_name' 36 | 37 | 38 | def empty_nfs_alias_name_msg(): 39 | return 'Provide a valid NFS alias name' 40 | 41 | 42 | def get_nfs_alias_failure_msg(): 43 | return 'Get details of NFS alias with name:/test_alias_1 failed with error' 44 | 45 | 46 | def new_alias_name_when_creation_msg(): 47 | return 'new_alias_name should not be provided during the creation of an NFS alias' 48 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_nfs_global_settings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of NFS global settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockNFSGlobalSettingsApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | 15 | NFS_GLOBAL_COMMON_ARGS = { 16 | "onefs_host": "**.***.**.***", 17 | "nfsv3_enabled": None, 18 | "nfsv3": None, 19 | "nfsv4": None, 20 | "rpc_maxthreads": 20, 21 | "rpc_minthreads": 17, 22 | "rquota_enabled": None, 23 | "service": None 24 | } 25 | GET_NFS_GLOBAL_RESPONSE = { 26 | "nfsv3_enabled": False, 27 | "nfsv3_rdma_enabled": True, 28 | "nfsv40_enabled": True, 29 | "nfsv41_enabled": True, 30 | "nfsv42_enabled": False, 31 | "nfsv4_enabled": True, 32 | "rpc_maxthreads": 20, 33 | "rpc_minthreads": 17, 34 | "rquota_enabled": True, 35 | "service": True 36 | } 37 | 38 | @staticmethod 39 | def get_nfs_global_settings_exception_response(response_type): 40 | if response_type == 'get_details_exception': 41 | return "Got error SDK Error message while getting NFS global setings details " 42 | elif response_type == 'update_exception': 43 | return "Modify NFS global settings failed with error: SDK Error message" 44 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_nfs_zone_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of NFS Zone Settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockNFSZoneSettingsApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | ZONE = "sample-zone" 15 | NFS_DOMAIN = "example.com" 16 | 17 | ZONE_SETTINGS_COMMON_ARGS = { 18 | "onefs_host": "**.***.**.***", 19 | "access_zone": None, 20 | "nfsv4_allow_numeric_ids": None, 21 | "nfsv4_domain": None, 22 | "nfsv4_no_domain": None, 23 | "nfsv4_no_domain_uids": None, 24 | "nfsv4_no_names": None, 25 | "nfsv4_replace_domain": None 26 | } 27 | 28 | GET_NFS_ZONE_SETTINGS_RESPONSE = { 29 | "settings": { 30 | "nfsv4_allow_numeric_ids": True, 31 | "nfsv4_domain": None, 32 | "nfsv4_no_domain": True, 33 | "nfsv4_no_domain_uids": True, 34 | "nfsv4_no_names": True, 35 | "nfsv4_replace_domain": True, 36 | "zone": "sample-zone" 37 | } 38 | } 39 | 40 | @staticmethod 41 | def zone_settings_exception(response_type): 42 | if response_type == "get_settings_exception": 43 | return 'Got error SDK Error message while getting NFS zone ' \ 44 | 'settings details for access zone: sample-zone' 45 | elif response_type == "update_zone_settings_exception": 46 | return 'Modify NFS zone settings with in access zone: ' \ 47 | 'sample-zone failed with error: SDK Error message' 48 | elif response_type == "prepare_zone_settings_object_exception": 49 | return 'Got error SDK Error message while preparing NFS zone' \ 50 | ' settings modify object' 51 | elif response_type == "invalid_zone_exception": 52 | return 'Invalid access zone provided. Provide valid access zone' 53 | elif response_type == "pre_reqs_exception": 54 | return '**********' 55 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_nfsdefaultsettings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of nfs default settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockNfsDefaultSettingsApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | NFS_DEFAULT_SETTINGS_COMMON_ARGS = { 15 | 'onefs_host': '**.***.**.***', 16 | 'access_zone': 'System', 17 | 'map_root': {}, 18 | 'map_non_root': {}, 19 | 'map_failure': {}, 20 | 'file_name_max_size': None, 21 | 'block_size': None, 22 | 'commit_asynchronous': None, 23 | 'directory_transfer_size': None, 24 | 'read_transfer_max_size': None, 25 | 'read_transfer_multiple': None, 26 | 'read_transfer_size': None, 27 | 'setattr_asynchronous': None, 28 | 'write_datasync_action': None, 29 | 'write_datasync_reply': None, 30 | 'write_filesync_action': None, 31 | 'write_filesync_reply': None, 32 | 'write_transfer_max_size': None, 33 | 'write_transfer_multiple': None, 34 | 'write_transfer_size': None, 35 | 'write_unstable_action': None, 36 | 'write_unstable_reply': None, 37 | 'max_file_size': None, 38 | 'readdirplus': None, 39 | 'return_32bit_file_ids': None, 40 | 'can_set_time': None, 41 | 'encoding': None, 42 | 'map_lookup_uid': None, 43 | 'symlinks': None, 44 | 'time_delta': None, 45 | 'security_flavors': [] 46 | } 47 | GET_NFSDEFAULTSETTINGS_RESPONSE = { 48 | "commit_asynchronous": False, 49 | "encoding": "UTF-8", 50 | "map_full": True, 51 | "map_root": { 52 | "enabled": False, 53 | "primary_group": { 54 | "id": "GROUP:0001", 55 | "name": None, 56 | "type": None 57 | }, 58 | "secondary_groups": [ 59 | { 60 | "id": "GROUP:0002" 61 | }, 62 | { 63 | "id": "GROUP:0003" 64 | }, 65 | { 66 | "id": "GROUP:0004" 67 | } 68 | ], 69 | "user": { 70 | "id": "USER:0005", 71 | "name": None, 72 | "type": None 73 | } 74 | }, 75 | "max_file_size": 3145728, 76 | "name_max_size": 10009, 77 | "security_flavors": [ 78 | "unix", 79 | "krb5" 80 | ], 81 | "time_delta": 1.0, 82 | "write_datasync_action": "DATASYNC", 83 | "zone": "System" 84 | } 85 | 86 | @staticmethod 87 | def get_nfsdefaultsettings_exception_response(response_type): 88 | if response_type == 'update_exception': 89 | return "Modifying NFS default settings for access zone: System failed with error: SDK Error message" 90 | elif response_type == 'form_dict_exception': 91 | return "Forming modification dict failed with error: " 92 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_node_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2025, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Node module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.node.utils' 12 | 13 | NODE = { 14 | "id": 1, 15 | "lnn": 1, 16 | "partitions": { 17 | "count": 1, 18 | "partitions": [ 19 | { 20 | "block_size": 1024, 21 | "capacity": 1957516, 22 | "component_devices": "ada0p2", 23 | "mount_point": "/", 24 | "percent_used": "50%", 25 | "statfs": { 26 | "f_namemax": 255, 27 | "f_owner": 0, 28 | "f_type": 53, 29 | "f_version": 538182936 30 | }, 31 | "used": 909066 32 | } 33 | ] 34 | } 35 | } 36 | 37 | 38 | def api_exception_msg(): 39 | return 'get node info for PowerScale cluster' 40 | 41 | 42 | def invalid_node_msg(): 43 | return 'Please provide a valid Node Id' 44 | 45 | 46 | def disallow_delete_node_msg(): 47 | return 'Deletion of node is not allowed through Ansible module' 48 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_sdk_response.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock SDKResponse for Unit tests for PowerScale modules""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockSDKResponse: 13 | def __init__(self, data=None, status_code=200): 14 | self.data = data 15 | self.status_code = status_code 16 | 17 | def to_dict(self): 18 | return self.data 19 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_smartpoolsettings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale SmartPool Settings module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.smartpoolsettings.utils' 12 | 13 | GET_SMARTPOOL_SETTINGS = {"settings": {"automatically_manage_io_optimization": "files_at_default", 14 | "automatically_manage_protection": "files_at_default", 15 | "global_namespace_acceleration_enabled": False, 16 | "global_namespace_acceleration_state": "inactive", 17 | "protect_directories_one_level_higher": False, 18 | "spillover_enabled": True, 19 | "tcp_ports": {"id": None, "name": None, "type": "anywhere"}, 20 | "ssd_l3_cache_default_enabled": True, 21 | "ssd_qab_mirrors": "one", 22 | "ssd_system_btree_mirrors": "one", 23 | "ssd_system_delta_mirrors": "one", 24 | "virtual_hot_spare_deny_writes": False, 25 | "virtual_hot_spare_hide_spare": True, 26 | "virtual_hot_spare_limit_drives": 4, 27 | "virtual_hot_spare_limit_percent": 15}} 28 | 29 | UPDATE_SMARTPOOL_SETTINGS = {"smartpool_settings": [{"virtual_hot_spare_limit_percent": 15, 30 | "virtual_hot_spare_hide_spare": True, 31 | "state": "present"}]} 32 | 33 | 34 | def get_networksettings_failed_msg(): 35 | return 'Retrieving details of smartpool settings failed with error:' 36 | 37 | 38 | def modify_networksettings_failed_msg(): 39 | return 'Modifying smartpool settings failed with error:' 40 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_smartquota_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of smartquota module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | from mock.mock import MagicMock 12 | 13 | 14 | class MockSmartQuotaApi: 15 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 16 | PATH1 = "/Test/Test1" 17 | PATH2 = "Test / Test1" 18 | SID = "S-1-5-21-2130" 19 | 20 | SMART_QUOTA_COMMON_ARGS = { 21 | "unispherehost": "**.***.**.***", 22 | "path": None, 23 | "access_zone": None, 24 | "quota_type": None, 25 | "user_name": None, 26 | "group_name": None, 27 | "provider_type": None, 28 | "quota": None, 29 | "list_snapshots": None, 30 | "state": None 31 | } 32 | 33 | @staticmethod 34 | def get_group_details(): 35 | get_quota_response = MagicMock() 36 | get_quota_response.quotas = MagicMock() 37 | get_quota_response.quotas.id = MockSmartQuotaApi.SID 38 | group_details = MagicMock() 39 | group_details.quotas = [ 40 | get_quota_response 41 | ] 42 | return group_details 43 | 44 | @staticmethod 45 | def get_user_sid(): 46 | user1 = MagicMock() 47 | user1.sid = MagicMock() 48 | user1.sid.id = MockSmartQuotaApi.SID 49 | sample_user_response = MagicMock() 50 | sample_user_response.users = [ 51 | user1 52 | ] 53 | return sample_user_response 54 | 55 | @staticmethod 56 | def get_group_sid(): 57 | group1 = MagicMock() 58 | group1.sid = MagicMock() 59 | group1.sid.id = MockSmartQuotaApi.SID 60 | sample_group_response = MagicMock() 61 | sample_group_response.groups = [ 62 | group1 63 | ] 64 | return sample_group_response 65 | 66 | @staticmethod 67 | def smartquota_create_quota_response(path): 68 | return "Create quota for " + path + " failed with" 69 | 70 | @staticmethod 71 | def smartquota_delete_quota_response(path): 72 | return "Delete quota for " + path + " failed with" 73 | 74 | @staticmethod 75 | def smartquota_get_sid_exception(name, az, provider): 76 | return "Failed to get " + name + \ 77 | " details for AccessZone:" + az + " and Provider:" + provider + \ 78 | " with error" 79 | 80 | @staticmethod 81 | def get_smartquota_dependent_response(response_type): 82 | if response_type == 'advisory': 83 | return 3221225472.0 84 | elif response_type == 'hard': 85 | return 10737418240.0 86 | else: 87 | return 5368709120.0 88 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_smb_file_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale SMB file module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.smb_file.utils' 12 | 13 | SmbFile = {'openfiles': [{ 14 | 'file': 'C:\\ifs', 15 | 'id': 1593, 16 | 'locks': 0, 17 | 'permissions': ['read'], 18 | 'user': 'admin'}]} 19 | 20 | 21 | def get_smb_file_failed_msg(): 22 | return 'Getting list of SMB open files failed' 23 | 24 | 25 | def close_smb_file_failed_msg(): 26 | return 'Failed to close smb file' 27 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_smb_global_settings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of SMB global settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockSMBGlobalSettingsApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | 15 | SMB_GLOBAL_COMMON_ARGS = { 16 | "onefs_host": "**.***.**.***", 17 | "verify_ssl": False 18 | } 19 | GET_SMB_GLOBAL_RESPONSE = { 20 | "access_based_share_enum": False, 21 | "dot_snap_accessible_child": True, 22 | "dot_snap_accessible_root": True, 23 | "dot_snap_visible_child": False, 24 | "dot_snap_visible_root": True, 25 | "enable_security_signatures": False, 26 | "guest_user": "nobody", 27 | "ignore_eas": False, 28 | "onefs_cpu_multiplier": 4, 29 | "onefs_num_workers": 0, 30 | "reject_unencrypted_access": False, 31 | "require_security_signatures": False, 32 | "server_side_copy": False, 33 | "server_string": "PowerScale Server", 34 | "service": False, 35 | "support_multichannel": True, 36 | "support_netbios": False, 37 | "support_smb2": True, 38 | "support_smb3_encryption": True 39 | } 40 | 41 | @staticmethod 42 | def get_smb_global_settings_exception_response(response_type): 43 | if response_type == 'get_details_exception': 44 | return "Got error SDK Error message while getting SMB global setings details " 45 | elif response_type == 'update_exception': 46 | return "Modify SMB global settings failed with error: SDK Error message" 47 | elif response_type == 'prereq_exception': 48 | return 'Prerequisite validation failed' 49 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_snapshot_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2025, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock API responses for PowerScale Snapshot module""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.modules.snapshot.utils' 12 | 13 | SNAPSHOT = { 14 | "snapshots": [ 15 | { 16 | "alias": "alias_name_1", 17 | "created": 1628155527, 18 | "expires": 10, 19 | "has_locks": False, 20 | "id": 936, 21 | "name": "ansible_test_snapshot", 22 | "path": "/ifs/ansible_test_snapshot", 23 | "pct_filesystem": 2.435778242215747e-06, 24 | "pct_reserve": 0.0, 25 | "schedule": None, 26 | "shadow_bytes": 0, 27 | "size": 4096, 28 | "state": "active", 29 | "target_id": None, 30 | "target_name": None 31 | } 32 | ] 33 | } 34 | 35 | SNAPSHOT_WO_EXPIRES = { 36 | "snapshots": [ 37 | { 38 | "alias": "alias_name_1", 39 | "created": 1628155527, 40 | "has_locks": False, 41 | "id": 936, 42 | "name": "ansible_test_snapshot", 43 | "path": "/ifs/ansible_test_snapshot", 44 | "pct_filesystem": 2.435778242215747e-06, 45 | "pct_reserve": 0.0, 46 | "schedule": None, 47 | "shadow_bytes": 0, 48 | "size": 4096, 49 | "state": "active", 50 | "target_id": None, 51 | "target_name": None 52 | } 53 | ] 54 | } 55 | 56 | ALIAS = { 57 | "snapshots": [ 58 | { 59 | "target_name": "ansible_test_snapshot", 60 | "name": "alias_name_1" 61 | } 62 | ] 63 | } 64 | 65 | CREATE_SNAPSHOT_PARAMS = { 66 | "name": "ansible_test_snapshot", 67 | "path": "/ifs/ansible_test_snapshot", 68 | "alias": "snap_alias_1", 69 | "expires": 60} 70 | 71 | MODIFY_SNAPSHOT_PARAMS = {"expires": 60} 72 | 73 | RENAME_SNAPSHOT_PARAMS = {"name": "renamed_snapshot_name_1"} 74 | 75 | 76 | def create_snapshot_failed_msg(): 77 | return 'Failed to create snapshot' 78 | 79 | 80 | def modify_snapshot_failed_msg(): 81 | return 'Failed to modify snapshot' 82 | 83 | 84 | def rename_snapshot_failed_msg(): 85 | return 'Failed to rename snapshot' 86 | 87 | 88 | def invalid_access_zone_failed_msg(): 89 | return 'Unable to fetch base path of Access Zone invalid_zone ,failed with error: SDK Error message' 90 | 91 | 92 | def get_snapshot_wo_name_failed_msg(): 93 | return 'Please provide a valid snapshot name' 94 | 95 | 96 | def modify_snapshot_wo_desired_retention_failed_msg(): 97 | return 'Specify desired retention along with retention unit.' 98 | 99 | 100 | def delete_snapshot_exception_failed_msg(): 101 | return 'Failed to delete snapshot' 102 | 103 | 104 | def get_snapshot_alias_failed_msg(): 105 | return 'Failed to get alias for snapshot' 106 | 107 | 108 | def create_snapshot_wo_retention_failed_msg(): 109 | return 'Please provide either desired_retention or expiration_timestamp for creating a snapshot' 110 | 111 | 112 | def create_snapshot_with_new_name_failed_msg(): 113 | return 'Invalid param: new_name while creating a new snapshot.' 114 | 115 | 116 | def create_snapshot_without_path_failed_msg(): 117 | return 'Please provide a valid path for snapshot creation' 118 | 119 | 120 | def create_snapshot_wo_desired_retention_failed_msg(): 121 | return 'Desired retention is set to' 122 | 123 | 124 | def create_snapshot_invalid_desired_retention_failed_msg(): 125 | return 'Please provide a valid integer as the desired retention.' 126 | 127 | 128 | def modify_non_existing_path_failed_msg(): 129 | return 'specified in the playbook does not match the path of the snapshot' 130 | 131 | 132 | def get_snapshot_failed_msg(): 133 | return 'Failed to get details of Snapshot' 134 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_snmp_settings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of SNMP settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockSNMPSettingsApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | SNMP_SETTINGS_COMMON_ARGS = { 15 | 'onefs_host': '**.***.**.***', 16 | 'read_only_community': None, 17 | 'service': None, 18 | 'snmp_v2c_access': None, 19 | 'snmp_v3': None, 20 | 'system_contact': None, 21 | 'system_location': None 22 | } 23 | GET_SNMP_SETTINGS_RESPONSE = { 24 | "read_only_community": "I$ilonpublic", 25 | "service": True, 26 | "snmp_v1_v2c_access": True, 27 | "snmp_v3_access": True, 28 | "snmp_v3_auth_protocol": "SHA", 29 | "snmp_v3_priv_protocol": "AES", 30 | "snmp_v3_read_only_user": "general", 31 | "snmp_v3_security_level": "authNoPriv", 32 | "system_contact": "unset@unset.none", 33 | "system_location": "unset" 34 | } 35 | 36 | @staticmethod 37 | def get_snmpsettings_exception_response(response_type): 38 | if response_type == 'update_exception': 39 | return "Modifying SNMP settings failed with error: SDK Error message" 40 | elif response_type == 'get_resp_exception': 41 | return "Fetching SNMP settings failed with error:" 42 | elif response_type == 'system_contact_exception': 43 | return "Provide valid system_contact parameter." 44 | elif response_type == 'system_location_exception': 45 | return "Provide valid system_location parameter." 46 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_storagepooltier_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of storagepooltier module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_sdk_response import MockSDKResponse 10 | 11 | __metaclass__ = type 12 | 13 | from mock.mock import MagicMock 14 | 15 | 16 | class MockStoragePoolTierApi: 17 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 18 | STORAGE_TIER_COMMON_ARGS = { 19 | 'onefs_host': '**.***.**.***', 20 | 'tier_id': None, 21 | 'tier_name': None, 22 | 'nodepools': [], 23 | 'state': None 24 | } 25 | STORAGE_TIER_LIST = \ 26 | {'tiers': [{'children': ['test_nodepool'], 27 | 'name': 'test_tier', 28 | 'id': 31, 29 | 'lnns': [1, 2, 3]}], 30 | 'total': 1} 31 | NODE_POOL_NAME_LIST = \ 32 | MockSDKResponse({'nodepools': [{'name': 'test_nodepool'}]}) 33 | 34 | @staticmethod 35 | def get_storage_tier_list(): 36 | return MockSDKResponse(MockStoragePoolTierApi.STORAGE_TIER_LIST) 37 | 38 | @staticmethod 39 | def get_storage_tier_create_response(): 40 | create_response = MagicMock() 41 | create_response.id = 32 42 | return create_response 43 | 44 | @staticmethod 45 | def get_storagetier_exception_response(response_type): 46 | if response_type == 'get_details_exception': 47 | return "Fetching storage pool tier details failed with error: SDK Error message" 48 | elif response_type == 'delete_exception': 49 | return "Deleting storage pool tier failed with error: SDK Error message" 50 | elif response_type == 'get_nodepools_exception': 51 | return "Getting list of nodepools names failed with error: SDK Error message" 52 | elif response_type == 'create_tier_exception': 53 | return "Creating storage pool tier failed with error: SDK Error message" 54 | 55 | @staticmethod 56 | def get_storagetier_error_response(response_type): 57 | if response_type == 'modify_error': 58 | return "Storage pool tier modification not supported." 59 | elif response_type == 'tier_name_error': 60 | return "'tier_name' is required to create a storage pool tier" 61 | elif response_type == 'nodepools_error': 62 | return "nodepool's {'test1'} are invalid." 63 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_subnet_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Subnet Api for Subnet Test module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | GENERIC_FAILURE_MSG = " failed with error" 11 | MOCK_IP_ADDRESS_VALUE = '10.*.*.*' 12 | 13 | 14 | def get_subnet_details(subnet_name): 15 | if subnet_name == 'new_subnet': 16 | return None 17 | else: 18 | return {'subnets': [{'addr_family': 'ipv4', 19 | 'base_addr': MOCK_IP_ADDRESS_VALUE, 20 | 'description': 'Initial subnet', 21 | 'dsr_addrs': [], 22 | 'gateway': MOCK_IP_ADDRESS_VALUE, 23 | 'gateway_priority': 10, 24 | 'groupnet': 'groupnet0', 25 | 'id': 'groupnet0.subnet0', 26 | 'mtu': 1500, 27 | 'name': 'subnet0', 28 | 'pools': ['pool0'], 29 | 'prefixlen': 21, 30 | 'sc_service_addrs': [ 31 | { 32 | 'high': MOCK_IP_ADDRESS_VALUE, 33 | 'low': MOCK_IP_ADDRESS_VALUE 34 | } 35 | ], 36 | 'sc_service_name': "", 37 | 'vlan_enabled': False, 38 | 'vlan_id': None}]} 39 | 40 | 41 | def get_invalid_subnet(): 42 | return "The value for subnet_name is invalid" 43 | 44 | 45 | def get_invalid_len(): 46 | return "The maximum length for subnet_name is 32" 47 | 48 | 49 | def get_invalid_desc(): 50 | return "The maximum length for description is 128" 51 | 52 | 53 | def get_invalid_netmask(): 54 | return "Invalid IPV4 address specified for netmask" 55 | 56 | 57 | def get_invalid_gateway_priority(): 58 | return "Please enter a valid value for gateway_priority" 59 | 60 | 61 | def get_invalid_vlan_id(): 62 | return "The minimum value for vlan_id is 2" 63 | 64 | 65 | def get_invalid_gateway(): 66 | return "Invalid address specified for gateway" 67 | 68 | 69 | def get_invalid_sc_ip(): 70 | return "The value for start_range is invalid" 71 | 72 | 73 | def get_subnet_ex_msg(subnet_name): 74 | return "Getting details of subnet " + subnet_name + GENERIC_FAILURE_MSG 75 | 76 | 77 | def modify_subnet_ex_msg(subnet_name): 78 | return "Modifying subnet " + subnet_name + GENERIC_FAILURE_MSG 79 | 80 | 81 | def delete_subnet_ex_msg(subnet_name): 82 | return "Deleting subnet " + subnet_name + GENERIC_FAILURE_MSG 83 | 84 | 85 | def create_subnet_ex_msg(subnet_name): 86 | return "Creating subnet " + subnet_name + GENERIC_FAILURE_MSG 87 | 88 | 89 | def get_invalid_mtu(): 90 | return "The minimum value for mtu is 576" 91 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_synciq_global_settings_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of SyncIQ global settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockSyncIQGlobalSettingsApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | 15 | SYNCIQ_GLOBAL_COMMON_ARGS = { 16 | "onefs_host": "**.***.**.***", 17 | "encryption_required": None, 18 | "service": None 19 | } 20 | GET_SYNCIQ_GLOBAL_RESPONSE = { 21 | "bandwidth_reservation_reserve_absolute": None, 22 | "bandwidth_reservation_reserve_percentage": 1, 23 | "cluster_certificate_id": "1234abc", 24 | "encryption_cipher_list": None, 25 | "encryption_required": False, 26 | "force_interface": False, 27 | "max_concurrent_jobs": 16, 28 | "ocsp_address": "", 29 | "ocsp_issuer_certificate_id": "", 30 | "preferred_rpo_alert": 0, 31 | "renegotiation_period": 28800, 32 | "report_email": [], 33 | "report_max_age": 31536000, 34 | "report_max_count": 2000, 35 | "restrict_target_network": False, 36 | "rpo_alerts": True, 37 | "service": "on", 38 | "service_history_max_age": 31536000, 39 | "service_history_max_count": 2000, 40 | "source_network": None, 41 | "tw_chkpt_interval": None, 42 | "use_workers_per_node": False 43 | } 44 | 45 | @staticmethod 46 | def get_synciq_global_settings_exception_response(response_type): 47 | if response_type == 'get_details_exception': 48 | return "Got error SDK Error message while getting SyncIQ global setings details " 49 | elif response_type == 'update_exception': 50 | return "Modify SyncIQ global settings failed with error: SDK Error message" 51 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_synciqcertificate_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of SyncIQ global settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockSyncIQCertificateApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | 15 | SYNCIQ_CERTIFICATE_COMMON_ARGS = { 16 | "onefs_host": "**.***.**.***", 17 | "certificate_file": "/ifs/server.crt", 18 | "description": "From python", 19 | "alias_name": "Test_1", 20 | "state": 'present', 21 | "certificate_id": "ywqeqwe76898y98wqwe", 22 | "new_alias_name": None 23 | } 24 | 25 | GET_SYNCIQ_CERTIFICATE_RESPONSE = { 26 | "certificates": [ 27 | { 28 | "description": "From python module", 29 | "fingerprints": [ 30 | { 31 | "type": "SHA1", 32 | "value": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:5e:xx:xx:xx:xx:xx:xx:xx:xx" 33 | }, 34 | { 35 | "type": "SHA256", 36 | "value": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:5e:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:" 37 | } 38 | ], 39 | "id": "ywqeqwe76898y98wqwe", 40 | "issuer": "C=AU, ST=Some-State, O=Internet Widgits Pty Ltd", 41 | "name": "Sample", 42 | "not_after": 1753465054, 43 | "not_before": 1690393054, 44 | "status": "valid", 45 | "subject": "C=AU, ST=Some-State, O=Internet Widgits Pty Ltd" 46 | } 47 | ] 48 | } 49 | 50 | CREATE_CERTIFICATE_ID = {"id": "ywqeqwe76898y98wqwe"} 51 | 52 | MODIFY_CERTIFICATE_DETAILS = { 53 | "description": "new_description", 54 | "fingerprints": [ 55 | { 56 | "type": "SHA1", 57 | "value": "xx:xx:xx:xx:xx:xx:84:xx:56:xx:xx:5e:xx:xx:xx:xx:xx:xx:xx:xx" 58 | }, 59 | { 60 | "type": "SHA256", 61 | "value": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:5e:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:94:44:xx:xx:xx:xx:xx:" 62 | } 63 | ], 64 | "id": "ywqeqwe76898yadasdsad98wqwe", 65 | "issuer": "C=AU, ST=Some-State1, O=Internet of things Widgits Pvt Ltd", 66 | "name": "new_name", 67 | "not_after": 1753465054, 68 | "not_before": 1690393054, 69 | "status": "valid", 70 | "subject": "C=AU, ST=Some-State1, O=Internet of things Widgits Pvt Ltd" 71 | } 72 | 73 | @staticmethod 74 | def get_synciq_certificate_exception_response(response_type): 75 | if response_type == 'get_details_exception': 76 | return "Fetching SyncIQ certificate failed with error:" 77 | elif response_type == 'import_exception': 78 | return "Importing SyncIQ target certificate failed with error:" 79 | elif response_type == 'delete_exception': 80 | return "Deleting SyncIQ target certificate failed with error:" 81 | elif response_type == 'update_exception': 82 | return "Updating SyncIQ target certificate details failed with error:" 83 | elif response_type == 'get_certificate_exception': 84 | return "Getting SyncIQ target certificate failed with error:" 85 | else: 86 | return "certificate_file and alias_name are required for Import certificate operation." 87 | 88 | @staticmethod 89 | def import_certificate_format_error_msg(): 90 | return "File format is not supported" 91 | 92 | @staticmethod 93 | def alias_name_error_msg(param): 94 | return "The value for " + param + " is invalid" 95 | 96 | @staticmethod 97 | def description_error_msg(): 98 | return "The maximum length for description is 128" 99 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_synciqpolicy_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of synciqpolicy module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockSynciqpolicyApi: 13 | MODULE_UTILS_PATH = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils' 14 | SYNCIQPOLICY_COMMON_ARGS = { 15 | 'onefs_host': '**.***.**.***', 16 | 'policy_name': '', 17 | 'policy_id': '', 18 | 'schedule': '', 19 | 'run_job': '', 20 | 'rpo_alert': '', 21 | 'rpo_alert_unit': '', 22 | 'target_snapshot': '', 23 | 'job_delay': '', 24 | 'job_delay_unit': '', 25 | 'job_params': '', 26 | 'target_cluster': '', 27 | 'source_cluster': '', 28 | 'state': 'present' 29 | } 30 | 31 | CREATE_ARGS = { 32 | "action": "sync", 33 | "description": "Creating a policy", 34 | "enabled": False, 35 | "policy_name": "Policy1", 36 | "run_job": "when-source-modified", 37 | "job_delay": 10, 38 | "job_delay_unit": "hours", 39 | "source_cluster": { 40 | "source_root_path": "/test", 41 | "source_exclude_directories": "/test/abc2", 42 | "source_include_directories": [ 43 | "/test/abc1" 44 | ], 45 | "source_network": { 46 | "pool": "pool0", 47 | "subnet": "subnet0" 48 | } 49 | }, 50 | "target_cluster": { 51 | "target_host": "xx.xx.xx.xx", 52 | "target_path": "/test/system", 53 | "target_certificate_id": "xxxxxxx" 54 | }, 55 | "target_snapshot": { 56 | "target_snapshot_archive": True, 57 | "target_snapshot_expiration": 90, 58 | "exp_time_unit": "days" 59 | }, 60 | "state": "present" 61 | } 62 | 63 | DELETE_ARGS = {"policy_name": "Policy1", "state": "absent"} 64 | 65 | JOB_ARGS1 = { 66 | "job_params": { 67 | "workers_per_node": 3, 68 | "action": "allow_write", 69 | "source_snapshot": "test_snap", 70 | "wait_for_completion": False 71 | } 72 | } 73 | 74 | JOB_ARGS2 = { 75 | "job_params": { 76 | "action": "run", 77 | "source_snapshot": "test_snap", 78 | "wait_for_completion": True 79 | } 80 | } 81 | 82 | JOB_ARGS3 = { 83 | "job_params": { 84 | "workers_per_node": 3, 85 | "action": "run", 86 | "source_snapshot": "test_snap", 87 | "wait_for_completion": True 88 | } 89 | } 90 | 91 | JOB_ARGS4 = { 92 | "job_params": { 93 | "workers_per_node": 0, 94 | "action": "allow_write", 95 | "source_snapshot": "test_snap", 96 | "wait_for_completion": True 97 | } 98 | } 99 | 100 | GET_ARGS = {"policy_name": "Policy1"} 101 | 102 | GET_ARGS2 = {} 103 | GET_ARGS2.update(GET_ARGS) 104 | GET_ARGS2.update({"policy_id": 23}) 105 | 106 | CREATE_ARGS2 = CREATE_ARGS.copy() 107 | CREATE_ARGS2["run_job"] = "manual" 108 | 109 | CREATE_JOB_ARGS = {} 110 | CREATE_JOB_ARGS.update(CREATE_ARGS) 111 | CREATE_JOB_ARGS.update(JOB_ARGS1) 112 | 113 | POLICY_ID = 'xx' 114 | EXCEPTION_MSG = "SyncIQ policy" 115 | CERT_NAME = "cert1" 116 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/mock_writable_snapshots_api.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Mock Api response for Unit tests of writable snapshots module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | class MockWritableSanpshotsApi: 13 | WS_COMMON_ARGS = {"onefs_host": "XX.XX.XX.XX", 14 | "port_no": "8080", 15 | "verify_ssl": "false" 16 | } 17 | DSTPATH = "/ifs/ansible8/" 18 | WS_CREATE_ARGS = {"writable_snapshots": [{"src_snap": 2, "dst_path": DSTPATH, "state": "present"}]} 19 | WS_CREATE_ARGS_STR = {"writable_snapshots": [{"src_snap": "snap-2", "dst_path": DSTPATH, "state": "present"}]} 20 | WS_DELETE_ARGS = {"writable_snapshots": [{"src_snap": 2, "dst_path": DSTPATH, "state": "absent"}]} 21 | WS_INVALID_DSTPATH_ARGS = {"writable_snapshots": [{"src_snap": "invalid", "dst_path": DSTPATH, "state": "present"}]} 22 | 23 | @staticmethod 24 | def get_writeable_snpshots_error_response(response_type): 25 | dst_path = MockWritableSanpshotsApi.DSTPATH 26 | if response_type == 'delete_exception': 27 | return f"Failed to delete snapshot: {dst_path} with error" 28 | elif response_type == 'create_exception': 29 | return f"Failed to create writable snapshot: {dst_path} with error: SDK Error message" 30 | elif response_type == 'invalid_dstpath': 31 | return "Few writable snapshots are not able to be created because the destination path or source path is invalid." 32 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/shared_library/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/tests/unit/plugins/module_utils/shared_library/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/shared_library/initial_mock.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | from mock.mock import MagicMock 9 | from ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell \ 10 | import utils 11 | 12 | utils.get_logger = MagicMock() 13 | utils.isi_sdk = MagicMock() 14 | utils.ISI_SDK_VERSION_9 = MagicMock(return_value=True) 15 | PREREQS_VALIDATE = { 16 | "all_packages_found": True 17 | } 18 | utils.validate_module_pre_reqs = MagicMock(return_value=PREREQS_VALIDATE) 19 | from ansible.module_utils import basic 20 | basic.AnsibleModule = MagicMock() 21 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/shared_library/powerscale_unit_base.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | 7 | __metaclass__ = type 8 | import copy 9 | import pytest 10 | from mock.mock import MagicMock 11 | 12 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_api_exception \ 13 | import MockApiException 14 | 15 | 16 | class PowerScaleUnitBase: 17 | 18 | '''Powerscale Unit Test Base Class''' 19 | 20 | @pytest.fixture(autouse=True) 21 | def powerscale_module_mock(self, mocker, module_object): 22 | exception_class_path = 'ansible_collections.dellemc.powerscale.plugins.module_utils.storage.dell.utils.ApiException' 23 | mocker.patch(exception_class_path, new=MockApiException) 24 | self.powerscale_module_mock = module_object() 25 | self.powerscale_module_mock.module = MagicMock() 26 | self.powerscale_module_mock.module.fail_json = MagicMock( 27 | side_effect=SystemExit) 28 | self.powerscale_module_mock.module.check_mode = False 29 | return self.powerscale_module_mock 30 | 31 | def capture_fail_json_call(self, error_msg, module_handler=None, invoke_perform_module=False): 32 | with pytest.raises(SystemExit): 33 | if not invoke_perform_module: 34 | module_handler().handle(self.powerscale_module_mock, 35 | self.powerscale_module_mock.module.params) 36 | else: 37 | self.powerscale_module_mock.perform_module_operation() 38 | self.powerscale_module_mock.module.fail_json.assert_called() 39 | call_args = self.powerscale_module_mock.module.fail_json.call_args.kwargs 40 | assert error_msg in call_args['msg'] 41 | 42 | def capture_fail_json_method(self, error_msg, module_mock, function_name, *args, **kwargs): 43 | with pytest.raises(SystemExit): 44 | func = getattr(module_mock, function_name) 45 | func(*args, **kwargs) 46 | self.powerscale_module_mock.module.fail_json.assert_called() 47 | call_args = self.powerscale_module_mock.module.fail_json.call_args.kwargs 48 | assert error_msg in call_args['msg'] 49 | 50 | def set_module_params(self, get_module_args, params, deep_copy=True): 51 | if deep_copy: 52 | get_module_args = copy.deepcopy(get_module_args) 53 | get_module_args.update(params) 54 | self.powerscale_module_mock.module.params = get_module_args 55 | -------------------------------------------------------------------------------- /tests/unit/plugins/module_utils/test_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Utils for PowerScale Test modules""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | import random 12 | import string 13 | 14 | 15 | def get_desc(length): 16 | desc = '' 17 | while (length > 0): 18 | desc += random.choice(string.ascii_letters) 19 | length -= 1 20 | return desc 21 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/__init__: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/tests/unit/plugins/modules/__init__ -------------------------------------------------------------------------------- /tests/unit/plugins/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/ansible-powerscale/cd646cb2e5223f8ee59a8608a13aad09ab29d978/tests/unit/plugins/modules/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/modules/test_alert_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Unit Tests for Alert Setting module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | import pytest 12 | from mock.mock import MagicMock 13 | # pylint: disable=unused-import 14 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.initial_mock \ 15 | import utils 16 | 17 | from ansible_collections.dellemc.powerscale.plugins.modules.alert_settings import AlertSettings, AlertSettingsModifyHandler, main 18 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_alert_settings_api import MockAlertSettingsApi 19 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_api_exception \ 20 | import MockApiException 21 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.powerscale_unit_base \ 22 | import PowerScaleUnitBase 23 | 24 | 25 | class TestAlertSettings(PowerScaleUnitBase): 26 | alert_args = MockAlertSettingsApi.ALERT_COMMON_ARGS 27 | 28 | @pytest.fixture 29 | def module_object(self): 30 | """ 31 | Returns an instance of the `AlertSettings` class for testing purposes. 32 | 33 | :return: An instance of the `AlertSettings` class. 34 | :rtype: `AlertSettings` 35 | """ 36 | return AlertSettings 37 | 38 | def test_get_alert_settings_response(self, powerscale_module_mock): 39 | self.set_module_params(self.alert_args, {}) 40 | AlertSettingsModifyHandler().handle(powerscale_module_mock, 41 | powerscale_module_mock.module.params) 42 | powerscale_module_mock.event_api.get_event_maintenance.assert_called() 43 | 44 | def test_get_alert_settings_exception(self, powerscale_module_mock): 45 | self.set_module_params(self.alert_args, {}) 46 | powerscale_module_mock.event_api.get_event_maintenance = MagicMock( 47 | side_effect=MockApiException) 48 | self.capture_fail_json_call( 49 | MockAlertSettingsApi.get_alert_exception_response('get_alert'), 50 | AlertSettingsModifyHandler) 51 | 52 | def test_modify_maintenance_mode(self, powerscale_module_mock): 53 | self.set_module_params(self.alert_args, 54 | {"enable_celog_maintenance_mode": True, "prune": 10}) 55 | powerscale_module_mock.get_alert_settings_details = MagicMock( 56 | return_value=MockAlertSettingsApi.SETTING_DETAILS) 57 | powerscale_module_mock.isi_sdk.EventMaintenanceExtended = MagicMock( 58 | {"maintenance": True, "prune": 10}) 59 | AlertSettingsModifyHandler().handle(powerscale_module_mock, 60 | powerscale_module_mock.module.params) 61 | powerscale_module_mock.event_api.update_event_maintenance.assert_called() 62 | 63 | def test_modify_maintenance_mode_exception(self, powerscale_module_mock): 64 | self.set_module_params(self.alert_args, 65 | {"enable_celog_maintenance_mode": True, "prune": 10}) 66 | powerscale_module_mock.get_alert_settings_details = MagicMock( 67 | return_value=MockAlertSettingsApi.SETTING_DETAILS) 68 | powerscale_module_mock.isi_sdk.EventMaintenanceExtended = MagicMock( 69 | side_effect=MockApiException) 70 | self.capture_fail_json_call( 71 | MockAlertSettingsApi.get_alert_exception_response( 72 | 'modify_exp'), 73 | AlertSettingsModifyHandler) 74 | 75 | def test_main(self, powerscale_module_mock): 76 | main() 77 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/test_networksettings.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2021-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Unit Tests for Network Settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | import pytest 12 | from mock.mock import MagicMock 13 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.initial_mock \ 14 | import utils 15 | 16 | 17 | from ansible_collections.dellemc.powerscale.plugins.modules.networksettings import NetworkSettings 18 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.\ 19 | module_utils import mock_networksettings_api as MockNetworkSettingsApi 20 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_sdk_response \ 21 | import MockSDKResponse 22 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.powerscale_unit_base import \ 23 | PowerScaleUnitBase 24 | 25 | 26 | class TestNetworkSettings(PowerScaleUnitBase): 27 | get_network_settings_args = {"enable_source_routing": None, 28 | "state": None} 29 | 30 | @pytest.fixture 31 | def module_object(self, mocker): 32 | return NetworkSettings 33 | 34 | def test_get_network_setting(self, powerscale_module_mock): 35 | self.get_network_settings_args.update({"state": "present"}) 36 | powerscale_module_mock.module.params = self.get_network_settings_args 37 | powerscale_module_mock.network_api.get_network_external = MagicMock( 38 | return_value=MockSDKResponse(MockNetworkSettingsApi.GET_NETWORK_SETTINGS)) 39 | powerscale_module_mock.perform_module_operation() 40 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] is False 41 | 42 | def test_get_network_settings_with_exception(self, powerscale_module_mock): 43 | self.get_network_settings_args.update({"state": "present"}) 44 | powerscale_module_mock.module.params = self.get_network_settings_args 45 | powerscale_module_mock.network_api.get_network_external = MagicMock(side_effect=utils.ApiException) 46 | self.capture_fail_json_call(MockNetworkSettingsApi.get_networksettings_failed_msg(), invoke_perform_module=True) 47 | 48 | def test_modify_network_settings(self, powerscale_module_mock): 49 | self.get_network_settings_args.update({"state": "present", "enable_source_routing": True}) 50 | powerscale_module_mock.module.params = self.get_network_settings_args 51 | powerscale_module_mock.network_api.update_network_external = MagicMock( 52 | return_value=MockSDKResponse(MockNetworkSettingsApi.UPDATE_NETWORK_SETTINGS)) 53 | powerscale_module_mock.perform_module_operation() 54 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] 55 | 56 | def test_modify_network_settings_with_exception(self, powerscale_module_mock): 57 | self.get_network_settings_args.update({"state": "present", "enable_source_routing": True}) 58 | powerscale_module_mock.module.params = self.get_network_settings_args 59 | powerscale_module_mock.network_api.update_network_external = MagicMock(side_effect=utils.ApiException) 60 | self.capture_fail_json_call(MockNetworkSettingsApi.modify_networksettings_failed_msg(), 61 | invoke_perform_module=True) 62 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/test_nfs_global_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Unit Tests for NFS global settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | import pytest 12 | from mock.mock import MagicMock 13 | # pylint: disable=unused-import 14 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.initial_mock \ 15 | import utils 16 | 17 | from ansible_collections.dellemc.powerscale.plugins.modules.nfs_global_settings import NFSGlobalSettings 18 | from ansible_collections.dellemc.powerscale.plugins.modules.nfs_global_settings import NFSGlobalSettingsHandler 19 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_nfs_global_settings_api \ 20 | import MockNFSGlobalSettingsApi 21 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_api_exception \ 22 | import MockApiException 23 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.powerscale_unit_base import \ 24 | PowerScaleUnitBase 25 | 26 | 27 | class TestNFSGlobalSettings(PowerScaleUnitBase): 28 | nfs_global_args = MockNFSGlobalSettingsApi.NFS_GLOBAL_COMMON_ARGS 29 | 30 | @pytest.fixture 31 | def module_object(self): 32 | return NFSGlobalSettings 33 | 34 | def test_get_nfs_global_details(self, powerscale_module_mock): 35 | self.nfs_global_args.update({ 36 | }) 37 | powerscale_module_mock.module.params = self.nfs_global_args 38 | NFSGlobalSettingsHandler().handle(powerscale_module_mock, powerscale_module_mock.module.params) 39 | powerscale_module_mock.protocol_api.get_nfs_settings_global.assert_called() 40 | 41 | def test_get_nfs_global_details_exception(self, powerscale_module_mock): 42 | self.nfs_global_args.update({}) 43 | powerscale_module_mock.module.params = self.nfs_global_args 44 | powerscale_module_mock.protocol_api.get_nfs_settings_global = MagicMock( 45 | side_effect=MockApiException) 46 | self.capture_fail_json_call( 47 | MockNFSGlobalSettingsApi.get_nfs_global_settings_exception_response('get_details_exception'), 48 | NFSGlobalSettingsHandler) 49 | 50 | def test_modify_nfs_global_response(self, powerscale_module_mock): 51 | self.nfs_global_args.update({ 52 | "service": True, 53 | "nfsv3": {"nfsv3_enabled": True, "nfsv3_rdma_enabled": None}, 54 | "nfsv4": { 55 | "nfsv4_enabled": True, 56 | "nfsv40_enabled": False, 57 | "nfsv41_enabled": None, 58 | "nfsv42_enabled": True 59 | } 60 | }) 61 | powerscale_module_mock.module.params = self.nfs_global_args 62 | powerscale_module_mock.get_nfs_global_settings_details = MagicMock( 63 | return_value=MockNFSGlobalSettingsApi.GET_NFS_GLOBAL_RESPONSE) 64 | NFSGlobalSettingsHandler().handle(powerscale_module_mock, 65 | powerscale_module_mock.module.params) 66 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] is True 67 | powerscale_module_mock.protocol_api.update_nfs_settings_global.assert_called() 68 | 69 | def test_modify_nfs_global_exception(self, powerscale_module_mock): 70 | self.nfs_global_args.update({ 71 | "service": True, 72 | "nfsv3": {"nfsv3_enabled": True, "nfsv3_rdma_enabled": None}, 73 | "nfsv4": { 74 | "nfsv4_enabled": True, 75 | "nfsv40_enabled": False, 76 | "nfsv41_enabled": None, 77 | "nfsv42_enabled": True 78 | } 79 | }) 80 | powerscale_module_mock.module.params = self.nfs_global_args 81 | powerscale_module_mock.get_nfs_global_settings_details = MagicMock( 82 | return_value=MockNFSGlobalSettingsApi.GET_NFS_GLOBAL_RESPONSE) 83 | powerscale_module_mock.protocol_api.update_nfs_settings_global = MagicMock( 84 | side_effect=MockApiException) 85 | self.capture_fail_json_call( 86 | MockNFSGlobalSettingsApi.get_nfs_global_settings_exception_response('update_exception'), 87 | NFSGlobalSettingsHandler) 88 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/test_node.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2025, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Unit Tests for Node module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | import pytest 12 | from mock.mock import MagicMock 13 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.initial_mock \ 14 | import utils 15 | 16 | 17 | from ansible_collections.dellemc.powerscale.plugins.modules.node import ClusterNode, main 18 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.\ 19 | module_utils import mock_node_api as MockNodeApi 20 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.powerscale_unit_base import \ 21 | PowerScaleUnitBase 22 | 23 | 24 | class TestClusterNode(PowerScaleUnitBase): 25 | get_node_args = { 26 | 'node_id': None, 27 | } 28 | 29 | @pytest.fixture 30 | def module_object(self): 31 | return ClusterNode 32 | 33 | def test_get_node_info(self, powerscale_module_mock): 34 | self.get_node_args.update({ 35 | 'node_id': 1, 36 | 'state': 'present', 37 | 'onefs_host': '1.2.3.4' 38 | }) 39 | ob = MagicMock() 40 | ob.node_info = { 41 | 'id': 1, 42 | 'lnn': 1, 43 | 'partitions': { 44 | 'count': 1, 45 | 'partitions': [ 46 | { 47 | 'block_size': 1024, 48 | 'capacity': 1957516, 49 | 'component_devices': 'ada0p2', 50 | 'mount_point': '/', 51 | 'percent_used': '50%', 52 | 'statfs': { 53 | 'f_namemax': 255, 54 | 'f_owner': 0, 55 | 'f_type': 53, 56 | 'f_version': 538182936 57 | }, 58 | 'used': 909066 59 | } 60 | ] 61 | } 62 | } 63 | powerscale_module_mock.module.params = self.get_node_args 64 | powerscale_module_mock.cluster_api.get_cluster_node = MagicMock( 65 | return_value=ob) 66 | powerscale_module_mock.perform_module_operation() 67 | 68 | assert ( 69 | powerscale_module_mock.module.exit_json.call_args[1]['cluster_node_details']) 70 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] is False 71 | 72 | # Scenario 2: When exception occured 73 | powerscale_module_mock.cluster_api.get_cluster_node = \ 74 | MagicMock(side_effect=utils.ApiException) 75 | 76 | self.capture_fail_json_call(MockNodeApi.api_exception_msg(), invoke_perform_module=True) 77 | 78 | def test_get_node_info_absent(self, powerscale_module_mock): 79 | self.get_node_args.update({ 80 | 'node_id': 1, 81 | 'state': 'absent', 82 | }) 83 | powerscale_module_mock.module.params = self.get_node_args 84 | powerscale_module_mock.cluster_api.get_cluster_node = MagicMock( 85 | return_value={}) 86 | self.capture_fail_json_call(MockNodeApi.disallow_delete_node_msg(), invoke_perform_module=True) 87 | 88 | def test_main(self): 89 | ob = main() 90 | assert ob is None # nothing to assert as it doesn't return anything 91 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/test_smartpoolsettings.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2022-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Unit Tests for Smartpool Settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | 12 | import pytest 13 | from mock.mock import MagicMock 14 | # pylint: disable=unused-import 15 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.initial_mock \ 16 | import utils 17 | 18 | 19 | from ansible_collections.dellemc.powerscale.plugins.modules.smartpoolsettings import SmartPoolSettings 20 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.\ 21 | module_utils import mock_smartpoolsettings_api as MockSmartPoolSettingsApi 22 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_sdk_response \ 23 | import MockSDKResponse 24 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_api_exception \ 25 | import MockApiException 26 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.powerscale_unit_base import \ 27 | PowerScaleUnitBase 28 | 29 | 30 | class TestSmartPoolSettings(PowerScaleUnitBase): 31 | get_smartpool_settings_args = {"virtual_hot_spare_limit_percent": None, 32 | "virtual_hot_spare_hide_spare": None, 33 | "state": None} 34 | 35 | @pytest.fixture 36 | def module_object(self, mocker): 37 | return SmartPoolSettings 38 | 39 | def test_get_smartpool_setting(self, powerscale_module_mock): 40 | self.get_smartpool_settings_args.update({"state": "present"}) 41 | powerscale_module_mock.module.params = self.get_smartpool_settings_args 42 | powerscale_module_mock.storagepool_api.get_storagepool_settings = MagicMock( 43 | return_value=MockSDKResponse(MockSmartPoolSettingsApi.GET_SMARTPOOL_SETTINGS)) 44 | powerscale_module_mock.perform_module_operation() 45 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] is False 46 | 47 | def test_get_smartpool_setting_with_exception(self, powerscale_module_mock): 48 | self.get_smartpool_settings_args.update({"state": "present"}) 49 | powerscale_module_mock.module.params = self.get_smartpool_settings_args 50 | powerscale_module_mock.storagepool_api.get_storagepool_settings = MagicMock(side_effect=utils.ApiException) 51 | self.capture_fail_json_call(MockSmartPoolSettingsApi.get_networksettings_failed_msg(), 52 | invoke_perform_module=True) 53 | 54 | def test_modify_smartpool_settings(self, powerscale_module_mock): 55 | self.get_smartpool_settings_args.update({"state": "present", "virtual_hot_spare_limit_percent": 10, "virtual_hot_spare_hide_spare": True}) 56 | powerscale_module_mock.module.params = self.get_smartpool_settings_args 57 | powerscale_module_mock.storagepool_api.update_storagepool_settings = MagicMock( 58 | return_value=MockSDKResponse(MockSmartPoolSettingsApi.UPDATE_SMARTPOOL_SETTINGS)) 59 | powerscale_module_mock.perform_module_operation() 60 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] 61 | 62 | def test_modify_smartpool_settings_with_exception(self, powerscale_module_mock): 63 | self.get_smartpool_settings_args.update({"state": "present", "virtual_hot_spare_limit_percent": 10, "virtual_hot_spare_hide_spare": True}) 64 | powerscale_module_mock.module.params = self.get_smartpool_settings_args 65 | powerscale_module_mock.storagepool_api.update_storagepool_settings = MagicMock(side_effect=utils.ApiException) 66 | self.capture_fail_json_call(MockSmartPoolSettingsApi.modify_networksettings_failed_msg(), 67 | invoke_perform_module=True) 68 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/test_synciq_global_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright: (c) 2023-2024, Dell Technologies 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | """Unit Tests for SyncIQ global settings module on PowerScale""" 6 | 7 | from __future__ import (absolute_import, division, print_function) 8 | 9 | __metaclass__ = type 10 | 11 | import pytest 12 | from mock.mock import MagicMock 13 | # pylint: disable=unused-import 14 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.initial_mock \ 15 | import utils 16 | 17 | from ansible_collections.dellemc.powerscale.plugins.modules.synciq_global_settings import SyncIQGlobalSettings 18 | from ansible_collections.dellemc.powerscale.plugins.modules.synciq_global_settings import SyncIQGlobalSettingsHandler 19 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_synciq_global_settings_api \ 20 | import MockSyncIQGlobalSettingsApi 21 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.mock_api_exception \ 22 | import MockApiException 23 | from ansible_collections.dellemc.powerscale.tests.unit.plugins.module_utils.shared_library.powerscale_unit_base \ 24 | import PowerScaleUnitBase 25 | 26 | 27 | class TestSyncIQGlobalSettings(PowerScaleUnitBase): 28 | synciq_global_args = MockSyncIQGlobalSettingsApi.SYNCIQ_GLOBAL_COMMON_ARGS 29 | 30 | @pytest.fixture 31 | def module_object(self): 32 | return SyncIQGlobalSettings 33 | 34 | def test_get_synciq_global_details(self, powerscale_module_mock): 35 | self.set_module_params(self.synciq_global_args, {}) 36 | SyncIQGlobalSettingsHandler().handle(powerscale_module_mock, powerscale_module_mock.module.params) 37 | powerscale_module_mock.synciq_api.get_sync_settings.assert_called() 38 | 39 | def test_get_synciq_global_details_exception(self, powerscale_module_mock): 40 | self.set_module_params(self.synciq_global_args, {}) 41 | powerscale_module_mock.synciq_api.get_sync_settings = MagicMock( 42 | side_effect=MockApiException) 43 | self.capture_fail_json_call( 44 | MockSyncIQGlobalSettingsApi.get_synciq_global_settings_exception_response('get_details_exception'), 45 | SyncIQGlobalSettingsHandler) 46 | 47 | def test_modify_synciq_global_response(self, powerscale_module_mock): 48 | self.set_module_params(self.synciq_global_args, 49 | {"service": 'on', 50 | "encryption_required": False}) 51 | powerscale_module_mock.get_synciq_global_settings_details = MagicMock( 52 | return_value=MockSyncIQGlobalSettingsApi.GET_SYNCIQ_GLOBAL_RESPONSE) 53 | powerscale_module_mock.module.check_mode = False 54 | powerscale_module_mock.is_synciq_global_modify_required = MagicMock() 55 | SyncIQGlobalSettingsHandler().handle(powerscale_module_mock, 56 | powerscale_module_mock.module.params) 57 | assert powerscale_module_mock.module.exit_json.call_args[1]['changed'] is True 58 | powerscale_module_mock.synciq_api.update_sync_settings.assert_called() 59 | 60 | def test_modify_synciq_global_exception(self, powerscale_module_mock): 61 | self.set_module_params(self.synciq_global_args, 62 | {"service": 'on', 63 | "encryption_required": False}) 64 | powerscale_module_mock.get_synciq_global_settings_details = MagicMock( 65 | return_value=MockSyncIQGlobalSettingsApi.GET_SYNCIQ_GLOBAL_RESPONSE) 66 | powerscale_module_mock.synciq_api.update_sync_settings = MagicMock( 67 | side_effect=MockApiException) 68 | self.capture_fail_json_call( 69 | MockSyncIQGlobalSettingsApi.get_synciq_global_settings_exception_response('update_exception'), SyncIQGlobalSettingsHandler) 70 | -------------------------------------------------------------------------------- /tests/unit/requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | pytest-xdist 3 | mock 4 | pytest-mock 5 | pytest-cov 6 | pytest-forked 7 | coverage 8 | setuptools 9 | --------------------------------------------------------------------------------