├── book.json ├── ansible.cfg ├── .gitignore ├── .devcontainer ├── devcontainer.json ├── Dockerfile └── start.sh ├── .github ├── ISSUE_TEMPLATE │ ├── enhancement_request.md │ └── bug-report.md └── pull_request_template.md ├── CHANGELOG.md ├── rubrikinc └── cdm │ ├── galaxy.yml │ ├── docs │ ├── SUMMARY.md │ ├── rubrik_module_template.py │ ├── create_documentation_block.py │ ├── rubrik_cluster_version.md │ ├── rubrik_get_vsphere_live_mount.md │ ├── rubrik_get_vsphere_live_mount_names.md │ ├── rubrik_refresh_vcenter.md │ ├── rubrik_dns_servers.md │ ├── rubrik_login_banner.md │ ├── rubrik_get_sql_live_mount.md │ ├── rubrik_post.md │ ├── rubrik_get.md │ ├── rubrik_job_status.md │ ├── rubrik_vsphere_live_unmount.md │ ├── rubrik_add_organization_protectable_object_mssql_server_host.md │ ├── rubrik_sql_live_unmount.md │ ├── rubrik_end_user_authorization.md │ ├── rubrik_add_organization_protectable_object_sql_server_availability_group.md │ ├── template.md │ ├── rubrik_add_organization_protectable_object_sql_server_db.md │ └── rubrik_sql_live_mount.md │ ├── README.md │ ├── plugins │ └── modules │ │ ├── rubrik_cluster_version.py │ │ ├── rubrik_get_vsphere_live_mount.py │ │ ├── rubrik_get_vsphere_live_mount_names.py │ │ ├── rubrik_configure_cluster_location.py │ │ ├── rubrik_dns_servers.py │ │ ├── rubrik_login_banner.py │ │ ├── rubrik_vsphere_live_unmount.py │ │ ├── rubrik_get_sql_live_mount.py │ │ ├── rubrik_configure_ntp.py │ │ ├── rubrik_job_status.py │ │ ├── rubrik_post.py │ │ ├── rubrik_refresh_vcenter.py │ │ ├── rubrik_sql_live_unmount.py │ │ ├── rubrik_add_organization_protectable_object_mssql_server_host.py │ │ ├── rubrik_get.py │ │ ├── rubrik_add_organization_protectable_object_sql_server_availability_group.py │ │ ├── rubrik_sql_live_mount.py │ │ ├── rubrik_add_organization_protectable_object_sql_server_db.py │ │ └── rubrik_end_user_authorization.py │ └── tests │ ├── unit │ ├── test_rubrik_cluster_version.py │ ├── test_rubrik_get.py │ ├── test_rubrik_post.py │ ├── test_rubrik_dns_servers.py │ ├── test_rubrik_login_banner.py │ ├── test_rubrik_refresh_vcenter.py │ └── test_rubrik_job_status.py │ └── sanity │ └── ignore.txt ├── library ├── rubrik_host_facts.py ├── rubrik_vmware_vcenter.py ├── rubrik_vcenter_refresh.py └── rubrik_vm_register.py ├── CONTRIBUTING.md ├── README.md ├── collection_dev.py └── CODE_OF_CONDUCT.md /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": "./rubrikinc/cdm/docs" 3 | } -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | 3 | library = ./rubrikinc/cdm/plugins/modules 4 | module_utils = ./rubrikinc/cdm/plugins/module_utils 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dev.yml 2 | .pytest_cache/v/cache/nodeids 3 | ansible.cfg 4 | demo.yml 5 | dev.py 6 | hosts 7 | variables.yml 8 | .vscode/settings.json 9 | .DS_Store 10 | */__pycache__ 11 | */.pytest_cache 12 | *.pyc 13 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Rubrik Ansible Module Development", 3 | "dockerFile": "Dockerfile", 4 | "context": "..", 5 | "extensions": [ 6 | "ms-python.python", 7 | "njpwerner.autodocstring", 8 | "github.vscode-pull-request-github", 9 | "bierner.markdown-preview-github-styles", 10 | "josa.markdown-table-formatter", 11 | "mrmlnc.vscode-duplicate", 12 | "codezombiech.gitignore" 13 | ], 14 | "postCreateCommand": "chmod +x .devcontainer/start.sh && . .devcontainer/start.sh", 15 | "settings": { 16 | "terminal.integrated.shell.linux": "/bin/zsh", 17 | "python.pythonPath": "/usr/local/bin/python", 18 | "python.linting.pylintEnabled": true, 19 | "python.linting.pylintPath": "/usr/local/bin/pylint", 20 | "python.linting.enabled": true, 21 | "python.formatting.autopep8Path": "/usr/local/bin/pylint/autopep8" 22 | } 23 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement Request 3 | about: Suggest an enhancement to the Rubrik Modules for Ansible 4 | title: '' 5 | labels: kind-enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | **Is your feature request related to a problem? Please describe.** 13 | 14 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 15 | 16 | **Describe the solution you'd like** 17 | 18 | A clear and concise description of what you want to happen. 19 | 20 | **Describe alternatives you've considered** 21 | 22 | A clear and concise description of any alternative solutions or features you've considered. 23 | 24 | **Additional context** 25 | 26 | Add any other context or screenshots about the feature request here. 27 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## Types of changes 9 | 10 | - **Added** for new features. 11 | - **Changed** for changes in existing functionality. 12 | - **Deprecated** for soon-to-be removed features. 13 | - **Removed** for now removed features. 14 | - **Fixed** for any bug fixes. 15 | - **Security** in case of vulnerabilities. 16 | 17 | ## v1.0.6 18 | 19 | ### Added 20 | 21 | - `rubrik_add_organization_protectable_object_mssql_server_host` 22 | - `rubrik_add_organization_protectable_object_sql_server_availability_group` 23 | - `rubrik_add_organization_protectable_object_sql_server_db` 24 | 25 | ## v1.0.5 26 | 27 | ### Added 28 | 29 | - `rubrik_vsphere_instant_recovery` 30 | -------------------------------------------------------------------------------- /rubrikinc/cdm/galaxy.yml: -------------------------------------------------------------------------------- 1 | ### requried 2 | # this can be a company/brand or product namespace under which all content lives 3 | namespace: rubrikinc 4 | # the designation of this specific collection 5 | name: cdm 6 | # semantic versioning compliant version designation 7 | version: "1.0.6" 8 | readme: README.md 9 | # a list of the collection's content authors: 'Full Name (http://site) @nicks:irc/im/site#channel' 10 | authors: Rubrik Build 11 | 12 | ### optional but strongly advised 13 | # short summary of the collection 14 | description: Ansible Modules that utilize the Rubrik RESTful API to manage the Rubrik Cloud Data Management Platform. 15 | # a valid SPDX license identifier https://spdx.org/licenses/ 16 | license: MIT 17 | # list of keywords you want to associate the collection with for indexing/search systems 18 | tags: cloud 19 | 20 | ### urls 21 | # url of originating SCM repository 22 | repository: https://github.com/rubrikinc/rubrik-modules-for-ansible 23 | # url to online docs 24 | documentation: https://rubrik.gitbook.io/rubrik-modules-for-ansible/ 25 | # homepage of the collection/project 26 | homepage: https://build.rubrik.com/tooling-integrations/ansible/ 27 | # issue tracker url 28 | issues: https://github.com/rubrikinc/rubrik-modules-for-ansible/issues 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug encountered while using the Rubrik Modules for Ansible. 4 | title: '' 5 | labels: kind-bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | 13 | **Expected Behavior** 14 | 15 | Please describe the behavior you are expecting. 16 | 17 | **Current Behavior** 18 | 19 | What is the current behavior? 20 | 21 | **Failure Information (for bugs)** 22 | 23 | Please help provide information about the failure if this is a bug. 24 | 25 | 26 | * Use verbose outputs to capture any debug information. 27 | ``` 28 | Paste into a code block. 29 | ``` 30 | 31 | **Steps to Reproduce** 32 | 33 | Please provide detailed steps for reproducing the issue. 34 | 35 | * Use numbered list. 36 | 37 | **Context** 38 | 39 | Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions. 40 | 41 | * Version of project. 42 | * Version of dependencies. 43 | * Version of operating system. 44 | 45 | **Failure Logs** 46 | 47 | Please include any relevant log snippets or files here. 48 | 49 | * Use verbose outputs to capture any debug information. 50 | 51 | ``` 52 | Paste into a code block. 53 | ``` 54 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | ### Getting Started 4 | 5 | * [Quick Start](README.md) 6 | 7 | ### Modules 8 | 9 | * [rubrik_assign_physical_host_fileset](rubrik_assign_physical_host_fileset.md) 10 | * [rubrik_assign_sla](rubrik_assign_sla.md) 11 | * [rubrik_bootstrap](rubrik_bootstrap.md) 12 | * [rubrik_create_sla](rubrik_create_sla.md) 13 | * [rubrik_cluster_version](rubrik_cluster_version.md) 14 | * [rubrik_dns_servers](rubrik_dns_servers.md) 15 | * [rubrik_end_user_authorization](rubrik_end_user_authorization.md) 16 | * [rubrik_job_status](rubrik_job_status.md) 17 | * [rubrik_login_banner](rubrik_login_banner.md) 18 | * [rubrik_managed_volume](rubrik_managed_volume.md) 19 | * [rubrik_nas_fileset](rubrik_nas_fileset.md) 20 | * [rubrik_on_demand_snapshot](rubrik_on_demand_snapshot.md) 21 | * [rubrik_physical_fileset](rubrik_physical_fileset.md) 22 | * [rubrik_physical_host](rubrik_physical_host.md) 23 | * [rubrik_refresh_vcenter](rubrik_refresh_vcenter.md) 24 | * [rubrik_vsphere_live_mount](rubrik_vsphere_live_mount.md) 25 | * [rubrik_vsphere_live_unmount](rubrik_vsphere_live_unmount.md) 26 | * [rubrik_sql_live_mount](rubrik_sql_live_mount.md) 27 | * [rubrik_sql_live_unmount](rubrik_sql_live_unmount.md) 28 | * [rubrik_get_vsphere_live_mount](rubrik_get_vsphere_live_mount.md) 29 | * [rubrik_get_vsphere_live_mount_names](rubrik_get_vsphere_live_mount_names.md) 30 | * [rubrik_get_sql_live_mount](rubrik_get_sql_live_mount.md) 31 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please describe your pull request in detail. 4 | 5 | ## Related Issue 6 | 7 | This project only accepts pull requests related to open issues. 8 | 9 | * If suggesting a new feature or change, please discuss it in an issue first. 10 | * If fixing a bug, there should be an issue describing it with steps to reproduce 11 | 12 | _Please link to the issue here_ 13 | 14 | ## Motivation and Context 15 | 16 | Why is this change required? What problem does it solve? 17 | 18 | ## How Has This Been Tested? 19 | 20 | * Please describe in detail how you tested your changes. 21 | * Include details of your testing environment, and the tests you ran to see how your change affects other areas of the code, etc. 22 | 23 | ## Screenshots (if appropriate): 24 | 25 | ## Types of changes 26 | 27 | What types of changes does your code introduce? Put an `x` in all the boxes that apply: 28 | - [ ] Bug fix (non-breaking change which fixes an issue) 29 | - [ ] New feature (non-breaking change which adds functionality) 30 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 31 | 32 | ## Checklist: 33 | 34 | Go over all the following points, and put an `x` in all the boxes that apply. If you're unsure about any of these, don't hesitate to ask. We're here to help! 35 | - [ ] My code follows the code style of this project. 36 | - [ ] My change requires a change to the documentation. 37 | - [ ] I have updated the documentation accordingly. 38 | - [ ] I have read the **[CONTRIBUTION](http://rubrikinc.github.io/PowerShell-Module/documentation/contribution.html)** document. 39 | - [ ] I have updated the CHANGELOG file accordingly for the version that this merge modifies. 40 | - [ ] I have added tests to cover my changes. 41 | - [ ] All new and existing tests passed. 42 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | #----------------------------------------------------------------------------------------- 2 | # Copyright (c) Microsoft Corporation. All rights reserved. 3 | # Licensed under the MIT License. See LICENSE in the project root for license information. 4 | #----------------------------------------------------------------------------------------- 5 | 6 | FROM python:3 7 | 8 | # Install the required development packages 9 | RUN pip install pylint requests python-dateutil pytz coverage pytest-cov pytest-mock tox pep8 autopep8 rubrik_cdm paramiko PyYAML Jinja2 httplib2 six voluptuous isort lazy-object-proxy wrapt docutils rstcheck pathspec yamllint 10 | 11 | # Configure apt 12 | ENV DEBIAN_FRONTEND=noninteractive 13 | RUN apt-get update \ 14 | && apt-get -y install --no-install-recommends apt-utils 2>&1 15 | 16 | # Install git, process tools, lsb-release (common in install instructions for CLIs), and zsh shell 17 | RUN apt-get -y install git procps lsb-release zsh 18 | 19 | # Install any missing dependencies for enhanced language service 20 | RUN apt-get install -y libicu[0-9][0-9] 21 | 22 | # Make zsh the default shell 23 | RUN chsh -s $(which zsh) 24 | 25 | # Install oh-my-zsh 26 | RUN sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 27 | 28 | RUN mkdir /workspace 29 | RUN git clone https://github.com/ansible/ansible.git /workspaces/ansible 30 | 31 | RUN mkdir -p /root/.ansible/collections/ansible_collections/rubrikinc/cdm 32 | RUN mkdir -p /workspaces/ansible/lib/ansible/modules/cloud/rubrikinc 33 | 34 | ENV PYTHONPATH=/workspaces/rubrik-modules-for-ansible/rubrikinc/cdm:/root/.ansible/collections 35 | 36 | WORKDIR /workspace 37 | 38 | # Clean up 39 | RUN apt-get autoremove -y \ 40 | && apt-get clean -y \ 41 | && rm -rf /var/lib/apt/lists/* 42 | ENV DEBIAN_FRONTEND=dialog 43 | 44 | ENV ANSIBLE_COLLECTIONS_PATHS="~/.ansible/collections" 45 | 46 | # Set the default shell to zsh rather than sh 47 | ENV SHELL /bin/zsh 48 | -------------------------------------------------------------------------------- /.devcontainer/start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Install Ansible 4 | echo "source /workspaces/ansible/hacking/env-setup" >> ~/.zshrc 5 | 6 | # Alias to run Ansible Collection Centric Sanity Check 7 | # TODO - Add script to update and then revert import path 8 | echo "alias sanityc='rm -rf /workspaces/ansible/lib/ansible/modules/cloud/rubrikinc/ && rm -f /workspaces/ansible/lib/ansible/module_utils/rubrik_cdm.py && rm -f /workspaces/ansible/lib/ansible/plugins/doc_fragments/credentials.py && cp -a /workspaces/rubrik-modules-for-ansible/rubrikinc/cdm/. /root/.ansible/collections/ansible_collections/rubrikinc/cdm && /root/.ansible/collections/ansible_collections/rubrikinc/cdm && rm /root/.ansible/collections/ansible_collections/rubrikinc/cdm/docs/rubrik_module_template.py && rm /root/.ansible/collections/ansible_collections/rubrikinc/cdm/docs/create_documentation_block.py && rm /root/.ansible/collections/ansible_collections/rubrikinc/cdm/docs/quick-start.md && python /workspaces/rubrik-modules-for-ansible/collection_dev.py -a test && ansible-test sanity && cd -'" >> ~/.zshrc 9 | 10 | # Alias to run "Traditional" Centric Sanity Check 11 | echo "alias sanityt='cp -a /workspaces/rubrik-modules-for-ansible/rubrikinc/cdm/plugins/modules/. /workspaces/ansible/lib/ansible/modules/cloud/rubrikinc && cp -a /workspaces/rubrik-modules-for-ansible/rubrikinc/cdm/plugins/module_utils/. /workspaces/ansible/lib/ansible/module_utils && cp -a /workspaces/rubrik-modules-for-ansible/rubrikinc/cdm/plugins/doc_fragments/. /workspaces/ansible/lib/ansible/plugins/doc_fragments && cd /workspaces/ansible/lib/ansible/modules/cloud/rubrikinc && ansible-test sanity && cd -'" >> ~/.zshrc 12 | 13 | 14 | # This script will automatically run after the container has been created. 15 | # To untrack this file in git, run git update-index --skip-worktree .devcontainer/start.sh 16 | 17 | # Set environment variables template 18 | # echo "export rubrik_cdm_username="" >> ~/.zshrc 19 | # echo "export rubrik_cdm_password="" >> ~/.zshrc 20 | # echo "export rubrik_cdm_token="" >> ~/.zshrc 21 | -------------------------------------------------------------------------------- /rubrikinc/cdm/README.md: -------------------------------------------------------------------------------- 1 | # Rubrik Ansible Modules 2 | 3 | Ansible Modules that utilize the Rubrik RESTful API to manage the Rubrik Cloud Data Management Platform. 4 | 5 | # Installation 6 | 7 | **Install the Rubrik SDK for Python.** 8 | 9 | `pip install rubrik_cdm` 10 | 11 | **Clone the GitHub repository to a local directory** 12 | 13 | `git clone https://github.com/rubrikinc/rubrik-modules-for-ansible.git` 14 | 15 | # Example 16 | 17 | ```yaml 18 | - rubrik_on_demand_snapshot: 19 | object_name: 'ansible-node01' 20 | object_type: "vmware" 21 | ``` 22 | 23 | # Documentation 24 | 25 | Here are some resources to get you started! If you find any challenges from this project are not properly documented or are unclear, please [raise an issue](https://github.com/rubrikinc/rubrik-modules-for-ansible/issues/new/choose) and let us know! This is a fun, safe environment - don't worry if you're a GitHub newbie! 26 | 27 | * [Quick Start Guide](https://github.com/rubrikinc/rubrik-modules-for-ansible/blob/master/docs/quick-start.md) 28 | * [Module Documentation](https://rubrik.gitbook.io/rubrik-modules-for-ansible/) 29 | * [Rubrik API Documentation](https://github.com/rubrikinc/api-documentation) 30 | * [VIDEO: Getting Started with the Rubrik Modules for Ansible](https://www.youtube.com/watch?v=B5MGkiJyIeI&t=1s) 31 | * [BLOG: Using Ansible with Rubrik Just Got Easier!](https://www.rubrik.com/blog/rubrik-modules-redhat-ansible/) 32 | 33 | # How You Can Help 34 | 35 | We glady welcome contributions from the community. From updating the documentation to adding more functions for Ansible, all ideas are welcome. Thank you in advance for all of your issues, pull requests, and comments! :star: 36 | 37 | * [Contributing Guide](CONTRIBUTING.md) 38 | * [Code of Conduct](CODE_OF_CONDUCT.md) 39 | 40 | # License 41 | 42 | * [MIT License](LICENSE) 43 | 44 | # About Rubrik Build 45 | 46 | We encourage all contributors to become members. We aim to grow an active, healthy community of contributors, reviewers, and code owners. Learn more in our [Welcome to the Rubrik Build Community](https://github.com/rubrikinc/welcome-to-rubrik-build) page. 47 | 48 | We'd love to hear from you! Email us: build@rubrik.com 49 | -------------------------------------------------------------------------------- /library/rubrik_host_facts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = { 10 | 'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community' 13 | } 14 | 15 | DOCUMENTATION = ''' 16 | module: rubrik_cluster_version 17 | short_description: Retrieves the software version of the Rubrik cluster. 18 | description: 19 | - Retrieves the software version of the Rubrik cluster. 20 | version_added: '2.8' 21 | author: Rubrik Build Team (@drew-russell) 22 | 23 | 24 | extends_documentation_fragment: 25 | - rubrik_cdm 26 | requirements: [rubrik_cdm] 27 | ''' 28 | 29 | EXAMPLES = ''' 30 | - name: Retrieve the software version of the Rubrik cluster 31 | rubrik_cluster_version: 32 | ''' 33 | 34 | RETURN = ''' 35 | version: 36 | description: The version of the Rubrik cluster. 37 | returned: success 38 | type: str 39 | sample: 4.1.3-2510 40 | ''' 41 | 42 | 43 | from ansible.module_utils.basic import AnsibleModule 44 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 45 | 46 | try: 47 | import rubrik_cdm 48 | HAS_RUBRIK_SDK = True 49 | except ImportError: 50 | HAS_RUBRIK_SDK = False 51 | 52 | 53 | def main(): 54 | """ Main entry point for Ansible module execution. 55 | """ 56 | 57 | results = {} 58 | 59 | argument_spec = dict( 60 | ) 61 | 62 | argument_spec.update(rubrik_argument_spec) 63 | 64 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 65 | 66 | ansible = module.params 67 | 68 | load_provider_variables(module) 69 | 70 | if not HAS_RUBRIK_SDK: 71 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 72 | 73 | node_ip, username, password = credentials(module) 74 | 75 | try: 76 | rubrik = rubrik_cdm.Connect(node_ip, username, password) 77 | except SystemExit as error: 78 | module.fail_json(msg=str(error)) 79 | 80 | try: 81 | api_request = rubrik.get_all_hosts() 82 | except SystemExit as error: 83 | module.fail_json(msg=str(error)) 84 | 85 | module.exit_json(**api_request) 86 | 87 | 88 | if __name__ == '__main__': 89 | main() 90 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Rubrik Modules for Ansible Development Guide 2 | 3 | Contributions via GitHub pull requests are gladly accepted from their original author. Along with any pull requests, please state that the contribution is your original work and that you license the work to the project under the project's open source license. Whether or not you state this explicitly, by submitting any copyrighted material via pull request, email, or other means you agree to license the material under the project's open source license and warrant that you have the legal authority to do so. 4 | 5 | ## Common Environment Setup 6 | 7 | 1. Clone the Rubrik Modules for Ansible repository 8 | 9 | ``` 10 | git clone https://github.com/rubrikinc/rubrik-modules-for-ansible.git 11 | ``` 12 | 13 | 2. Change to the repository root directory 14 | 15 | ``` 16 | cd rubrik-modules-for-ansible 17 | ``` 18 | 19 | 3. Switch to the devel branch 20 | 21 | ``` 22 | git checkout devel 23 | ``` 24 | 25 | 26 | ## New module Development 27 | 28 | The `/rubrik-modules-for-ansible/library` directory contains all of the Rubrik Ansible modules. You can also utilize the following file as a template for all new modules: 29 | 30 | `/rubrik-modules-for-ansible/docs/rubrik_module_template.py` 31 | 32 | To add paramters specific to the new module you can can update the following section which starts on `line 60`: 33 | 34 | ```python 35 | argument_spec.update( 36 | dict( 37 | timeout=dict(required=False, type='int', default=15), 38 | 39 | ) 40 | ) 41 | ``` 42 | 43 | After the new variables have been defined you can start adding any new required logic after the code block section. 44 | 45 | ```python 46 | ################################## 47 | ######### Code Block ############# 48 | ################################## 49 | ################################## 50 | ``` 51 | 52 | Your final Rubrik Python SDK call should be added to `Line 93`. 53 | 54 | ```python 55 | api_request = rubrik. 56 | ``` 57 | 58 | For example, if you wanted to call the `cluster_version()` function the line would look like: 59 | 60 | ```python 61 | api_request = rubrik.cluster_version() 62 | ``` 63 | 64 | Once the module has been fully coded you can use the following script to automatically generate the module `DOCUMENTATION` block: 65 | 66 | ``/rubrik-modules-for-ansible/docs/create_documentation_block.py` 67 | 68 | To use the script, update the `filename = ` variable and then run `python create_documentation_block.py` 69 | -------------------------------------------------------------------------------- /library/rubrik_vmware_vcenter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = { 10 | 'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community' 13 | } 14 | 15 | DOCUMENTATION = ''' 16 | module: rubrik_cluster_version 17 | short_description: Retrieves the software version of the Rubrik cluster. 18 | description: 19 | - Retrieves the software version of the Rubrik cluster. 20 | version_added: '2.8' 21 | author: Rubrik Build Team (@drew-russell) 22 | 23 | 24 | extends_documentation_fragment: 25 | - rubrik_cdm 26 | requirements: [rubrik_cdm] 27 | ''' 28 | 29 | EXAMPLES = ''' 30 | - name: Retrieve the software version of the Rubrik cluster 31 | rubrik_cluster_version: 32 | ''' 33 | 34 | RETURN = ''' 35 | version: 36 | description: The version of the Rubrik cluster. 37 | returned: success 38 | type: str 39 | sample: 4.1.3-2510 40 | ''' 41 | 42 | 43 | from ansible.module_utils.basic import AnsibleModule 44 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 45 | 46 | try: 47 | import rubrik_cdm 48 | HAS_RUBRIK_SDK = True 49 | except ImportError: 50 | HAS_RUBRIK_SDK = False 51 | 52 | 53 | def main(): 54 | """ Main entry point for Ansible module execution. 55 | """ 56 | 57 | results = {} 58 | 59 | argument_spec = dict( 60 | ) 61 | 62 | argument_spec.update(rubrik_argument_spec) 63 | 64 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 65 | 66 | ansible = module.params 67 | 68 | load_provider_variables(module) 69 | 70 | if not HAS_RUBRIK_SDK: 71 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 72 | 73 | node_ip, username, password = credentials(module) 74 | 75 | try: 76 | rubrik = rubrik_cdm.Connect(node_ip, username, password) 77 | except SystemExit as error: 78 | module.fail_json(msg=str(error)) 79 | 80 | try: 81 | api_request = rubrik.get_all_vcenters() 82 | except SystemExit as error: 83 | module.fail_json(msg=str(error)) 84 | #fixed 85 | module.exit_json(**api_request) 86 | 87 | 88 | if __name__ == '__main__': 89 | main() 90 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_cluster_version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_cluster_version 16 | short_description: Retrieves the software version of the Rubrik cluster. 17 | description: 18 | - Retrieves the software version of the Rubrik cluster. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | 22 | 23 | extends_documentation_fragment: rubrikinc.cdm.credentials 24 | requirements: [rubrik_cdm] 25 | ''' 26 | 27 | EXAMPLES = ''' 28 | - name: Retrieve the software version of the Rubrik cluster 29 | rubrik_cluster_version: 30 | ''' 31 | 32 | RETURN = ''' 33 | version: 34 | description: The version of the Rubrik cluster. 35 | returned: success 36 | type: str 37 | sample: 4.1.3-2510 38 | ''' 39 | 40 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 41 | from ansible.module_utils.basic import AnsibleModule 42 | 43 | try: 44 | import rubrik_cdm 45 | HAS_RUBRIK_SDK = True 46 | except ImportError: 47 | HAS_RUBRIK_SDK = False 48 | 49 | 50 | def main(): 51 | """ Main entry point for Ansible module execution. 52 | """ 53 | 54 | results = {} 55 | 56 | argument_spec = dict( 57 | ) 58 | 59 | argument_spec.update(rubrik_argument_spec) 60 | 61 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 62 | 63 | ansible = module.params 64 | 65 | load_provider_variables(module) 66 | 67 | if not HAS_RUBRIK_SDK: 68 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 69 | 70 | node_ip, username, password, api_token = credentials(module) 71 | 72 | try: 73 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 74 | except Exception as error: 75 | module.fail_json(msg=str(error)) 76 | 77 | try: 78 | api_request = rubrik.cluster_version() 79 | except Exception as error: 80 | module.fail_json(msg=str(error)) 81 | 82 | results["version"] = api_request 83 | 84 | module.exit_json(**results) 85 | 86 | 87 | if __name__ == '__main__': 88 | main() 89 | -------------------------------------------------------------------------------- /library/rubrik_vcenter_refresh.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = { 10 | 'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community' 13 | } 14 | 15 | DOCUMENTATION = ''' 16 | module: rubrik_vcenter_refresh 17 | short_description: Refreshes the vcenter environment that you specify. 18 | description: 19 | - Retrieves the software version of the Rubrik cluster. 20 | version_added: '2.8' 21 | author: Rubrik Build Team (@drew-russell) 22 | 23 | 24 | extends_documentation_fragment: 25 | - rubrik_cdm 26 | requirements: [rubrik_cdm] 27 | ''' 28 | 29 | EXAMPLES = ''' 30 | - name: Retrieve the software version of the Rubrik cluster 31 | vmware_vcenter_refresh: 32 | ''' 33 | 34 | RETURN = ''' 35 | version: 36 | description: The version of the Rubrik cluster. 37 | returned: success 38 | type: str 39 | sample: 4.1.3-2510 40 | ''' 41 | 42 | 43 | from ansible.module_utils.basic import AnsibleModule 44 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 45 | 46 | try: 47 | import rubrik_cdm 48 | HAS_RUBRIK_SDK = True 49 | except ImportError: 50 | HAS_RUBRIK_SDK = False 51 | 52 | 53 | def main(): 54 | """ Main entry point for Ansible module execution. 55 | """ 56 | 57 | results = {} 58 | 59 | argument_spec = dict( 60 | vcenter_ip=dict(required=True, type='str'), 61 | ) 62 | 63 | argument_spec.update(rubrik_argument_spec) 64 | 65 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 66 | 67 | ansible = module.params 68 | 69 | wait_for_completion=False 70 | 71 | load_provider_variables(module) 72 | 73 | if not HAS_RUBRIK_SDK: 74 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 75 | 76 | node_ip, username, password = credentials(module) 77 | 78 | try: 79 | rubrik = rubrik_cdm.Connect(node_ip, username, password) 80 | except SystemExit as error: 81 | module.fail_json(msg=str(error)) 82 | 83 | try: 84 | api_request = rubrik.refresh_vcenter(ansible["vcenter_ip"], wait_for_completion) 85 | except SystemExit as error: 86 | module.fail_json(msg=str(error)) 87 | #fixed 88 | module.exit_json(**api_request) 89 | 90 | 91 | if __name__ == '__main__': 92 | main() 93 | -------------------------------------------------------------------------------- /library/rubrik_vm_register.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = { 10 | 'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community' 13 | } 14 | 15 | DOCUMENTATION = ''' 16 | module: rubrik_vm_register 17 | short_description: Retrieves the software version of the Rubrik cluster. 18 | description: 19 | - Retrieves the software version of the Rubrik cluster. 20 | version_added: '2.8' 21 | author: Rubrik Build Team (@drew-russell) 22 | 23 | 24 | extends_documentation_fragment: 25 | - rubrik_cdm 26 | requirements: [rubrik_cdm] 27 | ''' 28 | 29 | EXAMPLES = ''' 30 | - name: Retrieve the software version of the Rubrik cluster 31 | rubrik_cluster_version: 32 | ''' 33 | 34 | RETURN = ''' 35 | version: 36 | description: The version of the Rubrik cluster. 37 | returned: success 38 | type: str 39 | sample: 4.1.3-2510 40 | ''' 41 | 42 | 43 | from ansible.module_utils.basic import AnsibleModule 44 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 45 | 46 | try: 47 | import rubrik_cdm 48 | HAS_RUBRIK_SDK = True 49 | except ImportError: 50 | HAS_RUBRIK_SDK = False 51 | 52 | 53 | def main(): 54 | """ Main entry point for Ansible module execution. 55 | """ 56 | 57 | results = {} 58 | 59 | argument_spec = dict( 60 | vm_id=dict(required=False, type='str',default=None), 61 | vm_name=dict(required=False, type='str', default=None), 62 | ) 63 | 64 | argument_spec.update(rubrik_argument_spec) 65 | 66 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 67 | 68 | ansible = module.params 69 | 70 | load_provider_variables(module) 71 | 72 | if not HAS_RUBRIK_SDK: 73 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 74 | 75 | node_ip, username, password = credentials(module) 76 | 77 | try: 78 | rubrik = rubrik_cdm.Connect(node_ip, username, password) 79 | except SystemExit as error: 80 | module.fail_json(msg=str(error)) 81 | 82 | try: 83 | api_request = rubrik.register_agent(ansible["vm_name"],ansible["vm_id"]) 84 | except SystemExit as error: 85 | module.fail_json(msg=str(error)) 86 | #fixed 87 | module.exit_json(**api_request) 88 | 89 | 90 | if __name__ == '__main__': 91 | main() 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rubrik Ansible Modules 2 | 3 | Ansible Modules that utilize the Rubrik RESTful API to manage the Rubrik Cloud Data Management Platform. 4 | 5 | # :hammer: Installation 6 | 7 | **Install the Rubrik SDK for Python** 8 | 9 | `pip install rubrik_cdm` 10 | 11 | **Clone the GitHub repository to a local directory** 12 | 13 | `git clone https://github.com/rubrikinc/rubrik-modules-for-ansible.git` 14 | 15 | # :woman_astronaut: Ansible Galaxy 16 | 17 | **Install the Rubrik Collection for Ansible via Ansible Galaxy** 18 | 19 | `ansible-galaxy collection install rubrikinc.cdm` 20 | 21 | See the [Quick Start Guide](https://github.com/rubrikinc/rubrik-modules-for-ansible/blob/master/rubrikinc/cdm/docs/README.md) for more information on using modules installed via Ansible Galaxy. For more information, see our [Galaxy Collection](https://galaxy.ansible.com/rubrikinc/cdm) 22 | 23 | # :mag: Example 24 | 25 | ```yaml 26 | - rubrik_on_demand_snapshot: 27 | object_name: 'ansible-node01' 28 | object_type: "vmware" 29 | ``` 30 | 31 | # :blue_book: Documentation 32 | 33 | Here are some resources to get you started! If you find any challenges from this project are not properly documented or are unclear, please [raise an issue](https://github.com/rubrikinc/rubrik-modules-for-ansible/issues/new/choose) and let us know! This is a fun, safe environment - don't worry if you're a GitHub newbie! :heart: 34 | 35 | * [Quick Start Guide](https://github.com/rubrikinc/rubrik-modules-for-ansible/blob/master/rubrikinc/cdm/docs/README.md) 36 | * [Module Documentation](https://rubrik.gitbook.io/rubrik-modules-for-ansible/) 37 | * [Rubrik API Documentation](https://github.com/rubrikinc/api-documentation) 38 | * [VIDEO: Getting Started with the Rubrik Modules for Ansible](https://www.youtube.com/watch?v=B5MGkiJyIeI&t=1s) 39 | * [BLOG: Using Ansible with Rubrik Just Got Easier!](https://www.rubrik.com/blog/rubrik-modules-redhat-ansible/) 40 | 41 | # :muscle: How You Can Help 42 | 43 | We glady welcome contributions from the community. From updating the documentation to adding more functions for Ansible, all ideas are welcome. Thank you in advance for all of your issues, pull requests, and comments! :star: 44 | 45 | * [Contributing Guide](CONTRIBUTING.md) 46 | * [Code of Conduct](CODE_OF_CONDUCT.md) 47 | 48 | # :pushpin: License 49 | 50 | * [MIT License](LICENSE) 51 | 52 | # :point_right: About Rubrik Build 53 | 54 | We encourage all contributors to become members. We aim to grow an active, healthy community of contributors, reviewers, and code owners. Learn more in our [Welcome to the Rubrik Build Community](https://github.com/rubrikinc/welcome-to-rubrik-build) page. 55 | 56 | We'd love to hear from you! Email us: build@rubrik.com :love_letter: 57 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_cluster_version.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_cluster_version as rubrik_cluster_version 10 | 11 | 12 | def set_module_args(args): 13 | """prepare arguments so that they will be picked up during module creation""" 14 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 15 | basic._ANSIBLE_ARGS = to_bytes(args) 16 | 17 | 18 | class AnsibleExitJson(Exception): 19 | """Exception class to be raised by module.exit_json and caught by the test case""" 20 | pass 21 | 22 | 23 | class AnsibleFailJson(Exception): 24 | """Exception class to be raised by module.fail_json and caught by the test case""" 25 | pass 26 | 27 | 28 | def exit_json(*args, **kwargs): 29 | """function to patch over exit_json; package return data into an exception""" 30 | if 'changed' not in kwargs: 31 | kwargs['changed'] = False 32 | raise AnsibleExitJson(kwargs) 33 | 34 | 35 | def fail_json(*args, **kwargs): 36 | """function to patch over fail_json; package return data into an exception""" 37 | kwargs['failed'] = True 38 | raise AnsibleFailJson(kwargs) 39 | 40 | 41 | class TestRubrikClusterVersion(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 45 | exit_json=exit_json, 46 | fail_json=fail_json) 47 | self.mock_module_helper.start() 48 | self.addCleanup(self.mock_module_helper.stop) 49 | 50 | def test_module_fail_when_required_args_missing(self): 51 | with self.assertRaises(AnsibleFailJson): 52 | set_module_args({}) 53 | rubrik_cluster_version.main() 54 | 55 | @patch.object(rubrik_cluster_version.rubrik_cdm.rubrik_cdm.Connect, 'get', autospec=True, spec_set=True) 56 | def test_module_cluster_version(self, mock_get): 57 | 58 | def mock_get_v1_cluster_me_version(): 59 | return {'version': '5.0.1-1280'} 60 | 61 | set_module_args({ 62 | 'node_ip': '1.1.1.1', 63 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 64 | }) 65 | 66 | mock_get.return_value = mock_get_v1_cluster_me_version() 67 | 68 | with self.assertRaises(AnsibleExitJson) as result: 69 | rubrik_cluster_version.main() 70 | 71 | self.assertEqual(result.exception.args[0]['changed'], False) 72 | self.assertEqual(result.exception.args[0]['version'], '5.0.1-1280') 73 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_module_template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright: Rubrik 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 7 | from ansible.module_utils.basic import AnsibleModule 8 | from __future__ import absolute_import, division, print_function 9 | __metaclass__ = type 10 | 11 | ANSIBLE_METADATA = { 12 | 'metadata_version': '1.1', 13 | 'status': ['preview'], 14 | 'supported_by': 'community' 15 | } 16 | 17 | DOCUMENTATION = ''' 18 | # Should be auto-generated and pasted here. 19 | ''' 20 | 21 | EXAMPLES = ''' 22 | - rubrik_module_name: 23 | ''' 24 | 25 | RETURN = ''' 26 | response: 27 | description: The full API response for . 28 | returned: on success 29 | type: dict 30 | sample: 31 | { 32 | 33 | } 34 | 35 | response: 36 | description: A "No changed required" message when 37 | returned: When the module idempotent check is succesful. 38 | type: str 39 | sample: 40 | ''' 41 | 42 | 43 | try: 44 | import rubrik_cdm 45 | HAS_RUBRIK_SDK = True 46 | except ImportError: 47 | HAS_RUBRIK_SDK = False 48 | 49 | 50 | def main(): 51 | """ Main entry point for Ansible module execution. 52 | """ 53 | 54 | results = {} 55 | 56 | argument_spec = rubrik_argument_spece 57 | 58 | # Start Parameters 59 | argument_spec.update( 60 | dict( 61 | timeout=dict(required=False, type='int', default=15), 62 | 63 | ) 64 | ) 65 | # End Parameters 66 | 67 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 68 | 69 | ansible = module.params 70 | 71 | load_provider_variables(module) 72 | 73 | if not HAS_RUBRIK_SDK: 74 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 75 | 76 | node_ip, username, password, api_token = credentials(module) 77 | 78 | try: 79 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 80 | except Exception as error: 81 | module.fail_json(msg=str(error)) 82 | 83 | try: 84 | rubrik = rubrik_cdm.Connect(node_ip, username, password) 85 | except SystemExit as error: 86 | module.fail_json(msg=str(error)) 87 | 88 | # Code Block 89 | 90 | 91 | try: 92 | api_request = rubrik. 93 | except SystemExit as error: 94 | module.fail_json(msg=str(error)) 95 | 96 | if "No change required" in api_request: 97 | results["changed"] = False 98 | else: 99 | results["changed"] = True 100 | 101 | results["response"] = api_request 102 | 103 | module.exit_json(**results) 104 | 105 | 106 | if __name__ == '__main__': 107 | main() 108 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_get.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_get as rubrik_get 10 | 11 | 12 | def set_module_args(args): 13 | """prepare arguments so that they will be picked up during module creation""" 14 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 15 | basic._ANSIBLE_ARGS = to_bytes(args) 16 | 17 | 18 | class AnsibleExitJson(Exception): 19 | """Exception class to be raised by module.exit_json and caught by the test case""" 20 | pass 21 | 22 | 23 | class AnsibleFailJson(Exception): 24 | """Exception class to be raised by module.fail_json and caught by the test case""" 25 | pass 26 | 27 | 28 | def exit_json(*args, **kwargs): 29 | """function to patch over exit_json; package return data into an exception""" 30 | if 'changed' not in kwargs: 31 | kwargs['changed'] = False 32 | raise AnsibleExitJson(kwargs) 33 | 34 | 35 | def fail_json(*args, **kwargs): 36 | """function to patch over fail_json; package return data into an exception""" 37 | kwargs['failed'] = True 38 | raise AnsibleFailJson(kwargs) 39 | 40 | 41 | class TestRubrikGet(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 45 | exit_json=exit_json, 46 | fail_json=fail_json) 47 | self.mock_module_helper.start() 48 | self.addCleanup(self.mock_module_helper.stop) 49 | 50 | def test_module_fail_when_required_args_missing(self): 51 | with self.assertRaises(AnsibleFailJson): 52 | set_module_args({}) 53 | rubrik_get.main() 54 | 55 | @patch.object(rubrik_get.rubrik_cdm.rubrik_cdm.Connect, '_common_api', autospec=True, spec_set=True) 56 | def test_module_get(self, mock_get): 57 | 58 | def mock_get_get(): 59 | return {"data": [], "hasMore": False, "total": 0} 60 | 61 | set_module_args({ 62 | 'node_ip': '1.1.1.1', 63 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP', 64 | 'api_version': 'v1', 65 | 'api_endpoint': '/sla_domain', 66 | 'params': {"name": "Python SDK"} 67 | }) 68 | 69 | mock_get.return_value = mock_get_get() 70 | 71 | with self.assertRaises(AnsibleExitJson) as result: 72 | rubrik_get.main() 73 | 74 | self.assertEqual(result.exception.args[0]['changed'], False) 75 | self.assertEqual(result.exception.args[0]['response'], {"data": [], "hasMore": False, "total": 0}) 76 | 77 | 78 | if __name__ == '__main__': 79 | unittest.main() 80 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/create_documentation_block.py: -------------------------------------------------------------------------------- 1 | 2 | directory = "../library/" 3 | filename = "rubrik_bootstrap.py" 4 | 5 | 6 | with open("{}{}".format(directory, filename)) as fp: 7 | line = fp.readline() 8 | cnt = 1 9 | while line: 10 | if line.strip() == "# Start Parameters": 11 | arugment_spec_upate_start = cnt 12 | elif line.strip() == "# End Parameters": 13 | arugment_spec_upate_end = cnt 14 | line = fp.readline() 15 | cnt += 1 16 | fp.close() 17 | 18 | 19 | module_parameters = [] 20 | with open("{}{}".format(directory, filename)) as fp: 21 | line = fp.readline() 22 | cnt = 1 23 | while line: 24 | if (arugment_spec_upate_start + 3) <= cnt <= (arugment_spec_upate_end - 3): 25 | if line.strip() != "": 26 | module_parameters.append(line.strip()) 27 | line = fp.readline() 28 | cnt += 1 29 | fp.close() 30 | 31 | print("DOCUMENTATION = '''") 32 | print("module: {}".format(filename.replace(".py", ""))) 33 | print("short_description: ") 34 | print("description:") 35 | print(" -") 36 | print("version_added: '2.8'") 37 | print("author: Rubrik Build Team ") 38 | print("options:") 39 | 40 | for param in module_parameters: 41 | indivdual_param = param[:-2].split("=dict(") 42 | option_name = indivdual_param[0] 43 | print(" " + option_name + ":") 44 | print(" description: ") 45 | if option_name == "timeout": 46 | print(" - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error.") 47 | else: 48 | print(" -") 49 | # print(indivdual_param[1]) 50 | for param in indivdual_param[1].split(" "): 51 | if "aliases" in param: 52 | print( 53 | " " + 54 | param.replace( 55 | ",", 56 | "").replace( 57 | "'", 58 | "").replace( 59 | "=", 60 | " = ").replace( 61 | '"', 62 | '').replace( 63 | "[", 64 | "").replace( 65 | "]", 66 | "").replace( 67 | ' = ', 68 | ": ")) 69 | else: 70 | print( 71 | " " + 72 | param.replace( 73 | ",", 74 | "").replace( 75 | "'", 76 | "").replace( 77 | "=", 78 | " = ").replace( 79 | '"', 80 | '').replace( 81 | ' = ', 82 | ": ")) 83 | 84 | 85 | print("\nextends_documentation_fragment:") 86 | print(" - rubrik_cdm") 87 | print("requirements: [rubrik_cdm]") 88 | print("'''\n") 89 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_post.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_post as rubrik_post 10 | 11 | 12 | def set_module_args(args): 13 | """prepare arguments so that they will be picked up during module creation""" 14 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 15 | basic._ANSIBLE_ARGS = to_bytes(args) 16 | 17 | 18 | class AnsibleExitJson(Exception): 19 | """Exception class to be raised by module.exit_json and caught by the test case""" 20 | pass 21 | 22 | 23 | class AnsibleFailJson(Exception): 24 | """Exception class to be raised by module.fail_json and caught by the test case""" 25 | pass 26 | 27 | 28 | def exit_json(*args, **kwargs): 29 | """function to patch over exit_json; package return data into an exception""" 30 | if 'changed' not in kwargs: 31 | kwargs['changed'] = False 32 | raise AnsibleExitJson(kwargs) 33 | 34 | 35 | def fail_json(*args, **kwargs): 36 | """function to patch over fail_json; package return data into an exception""" 37 | kwargs['failed'] = True 38 | raise AnsibleFailJson(kwargs) 39 | 40 | 41 | class TestRubrikPost(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 45 | exit_json=exit_json, 46 | fail_json=fail_json) 47 | self.mock_module_helper.start() 48 | self.addCleanup(self.mock_module_helper.stop) 49 | 50 | def test_module_fail_when_required_args_missing(self): 51 | with self.assertRaises(AnsibleFailJson): 52 | set_module_args({}) 53 | rubrik_post.main() 54 | 55 | @patch.object(rubrik_post.rubrik_cdm.rubrik_cdm.Connect, '_common_api', autospec=True, spec_set=True) 56 | def test_module_post(self, mock_common_api): 57 | 58 | def mock_get_post(): 59 | return {"data": [], "hasMore": False, "total": 0} 60 | 61 | set_module_args({ 62 | 'node_ip': '1.1.1.1', 63 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP', 64 | 'api_version': 'v1', 65 | 'api_endpoint': '/managed_volume', 66 | 'config': {"name": "AnsibleDemo", "volumeSize": 10737418240} 67 | }) 68 | 69 | mock_common_api.return_value = mock_get_post() 70 | 71 | with self.assertRaises(AnsibleExitJson) as result: 72 | rubrik_post.main() 73 | 74 | self.assertEqual(result.exception.args[0]['changed'], False) 75 | self.assertEqual(result.exception.args[0]['response'], {"data": [], "hasMore": False, "total": 0}) 76 | 77 | 78 | if __name__ == '__main__': 79 | unittest.main() 80 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_cluster_version.md: -------------------------------------------------------------------------------- 1 | # rubrik_cluster_version 2 | 3 | Retrieves the software version of the Rubrik cluster. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_cluster_version: 11 | 12 | - rubrik_cluster_version: 13 | provider: "{{ credentials }}" 14 | ``` 15 | 16 | # Arugments 17 | 18 | ## Common 19 | 20 | | Name | Description | Default | 21 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 22 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 27 | 28 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 29 | | --- | 30 | 31 | # Return Values 32 | 33 | | Name | Description | Returned | Type | 34 | |---------|------------------------------------|----------|--------| 35 | | version | The version of the Rubrik cluster. | success | string | 36 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/sanity/ignore.txt: -------------------------------------------------------------------------------- 1 | plugins/modules/rubrik_add_vcenter.py validate-modules:module-invalid-version-added 2 | plugins/modules/rubrik_assign_physical_host_fileset.py validate-modules:module-invalid-version-added 3 | plugins/modules/rubrik_assign_sla.py validate-modules:module-invalid-version-added 4 | plugins/modules/rubrik_aws_s3_cloudout.py validate-modules:module-invalid-version-added 5 | plugins/modules/rubrik_bootstrap.py validate-modules:module-invalid-version-added 6 | plugins/modules/rubrik_cluster_version.py validate-modules:module-invalid-version-added 7 | plugins/modules/rubrik_configure_cluster_location.py validate-modules:module-invalid-version-added 8 | plugins/modules/rubrik_configure_ntp.py validate-modules:module-invalid-version-added 9 | plugins/modules/rubrik_configure_smtp_settings.py validate-modules:module-invalid-version-added 10 | plugins/modules/rubrik_configure_timezone.py validate-modules:module-invalid-version-added 11 | plugins/modules/rubrik_create_sla.py validate-modules:module-invalid-version-added 12 | plugins/modules/rubrik_dns_servers.py validate-modules:module-invalid-version-added 13 | plugins/modules/rubrik_end_user_authorization.py validate-modules:module-invalid-version-added 14 | plugins/modules/rubrik_get.py validate-modules:module-invalid-version-added 15 | plugins/modules/rubrik_get_sql_live_mount.py validate-modules:module-invalid-version-added 16 | plugins/modules/rubrik_get_vsphere_live_mount.py validate-modules:module-invalid-version-added 17 | plugins/modules/rubrik_get_vsphere_live_mount_names.py validate-modules:module-invalid-version-added 18 | plugins/modules/rubrik_job_status.py validate-modules:module-invalid-version-added 19 | plugins/modules/rubrik_login_banner.py validate-modules:module-invalid-version-added 20 | plugins/modules/rubrik_managed_volume.py validate-modules:module-invalid-version-added 21 | plugins/modules/rubrik_nas_fileset.py validate-modules:module-invalid-version-added 22 | plugins/modules/rubrik_on_demand_snapshot.py validate-modules:module-invalid-version-added 23 | plugins/modules/rubrik_physical_fileset.py validate-modules:module-invalid-version-added 24 | plugins/modules/rubrik_physical_host.py validate-modules:module-invalid-version-added 25 | plugins/modules/rubrik_post.py validate-modules:module-invalid-version-added 26 | plugins/modules/rubrik_refresh_vcenter.py validate-modules:module-invalid-version-added 27 | plugins/modules/rubrik_sql_live_mount.py validate-modules:module-invalid-version-added 28 | plugins/modules/rubrik_sql_live_unmount.py validate-modules:module-invalid-version-added 29 | plugins/modules/rubrik_vsphere_instant_recovery.py validate-modules:module-invalid-version-added 30 | plugins/modules/rubrik_vsphere_live_mount.py validate-modules:module-invalid-version-added 31 | plugins/modules/rubrik_vsphere_live_unmount.py validate-modules:module-invalid-version-added 32 | 33 | tests/unit/test_rubrik_add_organization_protectable_object_mssql_server_host.py pep8:E501 34 | tests/unit/test_rubrik_add_organization_protectable_object_sql_server_availability_group.py pep8:E501 35 | tests/unit/test_rubrik_add_organization_protectable_object_sql_server_db.py pep8:E501 -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_get_vsphere_live_mount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_get_vsphere_live_mount 16 | short_description: Get existing Live Mounts for a vSphere VM. 17 | description: 18 | - Get existing Live Mounts for a vSphere VM. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | vm_name: 23 | description: 24 | - The name of the mounted vSphere VM. 25 | required: True 26 | type: str 27 | timeout: 28 | description: 29 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 30 | required: False 31 | type: int 32 | default: 15 33 | 34 | extends_documentation_fragment: 35 | - rubrikinc.cdm.credentials 36 | requirements: [rubrik_cdm] 37 | ''' 38 | 39 | 40 | EXAMPLES = ''' 41 | - rubrik_get_vsphere_live_mount: 42 | vm_name: 'ansible-tower' 43 | 44 | ''' 45 | 46 | RETURN = ''' 47 | version: 48 | description: The full response of `GET /v1/vmware/vm/snapshot/mount?vm_id={vm_id}`. 49 | returned: success 50 | type: dict 51 | ''' 52 | 53 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 54 | from ansible.module_utils.basic import AnsibleModule 55 | 56 | try: 57 | import rubrik_cdm 58 | HAS_RUBRIK_SDK = True 59 | except ImportError: 60 | HAS_RUBRIK_SDK = False 61 | 62 | 63 | def main(): 64 | """ Main entry point for Ansible module execution. 65 | """ 66 | 67 | results = {} 68 | 69 | argument_spec = dict( 70 | vm_name=dict(required=True, type='str'), 71 | timeout=dict(required=False, type='int', default=15), 72 | 73 | ) 74 | 75 | argument_spec.update(rubrik_argument_spec) 76 | 77 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 78 | 79 | ansible = module.params 80 | 81 | load_provider_variables(module) 82 | 83 | if not HAS_RUBRIK_SDK: 84 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 85 | 86 | node_ip, username, password, api_token = credentials(module) 87 | 88 | try: 89 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 90 | except Exception as error: 91 | module.fail_json(msg=str(error)) 92 | 93 | try: 94 | api_request = rubrik.get_vsphere_live_mount( 95 | ansible["vm_name"], 96 | ansible["timeout"]) 97 | except Exception as error: 98 | module.fail_json(msg=str(error)) 99 | 100 | results["response"] = api_request 101 | 102 | module.exit_json(**results) 103 | 104 | 105 | if __name__ == '__main__': 106 | main() 107 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_get_vsphere_live_mount_names.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_get_vsphere_live_mount_names 16 | short_description: Get existing Live Mount VM name(s) for a vSphere VM. 17 | description: 18 | - Get existing Live Mount VM name(s) for a vSphere VM. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | vm_name: 23 | description: 24 | - The name of the mounted vSphere VM. 25 | required: True 26 | type: str 27 | timeout: 28 | description: 29 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 30 | required: False 31 | type: int 32 | default: 15 33 | 34 | extends_documentation_fragment: 35 | - rubrikinc.cdm.credentials 36 | requirements: [rubrik_cdm] 37 | ''' 38 | 39 | 40 | EXAMPLES = ''' 41 | - rubrik_get_vsphere_live_mount_names: 42 | vm_name: 'ansible-tower' 43 | 44 | ''' 45 | 46 | RETURN = ''' 47 | version: 48 | description: A list of the Live Mounted VM names. 49 | returned: success 50 | type: list 51 | ''' 52 | 53 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 54 | from ansible.module_utils.basic import AnsibleModule 55 | 56 | try: 57 | import rubrik_cdm 58 | HAS_RUBRIK_SDK = True 59 | except ImportError: 60 | HAS_RUBRIK_SDK = False 61 | 62 | 63 | def main(): 64 | """ Main entry point for Ansible module execution. 65 | """ 66 | 67 | results = {} 68 | 69 | argument_spec = dict( 70 | vm_name=dict(required=True, type='str'), 71 | timeout=dict(required=False, type='int', default=15), 72 | 73 | ) 74 | 75 | argument_spec.update(rubrik_argument_spec) 76 | 77 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 78 | 79 | ansible = module.params 80 | 81 | load_provider_variables(module) 82 | 83 | if not HAS_RUBRIK_SDK: 84 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 85 | 86 | node_ip, username, password, api_token = credentials(module) 87 | 88 | try: 89 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 90 | except Exception as error: 91 | module.fail_json(msg=str(error)) 92 | 93 | try: 94 | api_request = rubrik.get_vsphere_live_mount_names( 95 | ansible["vm_name"], 96 | ansible["timeout"]) 97 | except Exception as error: 98 | module.fail_json(msg=str(error)) 99 | 100 | results["response"] = api_request 101 | 102 | module.exit_json(**results) 103 | 104 | 105 | if __name__ == '__main__': 106 | main() 107 | -------------------------------------------------------------------------------- /collection_dev.py: -------------------------------------------------------------------------------- 1 | # This file will update the module_utils import path in all modules to support Ansible Collections and then create the collection .tar 2 | 3 | import fileinput 4 | import os 5 | import argparse 6 | 7 | parser = argparse.ArgumentParser() 8 | parser.add_argument('-a', '--action', choices=['build', 'update_path'], required=True, help='Specify which action (build or test) you wish to use.') 9 | parser.add_argument('-p', '--platform', choices=['vscode', 'circleci'], default="vscode", required=False, help='The platform you wish to run the script against.') 10 | 11 | arguments = parser.parse_args() 12 | 13 | collections_path = "from ansible_collections.rubrikinc.cdm.plugins.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec" 14 | standard_path = "from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec" 15 | 16 | 17 | 18 | 19 | if arguments.action == 'build': 20 | # Create a list of all modules for processing 21 | modules = [] 22 | for dir_path, _, file_name in os.walk('./rubrikinc/cdm/plugins/modules'): 23 | for file in file_name: 24 | modules.append(os.path.join(dir_path, file)) 25 | 26 | # Update import path to support Ansible Collections 27 | for m in modules: 28 | with fileinput.FileInput(m, inplace=True) as file: 29 | for line in file: 30 | print(line.replace(standard_path, collections_path), end='') 31 | 32 | 33 | # Switch to the Collection directory and build the collection 34 | os.chdir('./rubrikinc/cdm') 35 | os.system('mv ./docs/create_documentation_block.py /tmp') 36 | os.system('mv ./docs/README.md /tmp') 37 | os.system('mv ./docs/SUMMARY.md /tmp') 38 | os.system('mv ./docs/template.md /tmp') 39 | os.system('mv ./docs/rubrik_module_template.py /tmp') 40 | 41 | os.system('ansible-galaxy collection build') 42 | 43 | os.system('mv /tmp/create_documentation_block.py ./docs') 44 | os.system('mv /tmp/README.md ./docs') 45 | os.system('mv /tmp/SUMMARY.md ./docs') 46 | os.system('mv /tmp/template.md ./docs') 47 | os.system('mv /tmp/rubrik_module_template.py ./docs') 48 | 49 | # Switch back to the root dir 50 | os.chdir('../..') 51 | 52 | 53 | # Revert changes to the import paths 54 | for m in modules: 55 | with fileinput.FileInput(m, inplace=True) as file: 56 | for line in file: 57 | print(line.replace(collections_path, standard_path), end='') 58 | else: 59 | # Create a list of all modules for processing 60 | modules = [] 61 | 62 | if arguments.platform == 'circleci': 63 | search_directory = os.walk("/home/circleci/.ansible/collections/ansible_collections/rubrikinc/cdm") 64 | else: 65 | search_directory = os.walk("/root/.ansible/collections/ansible_collections/rubrikinc/cdm/plugins/modules") 66 | print("VS Code") 67 | for dir_path, _, file_name in search_directory: 68 | for file in file_name: 69 | if '__pycache__' not in dir_path: 70 | modules.append(os.path.join(dir_path, file)) 71 | # Update import path to support Ansible Collections 72 | for m in modules: 73 | print(m) 74 | with fileinput.FileInput(m, inplace=True) as file: 75 | for line in file: 76 | print(line.replace(standard_path, collections_path), end='') 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_configure_cluster_location.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_configure_cluster_location 15 | short_description: Configure the Rubrik cluster location 16 | description: 17 | - Configure the Rubrik cluster location 18 | version_added: '2.8' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | location: 22 | description: 23 | - Geolocation of the cluster. 24 | required: True 25 | type: str 26 | timeout: 27 | description: 28 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 29 | required: False 30 | type: int 31 | default: 15 32 | 33 | extends_documentation_fragment: rubrikinc.cdm.credentials 34 | requirements: [rubrik_cdm] 35 | ''' 36 | 37 | EXAMPLES = ''' 38 | - rubrik_configure_cluster_location: 39 | location: St. Louis, Missouri 40 | ''' 41 | 42 | 43 | RETURN = ''' 44 | full_response: 45 | description: The full API response for PATCH /v1/cluster/me 46 | returned: on success 47 | type: dict 48 | 49 | idempotent_response: 50 | description: A "No changed required" message when the cluster location is already configured on the cluster. 51 | returned: When the module idempotent check is succesful. 52 | type: str 53 | sample: No change required. The Rubrik cluster is already configured with I(location) as its location. 54 | ''' 55 | 56 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 57 | from ansible.module_utils.basic import AnsibleModule 58 | 59 | try: 60 | import rubrik_cdm 61 | HAS_RUBRIK_SDK = True 62 | except ImportError: 63 | HAS_RUBRIK_SDK = False 64 | 65 | 66 | def main(): 67 | """ Main entry point for Ansible module execution. 68 | """ 69 | 70 | results = {} 71 | 72 | argument_spec = dict( 73 | location=dict(required=True, type='str'), 74 | timeout=dict(required=False, type='int', default=15), 75 | 76 | ) 77 | 78 | argument_spec.update(rubrik_argument_spec) 79 | 80 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 81 | 82 | ansible = module.params 83 | 84 | load_provider_variables(module) 85 | 86 | if not HAS_RUBRIK_SDK: 87 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 88 | 89 | node_ip, username, password, api_token = credentials(module) 90 | 91 | try: 92 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 93 | except Exception as error: 94 | module.fail_json(msg=str(error)) 95 | 96 | try: 97 | api_request = rubrik.configure_cluster_location(ansible["location"], ansible["timeout"]) 98 | except Exception as error: 99 | module.fail_json(msg=str(error)) 100 | 101 | if "No change required" in api_request: 102 | results["changed"] = False 103 | else: 104 | results["changed"] = True 105 | 106 | results["response"] = api_request 107 | 108 | module.exit_json(**results) 109 | 110 | 111 | if __name__ == '__main__': 112 | main() 113 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at build@rubrik.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_dns_servers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_dns_servers 15 | short_description: Configure the DNS Servers on the Rubrik cluster. 16 | description: 17 | - Configure the DNS Servers on the Rubrik cluster. 18 | version_added: '2.8' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | server_ip: 22 | description: 23 | - The DNS Server IPs you wish to add to the Rubrik cluster. 24 | required: True 25 | type: list 26 | elements: str 27 | timeout: 28 | description: 29 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 30 | required: False 31 | type: int 32 | default: 15 33 | 34 | extends_documentation_fragment: rubrikinc.cdm.credentials 35 | requirements: [rubrik_cdm] 36 | ''' 37 | 38 | EXAMPLES = ''' 39 | - rubrik_dns_servers: 40 | server_ip: ["192.168.100.20", "192.168.100.21"] 41 | ''' 42 | 43 | 44 | RETURN = ''' 45 | full_response: 46 | description: The full API response for POST /internal/cluster/me/dns_nameserver. 47 | returned: on success 48 | type: dict 49 | 50 | 51 | idempotent_response: 52 | description: A "No changed required" message when 53 | returned: When the module idempotent check is succesful. 54 | type: str 55 | sample: No change required. The Rubrik cluster is already configured with the provided DNS servers. 56 | ''' 57 | 58 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 59 | from ansible.module_utils.basic import AnsibleModule 60 | 61 | try: 62 | import rubrik_cdm 63 | HAS_RUBRIK_SDK = True 64 | except ImportError: 65 | HAS_RUBRIK_SDK = False 66 | 67 | 68 | def main(): 69 | """ Main entry point for Ansible module execution. 70 | """ 71 | 72 | results = {} 73 | 74 | argument_spec = dict( 75 | server_ip=dict(required=True, type='list', elements='str'), 76 | timeout=dict(required=False, type='int', default=15), 77 | 78 | ) 79 | 80 | argument_spec.update(rubrik_argument_spec) 81 | 82 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 83 | 84 | ansible = module.params 85 | 86 | load_provider_variables(module) 87 | 88 | if not HAS_RUBRIK_SDK: 89 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 90 | 91 | node_ip, username, password, api_token = credentials(module) 92 | 93 | try: 94 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 95 | except Exception as error: 96 | module.fail_json(msg=str(error)) 97 | 98 | try: 99 | api_request = rubrik.configure_dns_servers(ansible["server_ip"], ansible["timeout"]) 100 | except Exception as error: 101 | module.fail_json(msg=str(error)) 102 | 103 | if "No change required" in api_request: 104 | results["changed"] = False 105 | else: 106 | results["changed"] = True 107 | 108 | results["response"] = api_request 109 | 110 | module.exit_json(**results) 111 | 112 | 113 | if __name__ == '__main__': 114 | main() 115 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_login_banner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_login_banner 15 | short_description: Configure the Rubrik cluster login banner text. 16 | description: 17 | - Configure the Rubrik cluster login banner text. 18 | version_added: '2.8' 19 | author: Eric Alba (@KowMangler) 20 | options: 21 | banner_text: 22 | description: 23 | - The Login Banner you wish the Rubrik cluster to display prior to user login. 24 | required: True 25 | type: str 26 | timeout: 27 | description: 28 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 29 | required: False 30 | type: int 31 | default: 15 32 | 33 | extends_documentation_fragment: rubrikinc.cdm.credentials 34 | requirements: [rubrik_cdm] 35 | ''' 36 | 37 | EXAMPLES = ''' 38 | - rubrik_login_banner: 39 | banner_text: "This is a pre-login Banner. Welcome to Rubrik!" 40 | ''' 41 | 42 | 43 | RETURN = ''' 44 | full_response: 45 | description: The full API response for PUT /internal/cluster/me/login_banner 46 | returned: on success 47 | type: dict 48 | 49 | idempotent_response: 50 | description: A "No changed required" message when the banner text is identical to that which is already configured on the cluster. 51 | returned: When the module idempotent check is succesful. 52 | type: str 53 | sample: No change required. The Rubrik cluster is already configured with I(banner_text) as it's banner. 54 | ''' 55 | 56 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 57 | from ansible.module_utils.basic import AnsibleModule 58 | 59 | try: 60 | import rubrik_cdm 61 | HAS_RUBRIK_SDK = True 62 | except ImportError: 63 | HAS_RUBRIK_SDK = False 64 | 65 | 66 | def main(): 67 | """ Main entry point for Ansible module execution. 68 | """ 69 | 70 | results = {} 71 | 72 | argument_spec = dict( 73 | banner_text=dict(required=True, type='str'), 74 | timeout=dict(required=False, type='int', default=15), 75 | ) 76 | 77 | argument_spec.update(rubrik_argument_spec) 78 | 79 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 80 | 81 | ansible = module.params 82 | 83 | load_provider_variables(module) 84 | 85 | if not HAS_RUBRIK_SDK: 86 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 87 | 88 | node_ip, username, password, api_token = credentials(module) 89 | 90 | try: 91 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 92 | except Exception as error: 93 | module.fail_json(msg=str(error)) 94 | 95 | try: 96 | api_request = rubrik.configure_login_banner(ansible["banner_text"], ansible["timeout"]) 97 | except Exception as error: 98 | module.fail_json(msg=str(error)) 99 | 100 | if "No change required" in api_request: 101 | results["changed"] = False 102 | else: 103 | results["changed"] = True 104 | 105 | results["response"] = api_request 106 | 107 | module.exit_json(**results) 108 | 109 | 110 | if __name__ == '__main__': 111 | main() 112 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_vsphere_live_unmount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_vsphere_live_unmount 16 | short_description: Delete a vSphere Live Mount from the Rubrik cluster. 17 | description: 18 | - Delete a vSphere Live Mount from the Rubrik cluster. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | mounted_vm_name: 23 | description: 24 | - The name of the Live Mounted vSphere VM to be unmounted. 25 | required: True 26 | type: str 27 | force: 28 | description: 29 | - Force unmount to remove metadata when the datastore of the Live Mount virtual machine was moved off of the Rubrik cluster. 30 | required: False 31 | type: bool 32 | default: False 33 | timeout: 34 | description: 35 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 36 | required: False 37 | type: int 38 | default: 30 39 | 40 | extends_documentation_fragment: 41 | - rubrikinc.cdm.credentials 42 | requirements: [rubrik_cdm] 43 | ''' 44 | 45 | EXAMPLES = ''' 46 | - rubrik_vsphere_live_unmount: 47 | mounted_vm_name: 'ansible-tower' 48 | 49 | - rubrik_vsphere_live_unmount: 50 | mounted_vm_name: 'ansible-tower' 51 | force: True 52 | 53 | ''' 54 | 55 | RETURN = ''' 56 | full_response: 57 | description: The full response of `DELETE /vmware/vm/snapshot/mount/{id}?force={bool}`. 58 | returned: success 59 | type: dict 60 | ''' 61 | 62 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 63 | from ansible.module_utils.basic import AnsibleModule 64 | 65 | try: 66 | import rubrik_cdm 67 | HAS_RUBRIK_SDK = True 68 | except ImportError: 69 | HAS_RUBRIK_SDK = False 70 | 71 | 72 | def main(): 73 | """ Main entry point for Ansible module execution. 74 | """ 75 | 76 | results = {} 77 | 78 | argument_spec = dict( 79 | mounted_vm_name=dict(required=True, type='str'), 80 | force=dict(required=False, type='bool', default=False), 81 | timeout=dict(required=False, type='int', default=30), 82 | 83 | ) 84 | 85 | argument_spec.update(rubrik_argument_spec) 86 | 87 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 88 | 89 | ansible = module.params 90 | 91 | load_provider_variables(module) 92 | 93 | if not HAS_RUBRIK_SDK: 94 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 95 | 96 | node_ip, username, password, api_token = credentials(module) 97 | 98 | try: 99 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 100 | except Exception as error: 101 | module.fail_json(msg=str(error)) 102 | 103 | try: 104 | api_request = rubrik.vsphere_live_unmount( 105 | ansible["mounted_vm_name"], 106 | ansible["force"], 107 | ansible["timeout"]) 108 | except Exception as error: 109 | module.fail_json(msg=str(error)) 110 | 111 | results["response"] = api_request 112 | 113 | module.exit_json(**results) 114 | 115 | 116 | if __name__ == '__main__': 117 | main() 118 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_get_sql_live_mount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_get_sql_live_mount 16 | short_description: Retrieve the Live Mounts for a MSSQL source database. 17 | description: 18 | - Retrieve the Live Mounts for a MSSQL source database. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | db_name: 23 | description: 24 | - The name of the source database with Live Mounts. 25 | required: True 26 | type: str 27 | sql_instance: 28 | description: 29 | - The SQL instance name of the source database. 30 | required: True 31 | type: str 32 | sql_host: 33 | description: 34 | - The SQL host name of the source database/instance. 35 | required: True 36 | type: str 37 | timeout: 38 | description: 39 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 40 | required: False 41 | type: int 42 | default: 30 43 | 44 | extends_documentation_fragment: 45 | - rubrikinc.cdm.credentials 46 | requirements: [rubrik_cdm] 47 | ''' 48 | 49 | 50 | EXAMPLES = ''' 51 | - rubrik_get_sql_live_mount: 52 | db_name: 'AdventureWorks2016' 53 | sql_instance: 'MSSQLSERVER' 54 | sql_host: 'sql.rubrikdemo.com' 55 | ''' 56 | 57 | 58 | RETURN = ''' 59 | version: 60 | description: The full response of `GET /v1/mssql/db/mount?source_database_id={id}`. 61 | returned: success 62 | type: dict 63 | ''' 64 | 65 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 66 | from ansible.module_utils.basic import AnsibleModule 67 | 68 | try: 69 | import rubrik_cdm 70 | HAS_RUBRIK_SDK = True 71 | except ImportError: 72 | HAS_RUBRIK_SDK = False 73 | 74 | 75 | def main(): 76 | """ Main entry point for Ansible module execution. 77 | """ 78 | 79 | results = {} 80 | 81 | argument_spec = dict( 82 | db_name=dict(required=True, type='str'), 83 | sql_instance=dict(required=True, type='str'), 84 | sql_host=dict(required=True, type='str'), 85 | timeout=dict(required=False, type='int', default=30), 86 | 87 | ) 88 | 89 | argument_spec.update(rubrik_argument_spec) 90 | 91 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 92 | 93 | ansible = module.params 94 | 95 | load_provider_variables(module) 96 | 97 | if not HAS_RUBRIK_SDK: 98 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 99 | 100 | node_ip, username, password, api_token = credentials(module) 101 | 102 | try: 103 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 104 | except Exception as error: 105 | module.fail_json(msg=str(error)) 106 | 107 | try: 108 | api_request = rubrik.get_sql_live_mount( 109 | ansible["db_name"], 110 | ansible["sql_instance"], 111 | ansible["sql_host"], 112 | ansible["timeout"]) 113 | except Exception as error: 114 | module.fail_json(msg=str(error)) 115 | 116 | results["response"] = api_request 117 | 118 | module.exit_json(**results) 119 | 120 | 121 | if __name__ == '__main__': 122 | main() 123 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_configure_ntp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_configure_ntp 15 | short_description: Configure connection information for the NTP servers used by the Rubrik cluster for time synchronization. 16 | description: 17 | - Configure connection information for the NTP servers used by the Rubrik cluster for time synchronization. 18 | version_added: '2.8' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | ntp_servers: 22 | description: 23 | - A list of the NTP server(s) you wish to configure the Rubrik cluster to use. 24 | required: True 25 | type: list 26 | elements: str 27 | timeout: 28 | description: 29 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 30 | required: False 31 | type: int 32 | default: 15 33 | 34 | extends_documentation_fragment: rubrikinc.cdm.credentials 35 | requirements: [rubrik_cdm] 36 | ''' 37 | 38 | EXAMPLES = ''' 39 | - rubrik_configure_ntp: 40 | ntp_server: ["192.168.10.121", "192.168.10.122"] 41 | ''' 42 | 43 | 44 | RETURN = ''' 45 | success_response: 46 | description: A 204 status code success message. 47 | returned: on success 48 | type: dict 49 | 50 | idempotent_response: 51 | description: A "No changed required" message when the cluster is already configured with the provided I(ntp_servers). 52 | returned: When the module idempotent check is succesful. 53 | type: str 54 | sample: No change required. The NTP server(s) I(ntp_server) has already been added to the Rubrik cluster. 55 | ''' 56 | 57 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 58 | from ansible.module_utils.basic import AnsibleModule 59 | 60 | try: 61 | import rubrik_cdm 62 | HAS_RUBRIK_SDK = True 63 | except ImportError: 64 | HAS_RUBRIK_SDK = False 65 | 66 | 67 | def main(): 68 | """ Main entry point for Ansible module execution. 69 | """ 70 | 71 | results = {} 72 | 73 | argument_spec = dict( 74 | ntp_servers=dict(required=True, type='list', elements='str'), 75 | timeout=dict(required=False, type='int', default=15), 76 | 77 | ) 78 | 79 | argument_spec.update(rubrik_argument_spec) 80 | 81 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 82 | 83 | ansible = module.params 84 | 85 | load_provider_variables(module) 86 | 87 | if not HAS_RUBRIK_SDK: 88 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 89 | 90 | node_ip, username, password, api_token = credentials(module) 91 | 92 | try: 93 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 94 | except Exception as error: 95 | module.fail_json(msg=str(error)) 96 | 97 | try: 98 | api_request = rubrik.configure_ntp(ansible["ntp_servers"], ansible["timeout"]) 99 | except Exception as error: 100 | module.fail_json(msg=str(error)) 101 | 102 | if "No change required" in api_request: 103 | results["changed"] = False 104 | else: 105 | results["changed"] = True 106 | 107 | results["response"] = api_request 108 | 109 | module.exit_json(**results) 110 | 111 | 112 | if __name__ == '__main__': 113 | main() 114 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_get_vsphere_live_mount.md: -------------------------------------------------------------------------------- 1 | # rubrik_get_vsphere_live_mount 2 | 3 | Get existing Live Mounts for a vSphere VM. 4 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 5 | 6 | # Example 7 | 8 | ```yaml 9 | - rubrik_get_vsphere_live_mount: 10 | vm_name: 'ansible-tower' 11 | ``` 12 | 13 | # Arugments 14 | 15 | ## Common 16 | 17 | | Name | Description | Default | 18 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 19 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 20 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 21 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 24 | 25 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 26 | | --- | 27 | 28 | ## Module Specific 29 | 30 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 31 | |------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 32 | | vm_name | The name of the mounted vSphere VM. | | str | | true | | 33 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 34 | 35 | # Return Values 36 | 37 | | Name | Description | Returned | Type | Aliases | 38 | |----------|----------------------------------------------------------------------------|----------|------|---------| 39 | | response | The full response of `GET /v1/vmware/vm/snapshot/mount?vm_id={vm_id}` | success | dict | | 40 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_get_vsphere_live_mount_names.md: -------------------------------------------------------------------------------- 1 | # rubrik_get_vsphere_live_mount_names 2 | 3 | Get existing Live Mount VM name(s) for a vSphere VM. 4 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 5 | 6 | # Example 7 | 8 | ```yaml 9 | - rubrik_get_vsphere_live_mount_names: 10 | vm_name: 'ansible-tower' 11 | ``` 12 | 13 | # Arugments 14 | 15 | ## Common 16 | 17 | | Name | Description | Default | 18 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 19 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 20 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 21 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 24 | 25 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 26 | | --- | 27 | 28 | ## Module Specific 29 | 30 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 31 | |------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 32 | | vm_name | The name of the mounted vSphere VM. | | str | | true | | 33 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 34 | 35 | # Return Values 36 | 37 | | Name | Description | Returned | Type | Aliases | 38 | |----------|----------------------------------------------------------------------------|----------|------|---------| 39 | | response | A list of the Live Mounted VM names. | success | list | | 40 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_refresh_vcenter.md: -------------------------------------------------------------------------------- 1 | # rubrik_refresh_vcenter 2 | 3 | Refresh the metadata for the specified vCenter Server. Refreshing vCenter metadata happens automatically on a regular basis, but it may be necessary to trigger a refresh to protect a newly deployed VM. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_refresh_vcenter: 11 | vcenter_ip: "vcenter.example.com" 12 | ``` 13 | 14 | # Arugments 15 | 16 | ## Common 17 | 18 | | Name | Description | Default | 19 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 20 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 21 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 25 | 26 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 27 | | --- | 28 | 29 | ## Module Specific 30 | 31 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 32 | |---------------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 33 | | vcenter_ip | The IP address or FQDN of the vCenter you wish to refesh. | | string | | true | | 34 | | wait_for_completion | Flag that determines if the method should wait for the job to complete before exiting. | true | bool | | | | 35 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 36 | 37 | # Return Values 38 | 39 | | Name | Description | Returned | Type | 40 | |----------|-----------------------------------------|----------|------| 41 | | response | The full API response for the API call. | success | dict | 42 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_job_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_job_status 16 | short_description: Monitor the progress of a Rubrik job. 17 | description: 18 | - Certain Rubrik operations may not instantaneously complete. In those cases we have the ability to monitor the status of 19 | the job through a job status link provided in the actions API response body. In those cases the Ansible Module will return a "job_status_link" 20 | which can then be registered and used as a variable in the rubrik_job_status module. The rubrik_job_status will check on the status of the 21 | job every 20 seconds until the job has successfully completed for failed. 22 | version_added: '2.8' 23 | author: Rubrik Build Team (@drew-russell) 24 | options: 25 | url: 26 | description: 27 | - The job status URL provided by a previous API call. 28 | required: True 29 | type: str 30 | wait_for_completion: 31 | description: 32 | - Flag that determines if the method should wait for the job to complete before exiting. 33 | required: False 34 | type: bool 35 | default: True 36 | timeout: 37 | description: 38 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 39 | required: False 40 | type: int 41 | default: 15 42 | 43 | 44 | extends_documentation_fragment: rubrikinc.cdm.credentials 45 | requirements: [rubrik_cdm] 46 | ''' 47 | 48 | EXAMPLES = ''' 49 | - rubrik_job_status: 50 | url: "https://192.168.1.100/api/v1/vmware/vm/request/CREATE_VMWARE_SNAPSHOT_fbcb1d87-9872-4227-a68c-5982f48-vm-289386_e837-a04c-4327-915b-7698d2c5ecf48:::0" 51 | ''' 52 | 53 | RETURN = ''' 54 | response: 55 | description: The full API response for the API call. 56 | returned: on success 57 | type: dict 58 | sample: differs depending on the object_type being monitored. 59 | ''' 60 | 61 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 62 | from ansible.module_utils.basic import AnsibleModule 63 | 64 | try: 65 | import rubrik_cdm 66 | HAS_RUBRIK_SDK = True 67 | except ImportError: 68 | HAS_RUBRIK_SDK = False 69 | 70 | 71 | def main(): 72 | """ Main entry point for Ansible module execution. 73 | """ 74 | 75 | results = {} 76 | 77 | argument_spec = dict( 78 | url=dict(required=True), 79 | wait_for_completion=dict(required=False, type='bool', default=True), 80 | timeout=dict(required=False, type='int', default=15) 81 | ) 82 | 83 | # Start Parameters 84 | argument_spec.update(rubrik_argument_spec) 85 | # End Parameters 86 | 87 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 88 | 89 | ansible = module.params 90 | 91 | load_provider_variables(module) 92 | 93 | if not HAS_RUBRIK_SDK: 94 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 95 | 96 | node_ip, username, password, api_token = credentials(module) 97 | 98 | try: 99 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 100 | except Exception as error: 101 | module.fail_json(msg=str(error)) 102 | 103 | try: 104 | api_request = rubrik.job_status(ansible["url"], ansible["wait_for_completion"], ansible["timeout"]) 105 | except Exception as error: 106 | module.fail_json(msg=str(error)) 107 | 108 | results["changed"] = False 109 | 110 | results["response"] = api_request 111 | 112 | module.exit_json(**results) 113 | 114 | 115 | if __name__ == '__main__': 116 | main() 117 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_post.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_post 16 | short_description: Send a GET request to the provided Rubrik API endpoint. 17 | description: 18 | - Send a GET request to the provided Rubrik API endpoint. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | api_version: 23 | description: 24 | - The version of the Rubrik CDM API to call. 25 | required: True 26 | type: str 27 | choices: [v1, v2, internal] 28 | api_endpoint: 29 | description: 30 | - The endpoint of the Rubrik CDM API to call (ex. /cluster/me). 31 | required: True 32 | type: str 33 | config: 34 | description: 35 | - The specified data to send with the API call. 36 | required: True 37 | type: raw 38 | authentication: 39 | description: 40 | - Flag that specifies whether or not to utilize authentication when making the API call. 41 | required: False 42 | type: bool 43 | default: True 44 | timeout: 45 | description: 46 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 47 | required: False 48 | type: int 49 | default: 15 50 | 51 | extends_documentation_fragment: rubrikinc.cdm.credentials 52 | requirements: [rubrik_cdm] 53 | ''' 54 | 55 | EXAMPLES = ''' 56 | - name: Create a new Managed Volume 57 | rubrik_post: 58 | api_version: internal 59 | api_endpoint: "/managed_volume" 60 | config: {"name": "AnsibleDemo", "volumeSize": 10737418240} 61 | ''' 62 | 63 | RETURN = ''' 64 | response: 65 | description: The response body of the API call.. 66 | returned: success 67 | type: str 68 | sample: {"acceptedEulaVersion": "1.1", "name": "DEVOPS-1"} 69 | ''' 70 | 71 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 72 | from ansible.module_utils.basic import AnsibleModule 73 | 74 | try: 75 | import rubrik_cdm 76 | HAS_RUBRIK_SDK = True 77 | except ImportError: 78 | HAS_RUBRIK_SDK = False 79 | 80 | 81 | def main(): 82 | """ Main entry point for Ansible module execution. 83 | """ 84 | 85 | results = {} 86 | 87 | argument_spec = dict( 88 | api_version=dict(required=True, type='str', choices=['v1', 'v2', 'internal']), 89 | api_endpoint=dict(required=True, type='str'), 90 | config=dict(required=True, type='raw'), 91 | authentication=dict(required=False, type='bool', default=True), 92 | timeout=dict(required=False, type='int', default=15), 93 | ) 94 | 95 | argument_spec.update(rubrik_argument_spec) 96 | 97 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 98 | 99 | ansible = module.params 100 | 101 | load_provider_variables(module) 102 | 103 | if not HAS_RUBRIK_SDK: 104 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 105 | 106 | node_ip, username, password, api_token = credentials(module) 107 | 108 | try: 109 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token, enable_logging=True) 110 | except Exception as error: 111 | module.fail_json(msg=str(error)) 112 | 113 | try: 114 | api_request = rubrik.post(ansible["api_version"], ansible["api_endpoint"], ansible["config"], ansible["timeout"], ansible["authentication"]) 115 | except Exception as error: 116 | module.fail_json(msg=str(error)) 117 | 118 | results["response"] = api_request 119 | 120 | module.exit_json(**results) 121 | 122 | 123 | if __name__ == '__main__': 124 | main() 125 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_dns_servers.md: -------------------------------------------------------------------------------- 1 | # rubrik_dns_servers 2 | 3 | Configure the DNS Servers on the Rubrik cluster. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_dns_servers: 11 | server_ip: ["192.168.100.20", "192.168.100.21"] 12 | ``` 13 | 14 | # Arugments 15 | 16 | ## Common 17 | 18 | | Name | Description | Default | 19 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 20 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 21 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 25 | 26 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 27 | | --- | 28 | 29 | ## Module Specific 30 | 31 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 32 | |-----------|--------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 33 | | server_ip | The DNS Server IPs you wish to add to the Rubrik cluster. | | list | | true | | 34 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 35 | 36 | # Return Values 37 | 38 | | Name | Description | Returned | Type | Aliases | 39 | |----------|-----------------------------------------------------------------------------------|------------------------------------------------|--------|---------| 40 | | response | The full API response for POST /internal/cluster/me/dns_nameserver. | success | dict | | 41 | | response | A "No changed required" message when the DNS servers have already been configured | When the module idempotent check is succesful. | string | | 42 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_dns_servers.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_dns_servers as rubrik_dns_servers 10 | 11 | 12 | def set_module_args(args): 13 | """prepare arguments so that they will be picked up during module creation""" 14 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 15 | basic._ANSIBLE_ARGS = to_bytes(args) 16 | 17 | 18 | class AnsibleExitJson(Exception): 19 | """Exception class to be raised by module.exit_json and caught by the test case""" 20 | pass 21 | 22 | 23 | class AnsibleFailJson(Exception): 24 | """Exception class to be raised by module.fail_json and caught by the test case""" 25 | pass 26 | 27 | 28 | def exit_json(*args, **kwargs): 29 | """function to patch over exit_json; package return data into an exception""" 30 | if 'changed' not in kwargs: 31 | kwargs['changed'] = False 32 | raise AnsibleExitJson(kwargs) 33 | 34 | 35 | def fail_json(*args, **kwargs): 36 | """function to patch over fail_json; package return data into an exception""" 37 | kwargs['failed'] = True 38 | raise AnsibleFailJson(kwargs) 39 | 40 | 41 | class TestRubrikDNSServers(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 45 | exit_json=exit_json, 46 | fail_json=fail_json) 47 | self.mock_module_helper.start() 48 | self.addCleanup(self.mock_module_helper.stop) 49 | 50 | def test_module_fail_when_required_args_missing(self): 51 | with self.assertRaises(AnsibleFailJson): 52 | set_module_args({}) 53 | rubrik_dns_servers.main() 54 | 55 | @patch.object(rubrik_dns_servers.rubrik_cdm.rubrik_cdm.Connect, 'post', autospec=True, spec_set=True) 56 | @patch.object(rubrik_dns_servers.rubrik_cdm.rubrik_cdm.Connect, 'get', autospec=True, spec_set=True) 57 | def test_module_configure_dns_servers(self, mock_get, mock_post): 58 | 59 | def mock_get_internal_cluster_me_dns_nameserver(): 60 | return [] 61 | 62 | def mock_post_internal_cluster_me_dns_nameserver(): 63 | return {'status_code': '204'} 64 | 65 | set_module_args({ 66 | 'server_ip': ['server_1'], 67 | 'node_ip': '1.1.1.1', 68 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 69 | }) 70 | 71 | mock_get.return_value = mock_get_internal_cluster_me_dns_nameserver() 72 | 73 | mock_post.return_value = mock_post_internal_cluster_me_dns_nameserver() 74 | 75 | with self.assertRaises(AnsibleExitJson) as result: 76 | rubrik_dns_servers.main() 77 | 78 | self.assertEqual(result.exception.args[0]['changed'], True) 79 | self.assertEqual(result.exception.args[0]['response']['status_code'], '204') 80 | 81 | @patch.object(rubrik_dns_servers.rubrik_cdm.rubrik_cdm.Connect, 'get', autospec=True, spec_set=True) 82 | def test_module_idempotence(self, mock_get): 83 | 84 | def mock_get_internal_cluster_me_dns_nameserver(): 85 | return ['server_1'] 86 | 87 | set_module_args({ 88 | 'server_ip': ['server_1'], 89 | 'node_ip': '1.1.1.1', 90 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 91 | }) 92 | 93 | mock_get.return_value = mock_get_internal_cluster_me_dns_nameserver() 94 | 95 | with self.assertRaises(AnsibleExitJson) as result: 96 | rubrik_dns_servers.main() 97 | 98 | self.assertEqual(result.exception.args[0]['changed'], False) 99 | self.assertEqual( 100 | result.exception.args[0]['response'], 101 | 'No change required. The Rubrik cluster is already configured with the provided DNS servers.') 102 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_refresh_vcenter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2020 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_refresh_vcenter 16 | short_description: Refresh the metadata for the specified vCenter Server 17 | description: 18 | - Refresh the metadata for the specified vCenter Server. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | vcenter_ip: 23 | description: 24 | - The IP address or FQDN of the vCenter you wish to refresh metadata from 25 | required: True 26 | type: str 27 | wait_for_completion: 28 | description: 29 | - Flag that determines if the method should wait for the job to complete before exiting. 30 | required: False 31 | type: bool 32 | default: True 33 | timeout: 34 | description: 35 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 36 | required: False 37 | type: int 38 | default: 15 39 | 40 | extends_documentation_fragment: rubrikinc.cdm.credentials 41 | requirements: [rubrik_cdm] 42 | ''' 43 | 44 | EXAMPLES = ''' 45 | - name: Refresh the metadata for the specified vCenter Server 46 | rubrik_refresh_vcenter: 47 | vcenter_ip: vcenter.example.com 48 | wait_for_completion: true 49 | ''' 50 | 51 | RETURN = ''' 52 | full_response: 53 | description: The full API response for the API call. 54 | returned: on success 55 | type: dict 56 | sample: 57 | { 58 | "endTime": "2020-04-07T00:30:28.448Z", 59 | "id": "REFRESH_METADATA_01234567-8910-1abc-d435-0abc1234d567_01234567-8910-1abc-d435-0abc1234d567:::0", 60 | "links": [ 61 | { 62 | "href": "https://rubrik/api/v1/vmware/vcenter/request/REFRESH_METADATA_01234567:::0", 63 | "rel": "self" 64 | } 65 | ], 66 | "nodeId": "cluster:::RVM111S000000", 67 | "startTime": "2020-04-07T00:29:50.585Z", 68 | "status": "SUCCEEDED" 69 | } 70 | ''' 71 | 72 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 73 | from ansible.module_utils.basic import AnsibleModule 74 | 75 | try: 76 | import rubrik_cdm 77 | HAS_RUBRIK_SDK = True 78 | except ImportError: 79 | HAS_RUBRIK_SDK = False 80 | 81 | 82 | def main(): 83 | """ Main entry point for Ansible module execution. 84 | """ 85 | 86 | results = {} 87 | 88 | argument_spec = dict( 89 | vcenter_ip=dict(required=True, type='str'), 90 | wait_for_completion=dict(required=False, type='bool', default=True), 91 | timeout=dict(required=False, type='int', default=15) 92 | ) 93 | 94 | argument_spec.update(rubrik_argument_spec) 95 | 96 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 97 | 98 | ansible = module.params 99 | 100 | load_provider_variables(module) 101 | 102 | if not HAS_RUBRIK_SDK: 103 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 104 | 105 | node_ip, username, password, api_token = credentials(module) 106 | 107 | try: 108 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 109 | except Exception as error: 110 | module.fail_json(msg=str(error)) 111 | 112 | try: 113 | api_request = rubrik.refresh_vcenter(ansible["vcenter_ip"], ansible["wait_for_completion"], ansible["timeout"]) 114 | except Exception as error: 115 | module.fail_json(msg=str(error)) 116 | 117 | results["changed"] = False 118 | 119 | results["response"] = api_request 120 | 121 | module.exit_json(**results) 122 | 123 | 124 | if __name__ == '__main__': 125 | main() 126 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_login_banner.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_login_banner as rubrik_login_banner 10 | 11 | 12 | def set_module_args(args): 13 | """prepare arguments so that they will be picked up during module creation""" 14 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 15 | basic._ANSIBLE_ARGS = to_bytes(args) 16 | 17 | 18 | class AnsibleExitJson(Exception): 19 | """Exception class to be raised by module.exit_json and caught by the test case""" 20 | pass 21 | 22 | 23 | class AnsibleFailJson(Exception): 24 | """Exception class to be raised by module.fail_json and caught by the test case""" 25 | pass 26 | 27 | 28 | def exit_json(*args, **kwargs): 29 | """function to patch over exit_json; package return data into an exception""" 30 | if 'changed' not in kwargs: 31 | kwargs['changed'] = False 32 | raise AnsibleExitJson(kwargs) 33 | 34 | 35 | def fail_json(*args, **kwargs): 36 | """function to patch over fail_json; package return data into an exception""" 37 | kwargs['failed'] = True 38 | raise AnsibleFailJson(kwargs) 39 | 40 | 41 | class TestRubrikLoginBanner(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 45 | exit_json=exit_json, 46 | fail_json=fail_json) 47 | self.mock_module_helper.start() 48 | self.addCleanup(self.mock_module_helper.stop) 49 | 50 | def test_module_fail_when_required_args_missing(self): 51 | with self.assertRaises(AnsibleFailJson): 52 | set_module_args({}) 53 | rubrik_login_banner.main() 54 | 55 | @patch.object(rubrik_login_banner.rubrik_cdm.rubrik_cdm.Connect, 'put', autospec=True, spec_set=True) 56 | @patch.object(rubrik_login_banner.rubrik_cdm.rubrik_cdm.Connect, 'get', autospec=True, spec_set=True) 57 | def test_module_login_banner(self, mock_get, mock_put): 58 | 59 | def mock_get_internal_cluster_me_login_banner(): 60 | return {} 61 | 62 | def mock_put_internal_cluster_me_login_banner(): 63 | return {'loginBanner': 'Banner Test'} 64 | 65 | set_module_args({ 66 | 'banner_text': 'Banner Test', 67 | 'node_ip': '1.1.1.1', 68 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 69 | }) 70 | 71 | mock_get.return_value = mock_get_internal_cluster_me_login_banner() 72 | 73 | mock_put.return_value = mock_put_internal_cluster_me_login_banner() 74 | 75 | with self.assertRaises(AnsibleExitJson) as result: 76 | rubrik_login_banner.main() 77 | 78 | self.assertEqual(result.exception.args[0]['changed'], True) 79 | self.assertEqual(result.exception.args[0]['response']['loginBanner'], 'Banner Test') 80 | 81 | @patch.object(rubrik_login_banner.rubrik_cdm.rubrik_cdm.Connect, 'get', autospec=True, spec_set=True) 82 | def test_module_idempotence(self, mock_get): 83 | 84 | def mock_get_internal_cluster_me_login_banner(): 85 | return {'loginBanner': 'Banner Test'} 86 | 87 | set_module_args({ 88 | 'banner_text': 'Banner Test', 89 | 'node_ip': '1.1.1.1', 90 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 91 | }) 92 | 93 | mock_get.return_value = mock_get_internal_cluster_me_login_banner() 94 | 95 | with self.assertRaises(AnsibleExitJson) as result: 96 | rubrik_login_banner.main() 97 | 98 | self.assertEqual(result.exception.args[0]['changed'], False) 99 | self.assertEqual( 100 | result.exception.args[0]['response'], 101 | "No change required. The Rubrik cluster is already configured with the login banner text '`banner`'.") 102 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_login_banner.md: -------------------------------------------------------------------------------- 1 | # rubrik_login_banner 2 | 3 | Configure the Rubrik cluster login banner text. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_login_banner: 11 | banner_text: "This is a pre-login Banner. Welcome to Rubrik!" 12 | ``` 13 | 14 | # Arugments 15 | 16 | ## Common 17 | 18 | | Name | Description | Default | 19 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 20 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 21 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 25 | 26 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 27 | | --- | 28 | 29 | ## Module Specific 30 | 31 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 32 | |-----------|--------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 33 | | rubrik_login_banner | The Login Banner displayed by the Rubrik cluster to display prior to user login. | | str | | true | | 34 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 35 | 36 | # Return Values 37 | 38 | | Name | Description | Returned | Type | Aliases | 39 | |----------|-----------------------------------------------------------------------------------|------------------------------------------------|--------|---------| 40 | | response | The full API response for PUT /internal/cluster/me/login_banner | success | dict | | 41 | | response | A "No change required" message when the banner text is identical to that which is already configured on the cluster. | When the module idempotent check is succesful. | string | | 42 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_sql_live_unmount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_sql_live_unmount 16 | short_description: Delete a Microsoft SQL Live Mount from the Rubrik cluster. 17 | description: 18 | - Delete a Microsoft SQL Live Mount from the Rubrik cluster. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | mounted_db_name: 23 | description: 24 | - The name of the Live Mounted database to be unmounted. 25 | required: True 26 | type: str 27 | sql_instance: 28 | description: 29 | - The name of the MSSQL instance managing the Live Mounted database to be unmounted. 30 | required: True 31 | type: str 32 | sql_host: 33 | description: 34 | - The name of the MSSQL host running the Live Mounted database to be unmounted. 35 | required: True 36 | type: str 37 | force: 38 | description: 39 | - Remove all data within the Rubrik cluster related to the Live Mount, even if the SQL Server database cannot be contacted. 40 | required: False 41 | type: bool 42 | default: False 43 | timeout: 44 | description: 45 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 46 | required: False 47 | type: int 48 | default: 30 49 | 50 | extends_documentation_fragment: 51 | - rubrikinc.cdm.credentials 52 | requirements: [rubrik_cdm] 53 | ''' 54 | 55 | 56 | EXAMPLES = ''' 57 | - rubrik_sql_live_mount: 58 | mounted_db_name: 'AdventureWorks2016' 59 | sql_instance: 'MSSQLSERVER' 60 | sql_host: 'sql.rubrikdemo.com' 61 | force: True 62 | ''' 63 | 64 | 65 | RETURN = ''' 66 | full_response: 67 | description: The full response of `DELETE /mssql/db/mount/{id}?force={bool}`. 68 | returned: success 69 | type: dict 70 | ''' 71 | 72 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 73 | from ansible.module_utils.basic import AnsibleModule 74 | 75 | try: 76 | import rubrik_cdm 77 | HAS_RUBRIK_SDK = True 78 | except ImportError: 79 | HAS_RUBRIK_SDK = False 80 | 81 | 82 | def main(): 83 | """ Main entry point for Ansible module execution. 84 | """ 85 | 86 | results = {} 87 | 88 | argument_spec = dict( 89 | mounted_db_name=dict(required=True, type='str'), 90 | sql_instance=dict(required=True, type='str'), 91 | sql_host=dict(required=True, type='str'), 92 | force=dict(required=False, type='bool', default=False), 93 | timeout=dict(required=False, type='int', default=30), 94 | 95 | ) 96 | 97 | argument_spec.update(rubrik_argument_spec) 98 | 99 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 100 | 101 | ansible = module.params 102 | 103 | load_provider_variables(module) 104 | 105 | if not HAS_RUBRIK_SDK: 106 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 107 | 108 | node_ip, username, password, api_token = credentials(module) 109 | 110 | try: 111 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 112 | except Exception as error: 113 | module.fail_json(msg=str(error)) 114 | 115 | try: 116 | api_request = rubrik.sql_live_unmount( 117 | ansible["mounted_db_name"], 118 | ansible["sql_instance"], 119 | ansible["sql_host"], 120 | ansible["force"], 121 | ansible["timeout"]) 122 | except Exception as error: 123 | module.fail_json(msg=str(error)) 124 | 125 | results["response"] = api_request 126 | 127 | module.exit_json(**results) 128 | 129 | 130 | if __name__ == '__main__': 131 | main() 132 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_get_sql_live_mount.md: -------------------------------------------------------------------------------- 1 | # rubrik_get_sql_live_mount 2 | 3 | Retrieve the Live Mounts for a MSSQL source database. 4 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 5 | 6 | # Example 7 | 8 | ```yaml 9 | - rubrik_sql_live_mount: 10 | db_name: 'AdventureWorks2016' 11 | sql_instance: 'MSSQLSERVER' 12 | sql_host: 'sql.rubrikdemo.com' 13 | ``` 14 | 15 | # Arugments 16 | 17 | ## Common 18 | 19 | | Name | Description | Default | 20 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 21 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 26 | 27 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 28 | | --- | 29 | 30 | ## Module Specific 31 | 32 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 33 | |------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 34 | | db_name | The name of the source database with Live Mounts. | | str | | true | | 35 | | sql_instance | The SQL instance name of the source database. | None | str | |true| | 36 | | sql_host | The SQL host name of the source database/instance. | None | str | |true| | 37 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 30 | int | |false| | 38 | 39 | # Return Values 40 | 41 | | Name | Description | Returned | Type | Aliases | 42 | |----------|----------------------------------------------------------------------------|----------|------|---------| 43 | | response | The full response of `GET /v1/mssql/db/mount?source_database_id={id}`. | success | dict | | 44 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_add_organization_protectable_object_mssql_server_host.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_add_organization_protectable_object_mssql_server_host 15 | short_description: Add a MSSQL Server Host to an organization as a protectable object. 16 | description: 17 | - Add a MSSQL Server Host to an organization as a protectable object. 18 | version_added: '2.9' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | organization_name: 22 | description: 23 | - The name of the organization you wish to add the protectable object to. 24 | required: True 25 | type: str 26 | mssql_host: 27 | description: 28 | - The name of the MSSQL Host to add to the organization as a protectable object. 29 | required: True 30 | type: str 31 | timeout: 32 | description: 33 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 34 | required: False 35 | type: int 36 | default: 15 37 | 38 | extends_documentation_fragment: rubrikinc.cdm.credentials 39 | requirements: [rubrik_cdm] 40 | ''' 41 | 42 | EXAMPLES = ''' 43 | - rubrik_add_organization_protectable_object_mssql_server_host: 44 | organization_name: "Ansible" 45 | mssql_host: "demo-sql-host" 46 | ''' 47 | 48 | 49 | RETURN = ''' 50 | full_response: 51 | description: 52 | - The full API response for `POST /internal/role/{}/authorization`. 53 | returned: on success 54 | type: dict 55 | 56 | idempotent_response: 57 | description: A "No changed required" message when the MSSQL host has already been added to the organization. 58 | returned: When the module idempotent check is succesful. 59 | type: str 60 | sample: No change required. The MSSQL host `mssql_host` is already assigned to the `organization_name` organization. 61 | ''' 62 | 63 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 64 | from ansible.module_utils.basic import AnsibleModule 65 | 66 | try: 67 | import rubrik_cdm 68 | HAS_RUBRIK_SDK = True 69 | except ImportError: 70 | HAS_RUBRIK_SDK = False 71 | 72 | 73 | def main(): 74 | """ Main entry point for Ansible module execution. 75 | """ 76 | 77 | results = {} 78 | 79 | argument_spec = dict( 80 | organization_name=dict(required=True, type='str'), 81 | mssql_host=dict(required=True, type='str'), 82 | timeout=dict(required=False, type='int', default=15), 83 | ) 84 | 85 | argument_spec.update(rubrik_argument_spec) 86 | 87 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 88 | 89 | ansible = module.params 90 | 91 | organization_name = ansible["organization_name"] 92 | mssql_host = ansible["mssql_host"] 93 | timeout = ansible["timeout"] 94 | 95 | load_provider_variables(module) 96 | 97 | if not HAS_RUBRIK_SDK: 98 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 99 | 100 | node_ip, username, password, api_token = credentials(module) 101 | 102 | try: 103 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 104 | except Exception as error: 105 | module.fail_json(msg=str(error)) 106 | 107 | try: 108 | api_request = rubrik.add_organization_protectable_object_mssql_server_host(organization_name, mssql_host, timeout) 109 | except Exception as error: 110 | module.fail_json(msg=str(error)) 111 | 112 | if "No change required" in api_request: 113 | results["changed"] = False 114 | else: 115 | results["changed"] = True 116 | 117 | results["response"] = api_request 118 | 119 | module.exit_json(**results) 120 | 121 | 122 | if __name__ == '__main__': 123 | main() 124 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_refresh_vcenter.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | from rubrik_cdm.exceptions import RubrikException, APICallException 10 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_refresh_vcenter as rubrik_refresh_vcenter 11 | 12 | 13 | def set_module_args(args): 14 | """prepare arguments so that they will be picked up during module creation""" 15 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 16 | basic._ANSIBLE_ARGS = to_bytes(args) 17 | 18 | 19 | class AnsibleExitJson(Exception): 20 | """Exception class to be raised by module.exit_json and caught by the test case""" 21 | pass 22 | 23 | 24 | class AnsibleFailJson(Exception): 25 | """Exception class to be raised by module.fail_json and caught by the test case""" 26 | pass 27 | 28 | 29 | def exit_json(*args, **kwargs): 30 | """function to patch over exit_json; package return data into an exception""" 31 | if 'changed' not in kwargs: 32 | kwargs['changed'] = False 33 | raise AnsibleExitJson(kwargs) 34 | 35 | 36 | def fail_json(*args, **kwargs): 37 | """function to patch over fail_json; package return data into an exception""" 38 | kwargs['failed'] = True 39 | raise AnsibleFailJson(kwargs) 40 | 41 | 42 | class TestRubrikJobStatus(unittest.TestCase): 43 | 44 | def setUp(self): 45 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 46 | exit_json=exit_json, 47 | fail_json=fail_json) 48 | self.mock_module_helper.start() 49 | self.addCleanup(self.mock_module_helper.stop) 50 | 51 | def test_module_fail_when_required_args_missing(self): 52 | with self.assertRaises(AnsibleFailJson): 53 | set_module_args({}) 54 | rubrik_refresh_vcenter.main() 55 | 56 | def test_module_fail_with_invalid_wait_for_completion(self): 57 | 58 | vcenter_ip = "vcenter.example.com" 59 | wait_for_completion = "foo" 60 | 61 | set_module_args({ 62 | 'vcenter_ip': vcenter_ip, 63 | 'wait_for_completion': wait_for_completion, 64 | 'node_ip': '1.1.1.1', 65 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 66 | }) 67 | 68 | with self.assertRaises(AnsibleFailJson) as result: 69 | rubrik_refresh_vcenter.main() 70 | 71 | self.assertEqual(result.exception.args[0]['failed'], True) 72 | 73 | @patch.object(rubrik_refresh_vcenter.rubrik_cdm.rubrik_cdm.Cluster, 'refresh_vcenter', autospec=True, spec_set=True) 74 | def test_module_get_refresh_vcenter(self, mock_refresh): 75 | 76 | def mock_refresh_vcenter(): 77 | return { 78 | "endTime": "2020-04-07T00:30:28.448Z", 79 | "id": "REFRESH_METADATA_01234567-8910-1abc-d435-0abc1234d567_01234567-8910-1abc-d435-0abc1234d567:::0", 80 | "links": [ 81 | { 82 | "href": "https://rubrik/api/v1/vmware/vcenter/request/REFRESH_METADATA_01234567-8910-1abc-d435-0abc1234d567:::0", 83 | "rel": "self" 84 | } 85 | ], 86 | "nodeId": "cluster:::RVM111S000000", 87 | "startTime": "2020-04-07T00:29:50.585Z", 88 | "status": "SUCCEEDED" 89 | } 90 | 91 | set_module_args({ 92 | 'vcenter_ip': 'vcenter.example.com', 93 | 'wait_for_completion': True, 94 | 'node_ip': '1.1.1.1', 95 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 96 | }) 97 | 98 | mock_refresh.return_value = mock_refresh_vcenter() 99 | 100 | with self.assertRaises(AnsibleExitJson) as result: 101 | rubrik_refresh_vcenter.main() 102 | 103 | self.assertEqual(result.exception.args[0]['changed'], False) 104 | self.assertEqual(result.exception.args[0]['response'], mock_refresh_vcenter()) 105 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_post.md: -------------------------------------------------------------------------------- 1 | # rubrik_get 2 | 3 | Send a GET request to the provided Rubrik API endpoint. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_post: 11 | api_version: internal 12 | api_endpoint: "/managed_volume" 13 | config: {"name": "AnsibleDemo", "volumeSize": 10737418240} 14 | ``` 15 | 16 | # Arguments 17 | 18 | ## Common 19 | 20 | | Name | Description | Default | 21 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 22 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 27 | 28 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 29 | | --- | 30 | 31 | ## Module Specific 32 | 33 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 34 | |----------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 35 | | api_version | The version of the Rubrik CDM API to call. | | string | | true | | 36 | | api_endpoint | The endpoint of the Rubrik CDM API to call (ex. /cluster/me). | | string | | true | | 37 | | config | The specified data to send with the API call. | | raw | | false | | 38 | | authentication | Flag that specifies whether or not to utilize authentication when making the API call. | True | book | | false | | 39 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 30 | int | | false | | 40 | 41 | # Return Values 42 | 43 | | Name | Description | Returned | Type | 44 | |----------|------------------------------------|----------|------| 45 | | response | The response body of the API call. | success | dict | 46 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_get.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_get 16 | short_description: Send a GET request to the provided Rubrik API endpoint. 17 | description: 18 | - Send a GET request to the provided Rubrik API endpoint. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | api_version: 23 | description: 24 | - The version of the Rubrik CDM API to call. 25 | required: True 26 | type: str 27 | choices: [v1, v2, internal] 28 | api_endpoint: 29 | description: 30 | - The endpoint of the Rubrik CDM API to call (ex. /cluster/me). 31 | required: True 32 | type: str 33 | authentication: 34 | description: 35 | - Flag that specifies whether or not to utilize authentication when making the API call. 36 | required: False 37 | type: bool 38 | default: True 39 | params: 40 | description: 41 | - An optional dict containing variables in a key:value format to send with the call. 42 | required: False 43 | type: dict 44 | timeout: 45 | description: 46 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 47 | required: False 48 | type: int 49 | default: 30 50 | 51 | extends_documentation_fragment: rubrikinc.cdm.credentials 52 | requirements: [rubrik_cdm] 53 | ''' 54 | 55 | EXAMPLES = ''' 56 | - name: Retrieve summary information for the "Ansible" SLA Domain 57 | rubrik_get: 58 | api_version: v1 59 | api_endpoint: "/sla_domain" 60 | params: {"name": "Ansible"} 61 | 62 | - name: Retrieve summary information for the "Ansible" SLA Domain usingn params 63 | rubrik_get: 64 | api_version: v1 65 | api_endpoint: "/sla_domain?name=Ansible" 66 | ''' 67 | 68 | RETURN = ''' 69 | response: 70 | description: The response body of the API call.. 71 | returned: success 72 | type: str 73 | sample: {"acceptedEulaVersion": "1.1", "name": "DEVOPS-1"} 74 | ''' 75 | 76 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 77 | from ansible.module_utils.basic import AnsibleModule 78 | 79 | try: 80 | import rubrik_cdm 81 | HAS_RUBRIK_SDK = True 82 | except ImportError: 83 | HAS_RUBRIK_SDK = False 84 | 85 | 86 | def main(): 87 | """ Main entry point for Ansible module execution. 88 | """ 89 | 90 | results = {} 91 | 92 | argument_spec = dict( 93 | api_version=dict(required=True, type='str', choices=['v1', 'v2', 'internal']), 94 | api_endpoint=dict(required=True, type='str'), 95 | authentication=dict(required=False, type='bool', default=True), 96 | params=dict(required=False, type='dict'), 97 | timeout=dict(required=False, type='int', default=30), 98 | ) 99 | 100 | argument_spec.update(rubrik_argument_spec) 101 | 102 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 103 | 104 | ansible = module.params 105 | 106 | load_provider_variables(module) 107 | 108 | if not HAS_RUBRIK_SDK: 109 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 110 | 111 | node_ip, username, password, api_token = credentials(module) 112 | 113 | try: 114 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token, enable_logging=True) 115 | except Exception as error: 116 | module.fail_json(msg=str(error)) 117 | 118 | try: 119 | api_request = rubrik.get(ansible["api_version"], ansible["api_endpoint"], ansible["timeout"], ansible["authentication"], ansible["params"]) 120 | except Exception as error: 121 | module.fail_json(msg=str(error)) 122 | 123 | results["response"] = api_request 124 | 125 | module.exit_json(**results) 126 | 127 | 128 | if __name__ == '__main__': 129 | main() 130 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_get.md: -------------------------------------------------------------------------------- 1 | # rubrik_get 2 | 3 | Send a GET request to the provided Rubrik API endpoint. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_get: 11 | api_version: v1 12 | api_endpoint: "/sla_domain" 13 | params: {"name": "Ansible"} 14 | ``` 15 | 16 | ```yaml 17 | - rubrik_get: 18 | api_version: v1 19 | api_endpoint: "/sla_domain?name=Ansible" 20 | ``` 21 | 22 | 23 | # Arguments 24 | 25 | ## Common 26 | 27 | | Name | Description | Default | 28 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 29 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 30 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 31 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 32 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 33 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 34 | 35 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 36 | | --- | 37 | 38 | ## Module Specific 39 | 40 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 41 | |----------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 42 | | api_version | The version of the Rubrik CDM API to call. | | string | | true | | 43 | | api_endpoint | The endpoint of the Rubrik CDM API to call (ex. /cluster/me). | | string | | true | | 44 | | params | An optional dict containing variables in a key:value format to send with the call. | | dict | | false | | 45 | | authentication | Flag that specifies whether or not to utilize authentication when making the API call. | True | book | | false | | 46 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 30 | int | | false | | 47 | 48 | # Return Values 49 | 50 | | Name | Description | Returned | Type | 51 | |----------|------------------------------------|----------|------| 52 | | response | The response body of the API call. | success | dict | 53 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_job_status.md: -------------------------------------------------------------------------------- 1 | # rubrik_job_status 2 | 3 | Certain Rubrik operations may not instantaneously complete. In those cases we have the ability to monitor the status of the job through a job status link provided in the actions API response body. In those cases the Ansible Module will return a "job_status_link" which can then be registered and used as a variable in the rubrik_job_status module. The rubrik_job_status will check on the status of the job every 20 seconds until the job has successfully completed for failed. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_on_demand_snapshot: 11 | object_name: "{{ vm_name }}" 12 | register: snapshot 13 | 14 | - rubrik_job_status: 15 | url: "{{ snapshot.job_status_url }}" 16 | ``` 17 | 18 | # Arugments 19 | 20 | ## Common 21 | 22 | | Name | Description | Default | 23 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 24 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 27 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 28 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 29 | 30 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 31 | | --- | 32 | 33 | ## Module Specific 34 | 35 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 36 | |---------------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 37 | | url | The job status URL provided by a previous API call. | | string | | true | | 38 | | wait_for_completion | Flag that determines if the method should wait for the job to complete before exiting. | true | bool | | | | 39 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 40 | 41 | # Return Values 42 | 43 | | Name | Description | Returned | Type | 44 | |----------|-----------------------------------------|----------|------| 45 | | response | The full API response for the API call. | success | dict | 46 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_add_organization_protectable_object_sql_server_availability_group.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_add_organization_protectable_object_sql_server_availability_group 15 | short_description: Add a MSSQL Availability Group to an organization as a protectable object. 16 | description: 17 | - Add a MSSQL Availability Group to an organization as a protectable object. 18 | version_added: '2.9' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | organization_name: 22 | description: 23 | - The name of the organization you wish to add the protectable object to. 24 | required: True 25 | type: str 26 | mssql_availability_group: 27 | description: 28 | - The name of the MSSQL Availability Group to add to the organization as a protectable object. 29 | required: True 30 | type: str 31 | timeout: 32 | description: 33 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 34 | required: False 35 | type: int 36 | default: 15 37 | 38 | extends_documentation_fragment: rubrikinc.cdm.credentials 39 | requirements: [rubrik_cdm] 40 | ''' 41 | 42 | EXAMPLES = ''' 43 | - rubrik_add_organization_protectable_object_sql_server_availability_group: 44 | organization_name: "Ansible" 45 | mssql_availability_group: "demo-ag" 46 | ''' 47 | 48 | 49 | RETURN = ''' 50 | full_response: 51 | description: 52 | - The full API response for `POST /internal/role/{}/authorization`. 53 | returned: on success 54 | type: dict 55 | 56 | idempotent_response: 57 | description: A "No changed required" message when the MSSQL host has already been added to the organization. 58 | returned: When the module idempotent check is succesful. 59 | type: str 60 | sample: No change required. The MSSQL Availability Group `mssql_availability_group` is already assigned to the `organization_name` organization. 61 | ''' 62 | 63 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 64 | from ansible.module_utils.basic import AnsibleModule 65 | 66 | try: 67 | import rubrik_cdm 68 | HAS_RUBRIK_SDK = True 69 | except ImportError: 70 | HAS_RUBRIK_SDK = False 71 | 72 | 73 | def main(): 74 | """ Main entry point for Ansible module execution. 75 | """ 76 | 77 | results = {} 78 | 79 | argument_spec = dict( 80 | organization_name=dict(required=True, type='str'), 81 | mssql_availability_group=dict(required=True, type='str'), 82 | timeout=dict(required=False, type='int', default=15), 83 | ) 84 | 85 | argument_spec.update(rubrik_argument_spec) 86 | 87 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 88 | 89 | ansible = module.params 90 | 91 | organization_name = ansible["organization_name"] 92 | mssql_availability_group = ansible["mssql_availability_group"] 93 | timeout = ansible["timeout"] 94 | 95 | load_provider_variables(module) 96 | 97 | if not HAS_RUBRIK_SDK: 98 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 99 | 100 | node_ip, username, password, api_token = credentials(module) 101 | 102 | try: 103 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 104 | except Exception as error: 105 | module.fail_json(msg=str(error)) 106 | 107 | try: 108 | api_request = rubrik.add_organization_protectable_object_sql_server_availability_group(organization_name, mssql_availability_group, timeout) 109 | except Exception as error: 110 | module.fail_json(msg=str(error)) 111 | 112 | if "No change required" in api_request: 113 | results["changed"] = False 114 | else: 115 | results["changed"] = True 116 | 117 | results["response"] = api_request 118 | 119 | module.exit_json(**results) 120 | 121 | 122 | if __name__ == '__main__': 123 | main() 124 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_vsphere_live_unmount.md: -------------------------------------------------------------------------------- 1 | # rubrik_vsphere_live_unmount 2 | 3 | Delete a vSphere Live Mount from the Rubrik cluster. 4 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 5 | 6 | # Example 7 | 8 | ```yaml 9 | - rubrik_vsphere_live_unmount: 10 | mounted_vm_name: 'ansible-tower' 11 | ``` 12 | 13 | ```yaml 14 | - rubrik_vsphere_live_unmount: 15 | mounted_vm_name: 'ansible-tower' 16 | force: True 17 | ``` 18 | 19 | # Arugments 20 | 21 | ## Common 22 | 23 | | Name | Description | Default | 24 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 25 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 27 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 28 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 29 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 30 | 31 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 32 | | --- | 33 | 34 | ## Module Specific 35 | 36 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 37 | |------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 38 | | mounted_vm_name | The name of the Live Mounted vSphere VM to be unmounted. | | str | | true | | 39 | | force | Force unmount to remove metadata when the datastore of the Live Mount virtual machine was moved off of the Rubrik cluster. | false | bool | | | | 40 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 41 | 42 | # Return Values 43 | 44 | | Name | Description | Returned | Type | Aliases | 45 | |----------|----------------------------------------------------------------------------|----------|------|---------| 46 | | response | The full response of `DELETE /vmware/vm/snapshot/mount/{id}?force={bool}`. | success | dict | | 47 | -------------------------------------------------------------------------------- /rubrikinc/cdm/tests/unit/test_rubrik_job_status.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | import json 5 | import unittest 6 | from unittest.mock import Mock, patch 7 | from ansible.module_utils import basic 8 | from ansible.module_utils._text import to_bytes 9 | from rubrik_cdm.exceptions import RubrikException, APICallException 10 | import ansible_collections.rubrikinc.cdm.plugins.modules.rubrik_job_status as rubrik_job_status 11 | 12 | 13 | def set_module_args(args): 14 | """prepare arguments so that they will be picked up during module creation""" 15 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 16 | basic._ANSIBLE_ARGS = to_bytes(args) 17 | 18 | 19 | class AnsibleExitJson(Exception): 20 | """Exception class to be raised by module.exit_json and caught by the test case""" 21 | pass 22 | 23 | 24 | class AnsibleFailJson(Exception): 25 | """Exception class to be raised by module.fail_json and caught by the test case""" 26 | pass 27 | 28 | 29 | def exit_json(*args, **kwargs): 30 | """function to patch over exit_json; package return data into an exception""" 31 | if 'changed' not in kwargs: 32 | kwargs['changed'] = False 33 | raise AnsibleExitJson(kwargs) 34 | 35 | 36 | def fail_json(*args, **kwargs): 37 | """function to patch over fail_json; package return data into an exception""" 38 | kwargs['failed'] = True 39 | raise AnsibleFailJson(kwargs) 40 | 41 | 42 | class TestRubrikJobStatus(unittest.TestCase): 43 | 44 | def setUp(self): 45 | self.mock_module_helper = patch.multiple(basic.AnsibleModule, 46 | exit_json=exit_json, 47 | fail_json=fail_json) 48 | self.mock_module_helper.start() 49 | self.addCleanup(self.mock_module_helper.stop) 50 | 51 | def test_module_fail_when_required_args_missing(self): 52 | with self.assertRaises(AnsibleFailJson): 53 | set_module_args({}) 54 | rubrik_job_status.main() 55 | 56 | def test_module_fail_with_invalid_wait_for_completion(self): 57 | 58 | url = "https://1.1.1.1/api/v1/vmware/vm/request/" 59 | job_id = "CREATE_VMWARE_SNAPSHOT_fbcb1d87-9872-4227-a68c-5982f48-vm-289386_e837-a04c-4327-915b-7698d2c5ecf48:::0" 60 | 61 | full_url = url + job_id 62 | 63 | set_module_args({ 64 | 'url': full_url, 65 | 'node_ip': '1.1.1.1', 66 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 67 | }) 68 | 69 | with self.assertRaises(AnsibleFailJson) as result: 70 | rubrik_job_status.main() 71 | 72 | self.assertEqual(result.exception.args[0]['failed'], True) 73 | 74 | @patch.object(rubrik_job_status.rubrik_cdm.rubrik_cdm.Connect, '_common_api', autospec=True, spec_set=True) 75 | def test_module_get_job_status(self, mock_common_api): 76 | 77 | def mock_job_status(): 78 | return { 79 | "id": "CREATE_VMWARE_SNAPSHOT_fbcb1d87-9872-4227-a68c-5982f48-vm-289386_e837-a04c-4327-915b-7698d2c5ecf48:::0", 80 | "status": "SUCCEEDED", 81 | "startTime": "2019-04-17T21:31:17.785Z", 82 | "endTime": "2019-04-17T21:31:39.056Z", 83 | "nodeId": "cluster:::RVM189S019012", 84 | "links": [ 85 | { 86 | "href": "CREATE_VMWARE_SNAPSHOT_fbcb1d87-9872-4227-a68c-5982f48-vm-289386_e837-a04c-4327-915b-7698d2c5ecf48:::0", 87 | "rel": "self" 88 | } 89 | ] 90 | } 91 | 92 | url = "https://1.1.1.1/api/v1/vmware/vm/request/" 93 | job_id = "CREATE_VMWARE_SNAPSHOT_fbcb1d87-9872-4227-a68c-5982f48-vm-289386_e837-a04c-4327-915b-7698d2c5ecf48:::0" 94 | 95 | full_url = url + job_id 96 | 97 | set_module_args({ 98 | 'url': full_url, 99 | 'node_ip': '1.1.1.1', 100 | 'api_token': 'vkys219gn2jziReqdPJH0asGM3PKEQHP' 101 | }) 102 | 103 | mock_common_api.return_value = mock_job_status() 104 | 105 | with self.assertRaises(AnsibleExitJson) as result: 106 | rubrik_job_status.main() 107 | 108 | self.assertEqual(result.exception.args[0]['changed'], False) 109 | self.assertEqual(result.exception.args[0]['response'], mock_job_status()) 110 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_add_organization_protectable_object_mssql_server_host.md: -------------------------------------------------------------------------------- 1 | # rubrik_add_organization_protectable_object_mssql_server_host 2 | 3 | Add a MSSQL Server Host to an organization as a protectable object. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_add_organization_protectable_object_mssql_server_host: 11 | organization_name: "Ansible" 12 | mssql_host: "demo-sql-host" 13 | ``` 14 | 15 | # Arguments 16 | 17 | ## Common 18 | 19 | | Name | Description | Default | 20 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 21 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 26 | 27 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 28 | | --- | 29 | 30 | ## Module Specific 31 | 32 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 33 | |-------------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 34 | | organization_name | The name of the organization you wish to add the protectable object to. | | string | | true | | 35 | | mssql_host | The name of the MSSQL Host to add to the organization as a protectable object. | | string | | true | | 36 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 37 | 38 | # Return Values 39 | 40 | | Name | Description | Returned | Type | 41 | |----------|-------------------------------------------------------------------------------------------------|------------------------------------------------|--------| 42 | | response | The full API response for `POST /internal/role/{}/authorization`. | success | dict | 43 | | response | A "No changed required" message when the MSSQL host has already been added to the organization. | When the module idempotent check is succesful. | string | 44 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_sql_live_unmount.md: -------------------------------------------------------------------------------- 1 | # rubrik_sql_live_unmount 2 | 3 | Delete a Microsoft SQL Live Mount from the Rubrik cluster. 4 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 5 | 6 | # Example 7 | 8 | ```yaml 9 | - rubrik_sql_live_unmount: 10 | mounted_db_name: 'AdventureWorksClone' 11 | sql_instance: 'MSSQLSERVER' 12 | sql_host: 'sql.rubrikdemo.com' 13 | ``` 14 | 15 | # Arugments 16 | 17 | ## Common 18 | 19 | | Name | Description | Default | 20 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 21 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 26 | 27 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 28 | | --- | 29 | 30 | ## Module Specific 31 | 32 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 33 | |-----------------|---------------------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 34 | | mounted_db_name | The name of the Live Mounted database to be unmounted. | | str | | true | | 35 | | sql_instance | The SQL instance name with the database you wish to Live Mount. | None | str | | true | | 36 | | sql_host | The name of the MSSQL host running the Live Mounted database to be unmounted. | None | str | | true | | 37 | | force | Remove all data within the Rubrik cluster related to the Live Mount, even if the SQL Server database cannot be contacted. | false | bool | | false | | 38 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 30 | int | | false | | 39 | 40 | # Return Values 41 | 42 | | Name | Description | Returned | Type | Aliases | 43 | |----------|------------------------------------------------------------------|----------|------|---------| 44 | | response | The full response of `DELETE /mssql/db/mount/{id}?force={bool}`. | success | dict | | 45 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_end_user_authorization.md: -------------------------------------------------------------------------------- 1 | # rubrik_end_user_authorization 2 | 3 | Grant an End User authorization to the provided object. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_end_user_authorization: 11 | object_name: "ansible-tower" 12 | end_user: "ansible-user" 13 | ``` 14 | 15 | # Arugments 16 | 17 | ## Common 18 | 19 | | Name | Description | Default | 20 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 21 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 26 | 27 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 28 | | --- | 29 | 30 | ## Module Specific 31 | 32 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 33 | |-------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 34 | | end_user | The name of the end user you wish to grant authorization to. | | string | | true | | 35 | | object_name | The name of the object you wish to grant the `end_user' authorization to. | | string | | true | | 36 | | object_type | The Rubrik object type you wish to grant authorization to. | vmware | string | vmware | | | 37 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 38 | 39 | # Return Values 40 | 41 | | Name | Description | Returned | Type | 42 | |----------|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------|-------| 43 | | response | The full API response for POST /internal/authorization/role/end_user | success | dict | 44 | | response | A "No changed required" message when the end user is already authorized to interface with provided I(objec_name). | When the module idempotent check is succesful. | sring | 45 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_add_organization_protectable_object_sql_server_availability_group.md: -------------------------------------------------------------------------------- 1 | # rubrik_add_organization_protectable_object_sql_server_availability_group 2 | 3 | Add a MSSQL Availability Group to an organization as a protectable object. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_add_organization_protectable_object_sql_server_availability_group: 11 | organization_name: "Ansible" 12 | mssql_availability_group: "demo-ag" 13 | ``` 14 | 15 | # Arguments 16 | 17 | ## Common 18 | 19 | | Name | Description | Default | 20 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 21 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 22 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 26 | 27 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 28 | | --- | 29 | 30 | ## Module Specific 31 | 32 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 33 | |--------------------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 34 | | organization_name | The name of the organization you wish to add the protectable object to. | | string | | true | | 35 | | mssql_availability_group | The name of the MSSQL Availability Group to add to the organization as a protectable object. | | string | | true | | 36 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 37 | 38 | # Return Values 39 | 40 | | Name | Description | Returned | Type | 41 | |----------|---------------------------------------------------------------------------------------------------------------|------------------------------------------------|--------| 42 | | response | The full API response for `POST /internal/role/{}/authorization`. | success | dict | 43 | | response | A "No changed required" message when the MSSQL Availability Group has already been added to the organization. | When the module idempotent check is succesful. | string | 44 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_sql_live_mount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or 4 | # https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import absolute_import, division, print_function 6 | __metaclass__ = type 7 | 8 | ANSIBLE_METADATA = { 9 | 'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community' 12 | } 13 | 14 | DOCUMENTATION = ''' 15 | module: rubrik_sql_live_mount 16 | short_description: Live Mount a mssql database from a specified recovery point i.e. data and time. 17 | description: 18 | - Live Mount a mssql database from a specified recovery point i.e. data and time. 19 | version_added: '2.8' 20 | author: Rubrik Build Team (@drew-russell) 21 | options: 22 | db_name: 23 | description: 24 | - The name of the database to Live Mount. 25 | required: True 26 | type: str 27 | date: 28 | description: 29 | - The recovery_point date you wish to Live Mount formated as Month-Day-Year (ex. 1-15-2014). 30 | required: True 31 | type: str 32 | time: 33 | description: 34 | - The recovery_point time you wish to Live Mount formated as Hour:Minute AM/PM (ex. 1:30 AM). 35 | required: True 36 | type: str 37 | sql_instance: 38 | description: 39 | - The SQL instance name with the database you wish to Live Mount. 40 | required: True 41 | type: str 42 | sql_host: 43 | description: 44 | - The SQL Host of the database/instance to Live Mount. 45 | required: True 46 | type: str 47 | mount_name: 48 | description: 49 | - The name given to the Live Mounted database i.e. AdventureWorks_Clone. 50 | required: True 51 | type: str 52 | timeout: 53 | description: 54 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 55 | required: False 56 | type: int 57 | default: 30 58 | 59 | extends_documentation_fragment: 60 | - rubrikinc.cdm.credentials 61 | requirements: [rubrik_cdm] 62 | ''' 63 | 64 | 65 | EXAMPLES = ''' 66 | - rubrik_sql_live_mount: 67 | db_name: 'AdventureWorks2016' 68 | date: '08-26-2018' 69 | time: '12:11 AM' 70 | sql_instance: 'MSSQLSERVER' 71 | sql_host: 'sql.rubrikdemo.com' 72 | mount_name: 'AdventureWorksClone' 73 | ''' 74 | 75 | 76 | RETURN = ''' 77 | full_response: 78 | description: The full response of `POST /v1/mssql/db/{id}/mount`. 79 | returned: success 80 | type: dict 81 | ''' 82 | 83 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 84 | from ansible.module_utils.basic import AnsibleModule 85 | 86 | try: 87 | import rubrik_cdm 88 | HAS_RUBRIK_SDK = True 89 | except ImportError: 90 | HAS_RUBRIK_SDK = False 91 | 92 | 93 | def main(): 94 | """ Main entry point for Ansible module execution. 95 | """ 96 | 97 | results = {} 98 | 99 | argument_spec = dict( 100 | db_name=dict(required=True, type='str'), 101 | date=dict(required=True, type='str'), 102 | time=dict(required=True, type='str'), 103 | sql_instance=dict(required=True, type='str'), 104 | sql_host=dict(required=True, type='str'), 105 | mount_name=dict(required=True, type='str'), 106 | timeout=dict(required=False, type='int', default=30), 107 | 108 | ) 109 | 110 | argument_spec.update(rubrik_argument_spec) 111 | 112 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 113 | 114 | ansible = module.params 115 | 116 | load_provider_variables(module) 117 | 118 | if not HAS_RUBRIK_SDK: 119 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 120 | 121 | node_ip, username, password, api_token = credentials(module) 122 | 123 | try: 124 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 125 | except Exception as error: 126 | module.fail_json(msg=str(error)) 127 | 128 | try: 129 | api_request = rubrik.sql_live_mount( 130 | ansible["db_name"], 131 | ansible["date"], 132 | ansible["time"], 133 | ansible["sql_instance"], 134 | ansible["sql_host"], 135 | ansible["mount_name"], 136 | ansible["timeout"]) 137 | except Exception as error: 138 | module.fail_json(msg=str(error)) 139 | 140 | results["response"] = api_request 141 | 142 | module.exit_json(**results) 143 | 144 | 145 | if __name__ == '__main__': 146 | main() 147 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/template.md: -------------------------------------------------------------------------------- 1 | # rubrik_cluster_version 2 | 3 | Retrieves the software version of the Rubrik cluster. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_cluster_version: 11 | 12 | - rubrik_cluster_version: 13 | provider: "{{ credentials }}" 14 | ``` 15 | 16 | # Arugments 17 | 18 | ## Common 19 | 20 | | Name | Description | Default | 21 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 22 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 23 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 27 | 28 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 29 | | --- | 30 | 31 | 32 | ## Module Specific 33 | 34 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 35 | |---------|--------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 36 | | | | | | | | | 37 | | | | | | | | | 38 | | | | | | | | | 39 | | | | | | | | | 40 | | | | | | | | | 41 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 30 | int | | | | 42 | 43 | # Return Values 44 | 45 | | Name | Description | Returned | Type | 46 | |----------|-------------|------------------------------------------------|--------| 47 | | response | | success | dict | 48 | | response | | When the module idempotent check is succesful. | string | 49 | | | | | | 50 | | | | | | 51 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_add_organization_protectable_object_sql_server_db.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_add_organization_protectable_object_sql_server_db 15 | short_description: Add a MSSQL DB to an organization as a protectable object. 16 | description: 17 | - Add a MSSQL DB to an organization as a protectable object. 18 | version_added: '2.9' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | organization_name: 22 | description: 23 | - The name of the organization you wish to add the protectable object to. 24 | required: True 25 | type: str 26 | mssql_db: 27 | description: 28 | - The name of the MSSQL DB to add to the organization as a protectable object. 29 | required: True 30 | type: str 31 | mssql_instance: 32 | description: 33 | - The name of the MSSQL instance where the MSSQL DB lives. 34 | required: True 35 | type: str 36 | mssql_host: 37 | description: 38 | - The name of the MSSQL host where the MSSQL DB lives. 39 | required: True 40 | type: str 41 | timeout: 42 | description: 43 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 44 | required: False 45 | type: int 46 | default: 15 47 | 48 | extends_documentation_fragment: rubrikinc.cdm.credentials 49 | requirements: [rubrik_cdm] 50 | ''' 51 | 52 | EXAMPLES = ''' 53 | - rubrik_add_organization_protectable_object_sql_server_db: 54 | organization_name: "Ansible" 55 | mssql_db: "DemoDB" 56 | mssql_instance: "dmeo-sql-instance" 57 | mssql_host: "demo-sql-host" 58 | ''' 59 | 60 | 61 | RETURN = ''' 62 | full_response: 63 | description: 64 | - The full API response for `POST /internal/role/{}/authorization`. 65 | returned: on success 66 | type: dict 67 | 68 | idempotent_response: 69 | description: A "No changed required" message when the MSSQL DB has already been added to the organization. 70 | returned: When the module idempotent check is succesful. 71 | type: str 72 | sample: No change required. The MSSQL DB `mssql_db` is already assigned to the `organization_name` organization. 73 | ''' 74 | 75 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 76 | from ansible.module_utils.basic import AnsibleModule 77 | 78 | try: 79 | import rubrik_cdm 80 | HAS_RUBRIK_SDK = True 81 | except ImportError: 82 | HAS_RUBRIK_SDK = False 83 | 84 | 85 | def main(): 86 | """ Main entry point for Ansible module execution. 87 | """ 88 | 89 | results = {} 90 | 91 | argument_spec = dict( 92 | organization_name=dict(required=True, type='str'), 93 | mssql_db=dict(required=True, type='str'), 94 | mssql_host=dict(required=True, type='str'), 95 | mssql_instance=dict(required=True, type='str'), 96 | timeout=dict(required=False, type='int', default=15), 97 | ) 98 | 99 | argument_spec.update(rubrik_argument_spec) 100 | 101 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 102 | 103 | ansible = module.params 104 | 105 | organization_name = ansible["organization_name"] 106 | mssql_db = ansible["mssql_db"] 107 | mssql_host = ansible["mssql_host"] 108 | mssql_instance = ansible["mssql_instance"] 109 | timeout = ansible["timeout"] 110 | 111 | load_provider_variables(module) 112 | 113 | if not HAS_RUBRIK_SDK: 114 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 115 | 116 | node_ip, username, password, api_token = credentials(module) 117 | 118 | try: 119 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 120 | except Exception as error: 121 | module.fail_json(msg=str(error)) 122 | 123 | try: 124 | api_request = rubrik.add_organization_protectable_object_sql_server_db(organization_name, mssql_db, mssql_host, mssql_instance, timeout) 125 | except Exception as error: 126 | module.fail_json(msg=str(error)) 127 | 128 | if "No change required" in api_request: 129 | results["changed"] = False 130 | else: 131 | results["changed"] = True 132 | 133 | results["response"] = api_request 134 | 135 | module.exit_json(**results) 136 | 137 | 138 | if __name__ == '__main__': 139 | main() 140 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_add_organization_protectable_object_sql_server_db.md: -------------------------------------------------------------------------------- 1 | # rubrik_add_organization_protectable_object_sql_server_db 2 | 3 | Add a MSSQL DB to an organization as a protectable object. 4 | 5 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 6 | 7 | # Example 8 | 9 | ```yaml 10 | - rubrik_add_organization_protectable_object_sql_server_db: 11 | organization_name: "Ansible" 12 | mssql_db: "DemoDB" 13 | mssql_instance: "dmeo-sql-instance" 14 | mssql_host: "demo-sql-host" 15 | ``` 16 | 17 | # Arguments 18 | 19 | ## Common 20 | 21 | | Name | Description | Default | 22 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 23 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 24 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 27 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 28 | 29 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 30 | | --- | 31 | 32 | ## Module Specific 33 | 34 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 35 | |-------------------|--------------------------------------------------------------------------------------------------------------|---------|--------|---------|-----------|---------| 36 | | organization_name | The name of the organization you wish to add the protectable object to. | | string | | true | | 37 | | mssql_db | The name of the MSSQL DB to add to the organization as a protectable object. | | string | | true | | 38 | | mssql_instance | The name of the MSSQL instance where the MSSQL DB lives. | | string | | true | | 39 | | mssql_host | The name of the MSSQL host where the MSSQL DB lives. | | string | | true | | 40 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 15 | int | | | | 41 | 42 | # Return Values 43 | 44 | | Name | Description | Returned | Type | 45 | |----------|-----------------------------------------------------------------------------------------------|------------------------------------------------|--------| 46 | | response | The full API response for `POST /internal/role/{}/authorization`. | success | dict | 47 | | response | A "No changed required" message when the MSSQL DB has already been added to the organization. | When the module idempotent check is succesful. | string | 48 | -------------------------------------------------------------------------------- /rubrikinc/cdm/docs/rubrik_sql_live_mount.md: -------------------------------------------------------------------------------- 1 | # rubrik_sql_live_mount 2 | 3 | Live Mount a mssql database from a specified recovery point i.e. data and time. 4 | `Requirement: Rubrik Python SDK (pip install rubrik_cdm)` 5 | 6 | # Example 7 | 8 | ```yaml 9 | - rubrik_sql_live_mount: 10 | db_name: 'AdventureWorks2016' 11 | date: '08-26-2018' 12 | time: '12:11 AM' 13 | sql_instance: 'MSSQLSERVER' 14 | sql_host: 'sql.rubrikdemo.com' 15 | mount_name: 'AdventureWorksClone' 16 | ``` 17 | 18 | # Arugments 19 | 20 | ## Common 21 | 22 | | Name | Description | Default | 23 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| 24 | | node_ip | The DNS hostname or IP address of the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_node_ip environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 25 | | password | The password used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_password environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 26 | | username | The username used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_username environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 27 | | api_token | The api token used to authenticate the connection to the Rubrik cluster. By defeault, the module will attempt to read this value from the rubrik_cdm_token environment variable. If this environment variable is not present it will need to be manually specified here or in the `provider' parameter. | | 28 | | provider | Convenience method that allows all connection arguments (`node_ip', `username', `password') to be passed as a dict object. By default, the module will attempt to read these parameters from the rubrik_cdm_node_ip, rubrik_cdm_username, and rubrik_cdm_password environment variables. | | 29 | 30 | | Note: The `username` and `password` must be supplied together and may not be provided if the `api_token` variable is present| 31 | | --- | 32 | 33 | ## Module Specific 34 | 35 | | Name | Description | Default | Type | Choices | Mandatory | Aliases | 36 | |------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------|---------|-----------|---------| 37 | | db_name | The name of the database to Live Mount. | | str | | true | | 38 | | date | The recovery_point date you wish to Live Mount formated as `Month-Day-Year` (ex: 1-15-2014). | | str | |true| | 39 | | time | The recovery_point time you wish to Live Mount formated as `Hour:Minute AM/PM` (ex: 1:30 AM). | | str | |true| | 40 | | sql_instance | The SQL instance name with the database you wish to Live Mount. | None | str | |true| | 41 | | sql_host | The SQL Host of the database/instance to Live Mount. | None | str | |true| | 42 | | mount_name | The name given to the Live Mounted database i.e. AdventureWorksClone. | None | str | |true| | 43 | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | 30 | int | |false| | 44 | 45 | # Return Values 46 | 47 | | Name | Description | Returned | Type | Aliases | 48 | |----------|----------------------------------------------------------------------------|----------|------|---------| 49 | | response | The full response of `POST /v1/mssql/db/{id}/mount`. | success | dict | | 50 | -------------------------------------------------------------------------------- /rubrikinc/cdm/plugins/modules/rubrik_end_user_authorization.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # (c) 2018 Rubrik, Inc 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | from __future__ import absolute_import, division, print_function 5 | __metaclass__ = type 6 | 7 | ANSIBLE_METADATA = { 8 | 'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community' 11 | } 12 | 13 | DOCUMENTATION = ''' 14 | module: rubrik_end_user_authorization 15 | short_description: Grant an Rubrik End User authorization to the provided object. 16 | description: 17 | - Grant an End User authorization to the provided object. 18 | version_added: '2.8' 19 | author: Rubrik Build Team (@drew-russell) 20 | options: 21 | object_name: 22 | description: 23 | - The name of the object you wish to grant the I(end_user) authorization to. 24 | required: True 25 | type: str 26 | end_user: 27 | description: 28 | - The name of the end user you wish to grant authorization to. 29 | required: True 30 | type: str 31 | object_type: 32 | description: 33 | - The Rubrik object type you wish to grant authorization to. 34 | required: False 35 | type: str 36 | default: vmware 37 | choices: [vmware] 38 | timeout: 39 | description: 40 | - The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. 41 | required: False 42 | type: int 43 | default: 15 44 | 45 | 46 | extends_documentation_fragment: rubrikinc.cdm.credentials 47 | requirements: [rubrik_cdm] 48 | ''' 49 | 50 | 51 | EXAMPLES = ''' 52 | - rubrik_end_user_authorization: 53 | object_name: "ansible-tower" 54 | end_user: "ansible-user" 55 | ''' 56 | 57 | RETURN = ''' 58 | full_response: 59 | description: The full API response for POST /internal/authorization/role/end_user 60 | returned: on success 61 | type: dict 62 | sample: 63 | { 64 | "hasMore": true, 65 | "data": [ 66 | { 67 | "principal": "string", 68 | "privileges": { 69 | "destructiveRestore": [ 70 | "string" 71 | ], 72 | "restore": [ 73 | "string" 74 | ], 75 | "provisionOnInfra": [ 76 | "string" 77 | ] 78 | }, 79 | "organizationId": "string" 80 | } 81 | ], 82 | "total": 0 83 | } 84 | 85 | idempotent_response: 86 | description: A "No changed required" message when the end user is already authorized to interface with provided I(objec_name). 87 | returned: When the module idempotent check is succesful. 88 | type: str 89 | sample: No change required. The End User "end_user" is already authorized to interact with the "object_name" VM. 90 | ''' 91 | 92 | from ansible.module_utils.rubrik_cdm import credentials, load_provider_variables, rubrik_argument_spec 93 | from ansible.module_utils.basic import AnsibleModule 94 | 95 | try: 96 | import rubrik_cdm 97 | HAS_RUBRIK_SDK = True 98 | except ImportError: 99 | HAS_RUBRIK_SDK = False 100 | 101 | 102 | def main(): 103 | """ Main entry point for Ansible module execution. 104 | """ 105 | 106 | results = {} 107 | 108 | argument_spec = dict( 109 | object_name=dict(required=True, type='str'), 110 | end_user=dict(required=True, type='str'), 111 | object_type=dict(required=False, type='str', default="vmware", choices=['vmware']), 112 | timeout=dict(required=False, type='int', default=15), 113 | 114 | ) 115 | 116 | argument_spec.update(rubrik_argument_spec) 117 | 118 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) 119 | 120 | ansible = module.params 121 | 122 | load_provider_variables(module) 123 | 124 | if not HAS_RUBRIK_SDK: 125 | module.fail_json(msg='The Rubrik Python SDK is required for this module (pip install rubrik_cdm).') 126 | 127 | node_ip, username, password, api_token = credentials(module) 128 | 129 | try: 130 | rubrik = rubrik_cdm.Connect(node_ip, username, password, api_token) 131 | except Exception as error: 132 | module.fail_json(msg=str(error)) 133 | 134 | object_name = ansible["object_name"] 135 | end_user = ansible["end_user"] 136 | object_type = ansible["object_type"] 137 | timeout = ansible["timeout"] 138 | 139 | try: 140 | api_request = rubrik.end_user_authorization(object_name, end_user, object_type, timeout) 141 | except Exception as error: 142 | module.fail_json(msg=str(error)) 143 | 144 | if "No change required" in api_request: 145 | results["changed"] = False 146 | else: 147 | results["changed"] = True 148 | 149 | results["response"] = api_request 150 | 151 | module.exit_json(**results) 152 | 153 | 154 | if __name__ == '__main__': 155 | main() 156 | --------------------------------------------------------------------------------