├── .ansible-lint ├── .devcontainer └── devcontainer.json ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── documentation_report.yml │ └── feature_request.yml ├── dependabot.yml └── workflows │ ├── ansible-test-integration.yml │ ├── ansible-test-sanity.yml │ ├── ansible-test-unit.yml │ ├── ansible-test.yml │ ├── extra-docs-linting.yml │ ├── lint.yml │ ├── psf-black.yml │ ├── publish-galaxy.yml │ ├── pull-request-integration.yml │ ├── pull-request-sanity.yml │ └── pull-request-units.yml ├── .gitignore ├── .markdownlint.yaml ├── .pre-commit-config.yaml ├── .tool-versions ├── .vscode └── extensions.json ├── CHANGELOG.rst ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── GPL-3.0 ├── LICENSE ├── MAINTAINERS ├── MAINTAINING.md ├── Makefile ├── README.md ├── REVIEW_CHECKLIST.md ├── changelogs ├── changelog.yaml ├── config.yaml └── fragments │ └── .gitkeep ├── codecov.yml ├── do+a.png ├── docs └── docsite │ └── links.yml ├── galaxy.yml ├── inventory └── digitalocean.yml ├── meta └── runtime.yml ├── playbooks ├── account_info.yml ├── balance_info.yml ├── billing_history_info.yml ├── cdn_endpoints_info.yml └── droplet.yml ├── plugins ├── doc_fragments │ └── common.py ├── inventory │ └── droplets.py ├── module_utils │ ├── common.py │ ├── droplet_resize.py │ └── spaces.py └── modules │ ├── account_info.py │ ├── balance_info.py │ ├── billing_history_info.py │ ├── cdn_endpoints.py │ ├── cdn_endpoints_info.py │ ├── certificate.py │ ├── certificates_info.py │ ├── container_registry_info.py │ ├── database_cluster.py │ ├── database_clusters_info.py │ ├── domain.py │ ├── domain_record.py │ ├── domain_records_info.py │ ├── domains_info.py │ ├── droplet.py │ ├── droplet_action_power.py │ ├── droplet_action_resize.py │ ├── droplet_action_snapshot.py │ ├── droplets_info.py │ ├── firewall.py │ ├── firewalls_info.py │ ├── images_info.py │ ├── kubernetes_cluster.py │ ├── kubernetes_clusters_info.py │ ├── load_balancer.py │ ├── load_balancers_info.py │ ├── monitoring_alert_policies_info.py │ ├── monitoring_alert_policy.py │ ├── one_click.py │ ├── one_clicks_info.py │ ├── project.py │ ├── project_resources_info.py │ ├── projects_info.py │ ├── regions_info.py │ ├── reserved_ip.py │ ├── reserved_ips_info.py │ ├── sizes_info.py │ ├── snapshot.py │ ├── snapshots_info.py │ ├── space.py │ ├── spaces_info.py │ ├── ssh_key.py │ ├── ssh_keys_info.py │ ├── tag.py │ ├── tags_info.py │ ├── uptime_check.py │ ├── uptime_checks_info.py │ ├── uptime_checks_state_info.py │ ├── volume.py │ ├── volume_action.py │ ├── volume_snapshot.py │ ├── volumes_info.py │ ├── vpc.py │ └── vpcs_info.py ├── poetry.lock ├── pyproject.toml └── tests ├── integration ├── .gitignore ├── integration_config.yml.template ├── requirements.txt └── targets │ ├── .gitkeep │ ├── account_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── balance_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── billing_history_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── cdn_endpoints │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml │ ├── cdn_endpoints_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── certificate │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml │ ├── certificates_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── container_registry_info │ ├── aliases │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_get.yml │ │ └── main.yml │ ├── database_cluster │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete_valkey.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── database_clusters_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── domain │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_and_delete.yml │ │ └── main.yml │ ├── domain_record │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_create_and_delete.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── domain_records_info │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml │ ├── domains_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── droplet │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete_unique_name_and_region.yml │ │ ├── 02_resize_noop.yml │ │ ├── 03_resize_new.yml │ │ ├── 04_resize_bigger.yml │ │ ├── 05_resize_smaller.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── droplet_action_power │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_power_off.yml │ │ ├── 02_power_on.yml │ │ ├── 03_shutdown.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── droplet_action_resize │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_resize.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── droplet_action_snapshot │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_snapshot.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── droplets_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── firewall │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── firewalls_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── images_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── kubernetes_cluster │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_create_delete.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── kubernetes_clusters_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── load_balancer │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── load_balancers_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── monitoring_alert_policies_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── monitoring_alert_policy │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── one_click │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_check.yml │ │ ├── 02_fail.yml │ │ └── main.yml │ ├── one_clicks_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── project │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── project_resources_info │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_get_default.yml │ │ ├── 02_get_one.yml │ │ └── main.yml │ ├── projects_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── regions_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── reserved_ip │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── reserved_ips_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── sizes_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── snapshot │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── snapshots_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── space │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── spaces_info │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_get_all.yml │ │ ├── 02_get_one.yml │ │ └── main.yml │ ├── ssh_key │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── ssh_keys_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── tag │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── tags_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── uptime_check │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_create_delete_not_unique_name.yml │ │ ├── 02_create_delete_unique_name.yml │ │ └── main.yml │ ├── uptime_checks_info │ ├── aliases │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_get.yml │ │ └── main.yml │ ├── uptime_checks_state_info │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_get_existing.yml │ │ ├── 02_get_non_existent.yml │ │ └── main.yml │ ├── volume │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── volume_action │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 00_setup.yml │ │ ├── 01_attach.yml │ │ ├── 02_detach.yml │ │ ├── 99_teardown.yml │ │ └── main.yml │ ├── volume_snapshot │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ ├── volumes_info │ ├── aliases │ └── tasks │ │ └── main.yml │ ├── vpc │ ├── aliases │ ├── defaults │ │ └── main.yml │ └── tasks │ │ ├── 01_create_delete.yml │ │ └── main.yml │ └── vpcs_info │ ├── aliases │ └── tasks │ └── main.yml ├── run-integration.sh ├── run-sanity.sh ├── units └── .gitkeep └── utils └── render.sh /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/python 3 | { 4 | "name": "Python 3 Ansible Development", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/python:1-3.9-bookworm", 7 | 8 | // Features to add to the dev container. More info: https://containers.dev/features. 9 | "features": { 10 | "ghcr.io/devcontainers/features/docker-in-docker:2": { 11 | "dockerDashComposeVersion": "v2" 12 | }, 13 | "ghcr.io/devcontainers/features/git:1": {}, 14 | "ghcr.io/devcontainers/features/github-cli:1": {}, 15 | "ghcr.io/devcontainers-contrib/features/ansible:2": {}, 16 | "ghcr.io/devcontainers-contrib/features/poetry:2": {}, 17 | "ghcr.io/devcontainers-contrib/features/pre-commit:2": {}, 18 | "ghcr.io/devcontainers/features/common-utils:2": { 19 | "installOhMyZsh": true, 20 | "upgradePackages": true 21 | }, 22 | "ghcr.io/devcontainers-contrib/features/zsh-plugins:0": { 23 | "plugins": "ansible gh git poetry", 24 | "omzPlugins":"https://github.com/zsh-users/zsh-syntax-highlighting.git" 25 | }, 26 | "ghcr.io/devcontainers-contrib/features/apt-packages:1": { 27 | "packages": "shellcheck,vim" 28 | } 29 | }, 30 | 31 | "updateContentCommand": "make install", 32 | "postCreateCommand": "sudo apt update --fix-missing && sudo apt full-upgrade -y", 33 | "postStartCommand": "git pull --prune; make install", 34 | 35 | // Configure tool-specific properties. 36 | "customizations": { 37 | "vscode": { 38 | // Ensure that, minimally, these extensions are installed 39 | "extensions": [ 40 | "ms-python.python", 41 | "redhat.ansible", 42 | "yzhang.markdown-all-in-one", 43 | "tamasfe.even-better-toml", 44 | "github.vscode-github-actions", 45 | "ms-vscode.makefile-tools" 46 | ] 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @digitalocean/ansible-maintainers 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser 2 | blank_issues_enabled: false # default: true 3 | contact_links: 4 | - name: 🔐 Security bug report 🔥 5 | url: https://www.digitalocean.com/.well-known/security.txt 6 | about: | 7 | Please learn how to report security vulnerabilities here. 8 | 9 | For all security related bugs, report through our bug bounty program 10 | instead of using this issue tracker and you will receive 11 | a prompt response. 12 | 13 | For more information, see 14 | https://www.digitalocean.com/.well-known/security.txt 15 | 16 | - name: 📝 Ansible Code of Conduct 17 | url: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_template_chooser 18 | about: ❤ Be nice to other members of the community. ☮ Behave. 19 | 20 | - name: 💬 Talks to the community 21 | url: https://github.com/digitalocean/ansible-collection/discussions 22 | about: Please ask and answer usage questions here 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ✨ Feature request 3 | description: Suggest an idea for this project 4 | 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: > 9 | **Thank you for wanting to suggest a feature for `digitalocean.cloud`!** 10 | 11 | 12 | Verify first that your idea is not [already requested on 13 | GitHub][issue search]. 14 | 15 | Also test if the `main` branch does not already implement this. 16 | 17 | [issue search]: ../search?q=is%3Aissue&type=issues 18 | 19 | - type: textarea 20 | attributes: 21 | label: Summary 22 | description: > 23 | Describe the new feature/improvement you would like briefly below. 24 | 25 | What's the problem this feature will solve? 26 | 27 | What are you trying to do, that you are unable to achieve 28 | with `digitalocean.cloud` as it currently stands? 29 | 30 | * Provide examples of real-world use cases that this would enable 31 | and how it solves the problem you described. 32 | 33 | * How do you solve this now? 34 | 35 | * Have you tried to work around the problem using other tools? 36 | 37 | * Could there be a different approach to solving this issue? 38 | 39 | placeholder: >- 40 | I am trying to do X with `digitalocean.cloud` from the `main` branch on GitHub and 41 | I think that implementing a feature Y would be very helpful for me and 42 | every other user of `digitalocean.cloud` because of Z. 43 | validations: 44 | required: true 45 | 46 | - type: dropdown 47 | attributes: 48 | label: Issue Type 49 | description: > 50 | Please select the single available option in the drop-down. 51 | 52 |
53 | 54 | Why? 55 | 56 | 57 | 58 | _We will make it easier in the future, once GitHub 59 | supports dropdown defaults. Promise!_ 60 | 61 |
62 | options: 63 | - Feature Idea 64 | validations: 65 | required: true 66 | 67 | - type: input 68 | attributes: 69 | label: Component Name 70 | description: > 71 | Write the short name of the rst file, module, plugin, task or 72 | feature below, *use your best guess if unsure*. 73 | 74 | placeholder: droplet, one_click, domain_record, account_info, etc. 75 | validations: 76 | required: true 77 | 78 | - type: textarea 79 | attributes: 80 | label: Additional Information 81 | description: | 82 | Describe how this improves the documentation, e.g. before/after situation or screenshots. 83 | 84 | > [!TIP] 85 | > You can paste https://gist.github.com links for larger files. 86 | 87 | - type: checkboxes 88 | attributes: 89 | label: Code of Conduct 90 | description: | 91 | Read the [Ansible Code of Conduct][CoC] first. 92 | 93 | [CoC]: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--bug_report.yml 94 | options: 95 | - label: I agree to follow the Ansible Code of Conduct 96 | required: true 97 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Please see the documentation for all configuration options: 2 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 3 | 4 | version: 2 5 | updates: 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | labels: 11 | - "dependabot" 12 | groups: 13 | all: 14 | patterns: 15 | - "*" 16 | 17 | - package-ecosystem: "pip" 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | labels: 22 | - "dependabot" 23 | groups: 24 | production-dependencies: 25 | dependency-type: production 26 | nonprod-dependencies: 27 | dependency-type: development 28 | -------------------------------------------------------------------------------- /.github/workflows/ansible-test-sanity.yml: -------------------------------------------------------------------------------- 1 | name: Sanity tests 2 | on: 3 | push: 4 | branches: [main] 5 | workflow_dispatch: 6 | 7 | concurrency: 8 | group: ${{ github.workflow }} 9 | cancel-in-progress: false 10 | 11 | jobs: 12 | sanity: 13 | runs-on: ubuntu-22.04 14 | environment: main 15 | timeout-minutes: 30 16 | name: Sanity (Ⓐ${{ matrix.versions.ansible }} on ${{ matrix.versions.python }} / ${{ matrix.module }}) 17 | strategy: 18 | fail-fast: false 19 | max-parallel: 4 20 | matrix: 21 | # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html 22 | versions: 23 | - ansible: stable-2.14 24 | python: "3.9" 25 | - ansible: stable-2.15 26 | python: "3.10" 27 | - ansible: stable-2.16 28 | python: "3.10" 29 | - ansible: devel 30 | python: "3.11" 31 | module: 32 | - account_info 33 | 34 | steps: 35 | - name: Perform testing 36 | uses: ansible-community/ansible-test-gh-action@release/v1 37 | with: 38 | ansible-core-version: ${{ matrix.versions.ansible }} 39 | origin-python-version: ${{ matrix.versions.python }} 40 | target: ${{ matrix.module }} 41 | target-python-version: ${{ matrix.versions.python }} 42 | testing-type: sanity 43 | -------------------------------------------------------------------------------- /.github/workflows/ansible-test-unit.yml: -------------------------------------------------------------------------------- 1 | name: Unit tests 2 | on: 3 | push: 4 | branches: [main] 5 | workflow_dispatch: 6 | 7 | concurrency: 8 | group: ${{ github.workflow }} 9 | cancel-in-progress: false 10 | 11 | jobs: 12 | units: 13 | runs-on: ubuntu-22.04 14 | environment: main 15 | timeout-minutes: 30 16 | name: Units (Ⓐ${{ matrix.versions.ansible }} on ${{ matrix.versions.python }}) 17 | strategy: 18 | fail-fast: false 19 | max-parallel: 4 20 | matrix: 21 | # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html 22 | versions: 23 | - ansible: stable-2.14 24 | python: "3.9" 25 | - ansible: stable-2.15 26 | python: "3.10" 27 | - ansible: stable-2.16 28 | python: "3.10" 29 | - ansible: devel 30 | python: "3.11" 31 | 32 | steps: 33 | - name: Perform testing 34 | uses: ansible-community/ansible-test-gh-action@release/v1 35 | with: 36 | ansible-core-version: ${{ matrix.versions.ansible }} 37 | origin-python-version: ${{ matrix.versions.python }} 38 | target-python-version: ${{ matrix.versions.python }} 39 | testing-type: units 40 | -------------------------------------------------------------------------------- /.github/workflows/extra-docs-linting.yml: -------------------------------------------------------------------------------- 1 | name: Lint extra docsite docs and links 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [main] 7 | workflow_dispatch: 8 | 9 | jobs: 10 | docsite: 11 | name: Lint extra docsite docs and links 12 | permissions: 13 | contents: read 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Check out code 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up Python 20 | uses: actions/setup-python@v5 21 | with: 22 | python-version: "3.9" 23 | 24 | - name: Install antsibull-docs 25 | run: pip install antsibull-docs --disable-pip-version-check 26 | 27 | - name: Run collection docs linter 28 | run: antsibull-docs lint-collection-docs . 29 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint Checks 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | lint: 8 | name: "Ansible Lint" 9 | runs-on: ubuntu-22.04 10 | 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: Install dependency manager 15 | run: pipx install poetry 16 | 17 | - name: Set up Python 3.x 18 | id: setup-python 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version-file: pyproject.toml 22 | cache: 'poetry' 23 | 24 | - name: Install packages 25 | run: poetry install --no-interaction 26 | 27 | - name: Lint 28 | run: make lint 29 | -------------------------------------------------------------------------------- /.github/workflows/psf-black.yml: -------------------------------------------------------------------------------- 1 | name: Python psf/black 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "**.py" 7 | push: 8 | branches: [main] 9 | paths: 10 | - "**.py" 11 | workflow_dispatch: 12 | 13 | concurrency: 14 | group: ${{ github.workflow }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | psf-black: 19 | runs-on: ubuntu-22.04 20 | timeout-minutes: 5 21 | steps: 22 | - name: Check out code 23 | uses: actions/checkout@v4 24 | 25 | - name: Run psf/black 26 | uses: psf/black@stable 27 | -------------------------------------------------------------------------------- /.github/workflows/publish-galaxy.yml: -------------------------------------------------------------------------------- 1 | name: Publish Collection on Galaxy 2 | 3 | on: 4 | release: 5 | types: 6 | - published 7 | workflow_dispatch: 8 | 9 | concurrency: 10 | group: ${{ github.workflow }} 11 | cancel-in-progress: false 12 | 13 | jobs: 14 | build-and-publish: 15 | name: Build and publish the Collection on Galaxy 16 | runs-on: ubuntu-22.04 17 | environment: main 18 | timeout-minutes: 5 19 | steps: 20 | - name: Check out code 21 | uses: actions/checkout@v4 22 | 23 | - name: Build and publish 24 | uses: artis3n/ansible_galaxy_collection@v2 25 | with: 26 | api_key: '${{ secrets.GALAXY_TOKEN }}' 27 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-sanity.yml: -------------------------------------------------------------------------------- 1 | name: Pull request sanity tests 2 | 3 | on: 4 | pull_request: 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.event.pull_request.number }} 8 | cancel-in-progress: true 9 | 10 | env: 11 | PR_NUMBER: ${{ github.event.pull_request.number }} 12 | 13 | jobs: 14 | test-sanity: 15 | runs-on: ubuntu-22.04 16 | timeout-minutes: 30 17 | strategy: 18 | fail-fast: false 19 | max-parallel: 4 20 | matrix: 21 | versions: 22 | - ansible: stable-2.14 23 | python: "3.9" 24 | - ansible: stable-2.15 25 | python: "3.10" 26 | - ansible: stable-2.16 27 | python: "3.11" 28 | - ansible: devel 29 | python: "3.11" 30 | steps: 31 | - name: Perform sanity testing 32 | uses: ansible-community/ansible-test-gh-action@release/v1 33 | with: 34 | ansible-core-version: ${{ matrix.versions.ansible }} 35 | origin-python-version: ${{ matrix.versions.python }} 36 | target-python-version: ${{ matrix.versions.python }} 37 | testing-type: sanity 38 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-units.yml: -------------------------------------------------------------------------------- 1 | name: Pull request unit tests 2 | 3 | on: 4 | pull_request: 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.event.pull_request.number }} 8 | cancel-in-progress: true 9 | 10 | env: 11 | PR_NUMBER: ${{ github.event.pull_request.number }} 12 | 13 | jobs: 14 | test-units: 15 | runs-on: ubuntu-22.04 16 | timeout-minutes: 30 17 | strategy: 18 | fail-fast: false 19 | max-parallel: 4 20 | matrix: 21 | versions: 22 | - ansible: stable-2.14 23 | python: "3.9" 24 | - ansible: stable-2.15 25 | python: "3.10" 26 | - ansible: stable-2.16 27 | python: "3.11" 28 | - ansible: devel 29 | python: "3.11" 30 | steps: 31 | - name: Perform unit testing 32 | uses: ansible-community/ansible-test-gh-action@release/v1 33 | with: 34 | ansible-core-version: ${{ matrix.versions.ansible }} 35 | origin-python-version: ${{ matrix.versions.python }} 36 | target-python-version: ${{ matrix.versions.python }} 37 | testing-type: units 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /tests/output/ 2 | /changelogs/.plugin-cache.yaml 3 | tests/integration/inventory 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | pip-wheel-metadata/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | 135 | # IDEs 136 | .vscode 137 | .idea 138 | 139 | # Internal only files 140 | *internal* 141 | 142 | # macOS metadata 143 | .DS_Store 144 | -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | MD013: false # https://github.com/DavidAnson/markdownlint/blob/v0.25.1/doc/Rules.md#md013 3 | MD033: false # https://github.com/DavidAnson/markdownlint/blob/v0.25.1/doc/Rules.md#md033 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v4.4.0 5 | hooks: 6 | - id: check-yaml 7 | - id: end-of-file-fixer 8 | - id: trailing-whitespace 9 | - repo: https://github.com/ansible/ansible-lint 10 | rev: v6.20.0 11 | hooks: 12 | - id: ansible-lint 13 | - repo: https://github.com/psf/black 14 | rev: 23.7.0 15 | hooks: 16 | - id: black 17 | - repo: https://github.com/koalaman/shellcheck-precommit 18 | rev: v0.9.0 19 | hooks: 20 | - id: shellcheck 21 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | python3 3.11.11 2 | poetry 1.8.5 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "redhat.ansible" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Code of Conduct 2 | 3 | Please see the official [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html). 4 | -------------------------------------------------------------------------------- /GPL-3.0: -------------------------------------------------------------------------------- 1 | LICENSE -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Mark Mercado (@mamercad) 2 | Ari Kalfus (@artis3n) 3 | Daniel George (@danxg87) 4 | -------------------------------------------------------------------------------- /MAINTAINING.md: -------------------------------------------------------------------------------- 1 | # Maintaining this collection 2 | 3 | Refer to the [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst). 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | .PHONY: install 4 | install: 5 | poetry install --no-root --with=dev 6 | poetry run pre-commit install --install-hooks 7 | 8 | .PHONY: update 9 | clean: 10 | poetry update 11 | poetry run pre-commit autoupdate 12 | 13 | .PHONY: lint 14 | lint: collection-cleanup collection-prep 15 | poetry run antsibull-changelog lint 16 | poetry run ansible-lint --fix 17 | 18 | # Assumes ansible-test is available in the global scope, such as within the devcontainer environment 19 | .PHONY: sanity 20 | sanity: collection-cleanup collection-prep 21 | poetry run tests/run-sanity.sh 22 | 23 | .PHONY: integration 24 | integration: collection-cleanup collection-prep 25 | poetry run tests/run-integration.sh 26 | 27 | # Make a copy of the collection available in an expected Ansible path 28 | # For running tooling in Codespaces or other environments 29 | # If you get ansible-lint errors about unresolved modules in this collection, 30 | # run this command then re-run ansible-lint. 31 | .PHONY: collection-prep 32 | collection-prep: 33 | mkdir -p ~/.ansible/collections/ansible_collections/digitalocean/cloud 34 | cp -r ./ ~/.ansible/collections/ansible_collections/digitalocean/cloud 35 | 36 | .PHONY: collection-cleanup 37 | collection-cleanup: 38 | rm -rf ~/.ansible/collections/ansible_collections/digitalocean/cloud 39 | -------------------------------------------------------------------------------- /REVIEW_CHECKLIST.md: -------------------------------------------------------------------------------- 1 | # Review Checklist 2 | 3 | Refer to the [Collection review checklist](https://github.com/ansible/community-docs/blob/main/review_checklist.rst). 4 | -------------------------------------------------------------------------------- /changelogs/config.yaml: -------------------------------------------------------------------------------- 1 | changelog_filename_template: ../CHANGELOG.rst 2 | changelog_filename_version_depth: 0 3 | changes_file: changelog.yaml 4 | changes_format: combined 5 | keep_fragments: false 6 | mention_ancestor: true 7 | new_plugins_after_name: removed_features 8 | notesdir: fragments 9 | prelude_section_name: release_summary 10 | prelude_section_title: Release Summary 11 | sections: 12 | - - major_changes 13 | - Major Changes 14 | - - minor_changes 15 | - Minor Changes 16 | - - breaking_changes 17 | - Breaking Changes / Porting Guide 18 | - - deprecated_features 19 | - Deprecated Features 20 | - - removed_features 21 | - Removed Features (previously deprecated) 22 | - - security_fixes 23 | - Security Fixes 24 | - - bugfixes 25 | - Bugfixes 26 | - - known_issues 27 | - Known Issues 28 | title: DigitalOcean Collection 29 | trivial_section_name: trivial 30 | -------------------------------------------------------------------------------- /changelogs/fragments/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/changelogs/fragments/.gitkeep -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - "/ansible_collections/digitalocean/cloud/::" 4 | -------------------------------------------------------------------------------- /do+a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/do+a.png -------------------------------------------------------------------------------- /docs/docsite/links.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This will make sure that plugin and module documentation gets Edit on GitHub links 3 | # that allow users to directly create a PR for this plugin or module in GitHub's UI. 4 | # Remove this section if the collection repository is not on GitHub, or if you do not want this 5 | # functionality for your collection. 6 | edit_on_github: 7 | repository: digitalocean/ansible-collection 8 | branch: main 9 | # If your collection root (the directory containing galaxy.yml) does not coincide with your 10 | # repository's root, you have to specify the path to the collection root here. For example, 11 | # if the collection root is in a subdirectory ansible_collections/community/REPO_NAME 12 | # in your repository, you have to set path_prefix to 'ansible_collections/community/REPO_NAME'. 13 | path_prefix: "" 14 | 15 | # Here you can add arbitrary extra links. Please keep the number of links down to a 16 | # minimum! Also please keep the description short, since this will be the text put on 17 | # a button. 18 | # 19 | # Also note that some links are automatically added from information in galaxy.yml. 20 | # The following are automatically added: 21 | # 1. A link to the issue tracker (if `issues` is specified); 22 | # 2. A link to the homepage (if `homepage` is specified and does not equal the 23 | # `documentation` or `repository` link); 24 | # 3. A link to the collection's repository (if `repository` is specified). 25 | 26 | extra_links: 27 | - description: Report an issue 28 | url: https://github.com/digitalocean/ansible-collection/issues/new/choose 29 | 30 | # Specify communication channels for your collection. We suggest to not specify more 31 | # than one place for communication per communication tool to avoid confusion. 32 | communication: {} 33 | # Sigh ... 34 | # github_discussions: 35 | # - topic: "Start a new discussion" 36 | # room: "TBD" 37 | # matrix_rooms: 38 | # - topic: General usage and support questions 39 | # room: "#users:ansible.im" 40 | # irc_channels: 41 | # - topic: General usage and support questions 42 | # network: Libera 43 | # channel: "#ansible" 44 | # mailing_lists: 45 | # - topic: Ansible Project List 46 | # url: https://groups.google.com/g/ansible-project 47 | # You can also add a `subscribe` field with an URI that allows to subscribe 48 | # to the mailing list. For lists on https://groups.google.com/ a subscribe link is 49 | # automatically generated. 50 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # See https://docs.ansible.com/ansible/latest/dev_guide/collections_galaxy_meta.html 3 | namespace: digitalocean 4 | name: cloud 5 | version: "1.2.1" 6 | readme: README.md 7 | authors: 8 | - Mark Mercado (@mamercad) 9 | - Ari Kalfus (@artis3n) 10 | description: DigitalOcean Ansible Collection 11 | license_file: GPL-3.0 12 | tags: 13 | - cloud 14 | - digitalocean 15 | - droplet 16 | - sammy 17 | repository: https://github.com/digitalocean/ansible-collection 18 | documentation: https://github.com/digitalocean/ansible-collection/blob/main/README.md 19 | homepage: https://github.com/digitalocean/ansible-collection 20 | issues: https://github.com/digitalocean/ansible-collection/issues 21 | build_ignore: 22 | - .gitignore 23 | - changelogs/.plugin-cache.yaml 24 | -------------------------------------------------------------------------------- /inventory/digitalocean.yml: -------------------------------------------------------------------------------- 1 | --- 2 | plugin: digitalocean.cloud.droplets 3 | cache: true 4 | cache_plugin: ansible.builtin.jsonfile 5 | cache_connection: /tmp/digitalocean_droplets_inventory 6 | cache_timeout: 300 7 | attributes: 8 | - id 9 | - memory 10 | - vcpus 11 | - disk 12 | - locked 13 | - status 14 | - kernel 15 | - created_at 16 | - features 17 | - backup_ids 18 | - next_backup_window 19 | - snapshot_ids 20 | - image 21 | - volume_ids 22 | - size 23 | - size_slug 24 | - networks 25 | - region 26 | - tags 27 | - vpc_uuid 28 | compose: 29 | ansible_host: networks.v4 | selectattr("type", "eq", "public") | map(attribute="ip_address") | first 30 | class: size.description | lower 31 | distribution: image.distribution | lower 32 | keyed_groups: 33 | - key: image.slug | default("null", true) 34 | prefix: image 35 | separator: _ 36 | - key: tags 37 | prefix: tag 38 | separator: _ 39 | - key: region.slug 40 | prefix: region_slug 41 | separator: _ 42 | - key: status 43 | prefix: status 44 | separator: _ 45 | - key: vpc_uuid 46 | prefix: vpc 47 | groups: 48 | basic: "'basic' in class" 49 | ubuntu: "'ubuntu' in distribution" 50 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | --- 2 | requires_ansible: ">=2.14.0" # Use '>= 2.9.10' instead, if needed 3 | action_groups: 4 | all: 5 | - account_info 6 | - balance_info 7 | - billing_history_info 8 | - cdn_endpoints 9 | - cdn_endpoints_info 10 | - certificate 11 | - certificates_info 12 | - container_registry_info 13 | - database_cluster 14 | - database_clusters_info 15 | - domain 16 | - domain_record 17 | - domain_records_info 18 | - domains_info 19 | - droplet 20 | - droplet_action_power 21 | - droplet_action_resize 22 | - droplet_action_snapshot 23 | - droplets_info 24 | - firewall 25 | - firewalls_info 26 | - images_info 27 | - kubernetes_cluster 28 | - kubernetes_clusters_info 29 | - load_balancer 30 | - load_balancers_info 31 | - monitoring_alert_policies_info 32 | - monitoring_alert_policy 33 | - one_click 34 | - one_clicks_info 35 | - project 36 | - project_resources_info 37 | - projects_info 38 | - regions_info 39 | - reserved_ip 40 | - reserved_ips_info 41 | - sizes_info 42 | - snapshot 43 | - snapshots_info 44 | - space 45 | - spaces_info 46 | - ssh_key 47 | - ssh_keys_info 48 | - tag 49 | - tags_info 50 | - uptime_check 51 | - uptime_checks_info 52 | - uptime_checks_state_info 53 | - volume 54 | - volume_action 55 | - volumes_info 56 | - volume_snapshot 57 | - vpc 58 | - vpcs_info 59 | -------------------------------------------------------------------------------- /playbooks/account_info.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | # Running this playbook: 4 | # ansible-playbook -i localhost, -c local playbooks/account_info.yml -v 5 | 6 | - name: Account info 7 | hosts: localhost 8 | connection: local 9 | gather_facts: false 10 | tasks: 11 | - name: Get account information 12 | digitalocean.cloud.account_info: 13 | 14 | # Example task output: 15 | # TASK [Get account information] *********************************************** 16 | # ok: [localhost] => changed=false 17 | # account: 18 | # droplet_limit: 25 19 | # email: mmercado@digitalocean.com 20 | # email_verified: true 21 | # floating_ip_limit: 3 22 | # name: Mark Mercado 23 | # reserved_ip_limit: 3 24 | # status: active 25 | # status_message: '' 26 | # team: 27 | # name: FOSS 28 | # uuid: 3281ad4a-0092-4e6b-abd2-c7a7ed111503 29 | # uuid: eab13a8a-99e3-4ffd-a587-b8a7789f0090 30 | # volume_limit: 100 31 | # msg: Current account information 32 | -------------------------------------------------------------------------------- /playbooks/balance_info.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | # Running this playbook: 4 | # ansible-playbook -i localhost, -c local playbooks/balance_info.yml -v 5 | 6 | - name: Balance info 7 | hosts: localhost 8 | connection: local 9 | gather_facts: false 10 | tasks: 11 | - name: Get balance information 12 | digitalocean.cloud.balance_info: 13 | 14 | # Example task output: 15 | # TASK [Get balance information] *********************************************** 16 | # ok: [localhost] => changed=false 17 | # balance: 18 | # account_balance: '0.00' 19 | # generated_at: '2023-07-28T00:00:00Z' 20 | # month_to_date_balance: '0.00' 21 | # month_to_date_usage: '0.00' 22 | # msg: Current balance information 23 | -------------------------------------------------------------------------------- /playbooks/billing_history_info.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | # Running this playbook: 4 | # ansible-playbook -i localhost, -c local playbooks/billing_history_info.yml -v 5 | 6 | - name: Billing history info 7 | hosts: localhost 8 | connection: local 9 | gather_facts: false 10 | tasks: 11 | - name: Get billing history information 12 | digitalocean.cloud.billing_history_info: 13 | 14 | # Example task output: 15 | # TASK [Get billing history information] *************************************** 16 | # ok: [localhost] => changed=false 17 | # msg: No billing history information 18 | -------------------------------------------------------------------------------- /playbooks/cdn_endpoints_info.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | # Running this playbook: 4 | # ansible-playbook -i localhost, -c local playbooks/billing_history_info.yml -v 5 | 6 | - name: CDN endpoints info 7 | hosts: localhost 8 | connection: local 9 | gather_facts: false 10 | tasks: 11 | - name: Get CDN endpoints 12 | digitalocean.cloud.cdn_endpoints_info: 13 | 14 | # Example task output: 15 | # TASK [Get CDN endpoints] ***************************************************** 16 | # ok: [localhost] => changed=false 17 | # endpoints: [] 18 | # msg: No CDN endpoints 19 | -------------------------------------------------------------------------------- /playbooks/droplet.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create SSH key and Droplet 3 | hosts: localhost 4 | connection: local 5 | gather_facts: true 6 | 7 | vars: 8 | digitalocean_token: "{{ lookup('ansible.builtin.env', 'DIGITALOCEAN_TOKEN') }}" 9 | public_key: "{{ lookup('ansible.builtin.file', ansible_env['HOME'] ~ '/.ssh/sammy.key.pub') }}" 10 | 11 | tasks: 12 | - name: Create SSH key 13 | digitalocean.cloud.ssh_key: 14 | state: present 15 | token: "{{ digitalocean_token }}" 16 | public_key: "{{ public_key }}" 17 | name: sammy 18 | register: ssh_key 19 | 20 | - name: Create Droplet 21 | digitalocean.cloud.droplet: 22 | state: present 23 | token: "{{ digitalocean_token }}" 24 | name: sammy-droplet 25 | region: nyc3 26 | size: s-1vcpu-2gb 27 | image: ubuntu-22-04-x64 28 | ssh_keys: ["{{ ssh_key.ssh_key.id }}"] 29 | unique_name: true 30 | -------------------------------------------------------------------------------- /plugins/doc_fragments/common.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright: (c) 2023, Mark Mercado 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import absolute_import, division, print_function 6 | 7 | __metaclass__ = type 8 | 9 | 10 | class ModuleDocFragment(object): 11 | DOCUMENTATION = r""" 12 | options: 13 | state: 14 | description: 15 | - State of the resource, C(present) to create, C(absent) to destroy. 16 | type: str 17 | choices: [ present, absent ] 18 | default: present 19 | timeout: 20 | description: 21 | - Polling timeout in seconds. 22 | type: int 23 | default: 300 24 | token: 25 | description: 26 | - DigitalOcean API token. 27 | - There are several environment variables which can be used to provide this value. 28 | - C(DIGITALOCEAN_ACCESS_TOKEN), C(DIGITALOCEAN_TOKEN), C(DO_API_TOKEN), C(DO_API_KEY), C(DO_OAUTH_TOKEN) and C(OAUTH_TOKEN) 29 | type: str 30 | aliases: [ oauth_token, api_token ] 31 | required: false 32 | client_override_options: 33 | description: 34 | - Client override options (developer use). 35 | - For example, can be used to override the DigitalOcean API endpoint for an internal test suite. 36 | - If provided, these options will knock out existing options. 37 | type: dict 38 | required: false 39 | module_override_options: 40 | description: 41 | - Module override options (developer use). 42 | - Can be used to override module options to support experimental or future options. 43 | - If provided, these options will knock out existing options. 44 | type: dict 45 | required: false 46 | """ 47 | -------------------------------------------------------------------------------- /plugins/module_utils/droplet_resize.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright: (c) 2025, DigitalOcean LLC 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import absolute_import, division, print_function 6 | 7 | __metaclass__ = type 8 | 9 | 10 | import time 11 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 12 | DigitalOceanCommonModule, 13 | DigitalOceanConstants, 14 | ) 15 | 16 | 17 | class DropletResize(DigitalOceanCommonModule): 18 | def __init__(self, module, droplet_id, region, current_size, new_size, resize_disk): 19 | super().__init__(module) 20 | self.droplet_id = droplet_id 21 | self.current_size = current_size 22 | self.resize_disk = resize_disk 23 | self.new_size = new_size 24 | self.region = region 25 | self.type = "resize" 26 | self.timeout = module.params.get("timeout") 27 | 28 | def resize_droplet(self): 29 | try: 30 | body = { 31 | "type": "resize", 32 | "size": self.new_size, 33 | "disk": self.resize_disk, 34 | } 35 | 36 | self.client.droplet_actions.post(droplet_id=self.droplet_id, body=body) 37 | 38 | # Wait for the resize action to complete 39 | end_time = time.monotonic() + self.timeout 40 | while time.monotonic() < end_time: 41 | droplet = self.client.droplets.get(self.droplet_id)["droplet"] 42 | if droplet["size"]["slug"] == self.new_size: 43 | self.module.exit_json( 44 | changed=True, 45 | msg=f"Resized Droplet {droplet['name']} ({self.droplet_id}) in {self.region} from size {self.current_size} to size {self.new_size}", 46 | droplet=droplet, 47 | ) 48 | time.sleep(DigitalOceanConstants.SLEEP) 49 | 50 | self.module.fail_json( 51 | changed=False, 52 | msg=f"Resizing Droplet {self.droplet_id} from {self.current_size} to size {self.new_size} has failed", 53 | ) 54 | except Exception as err: 55 | self.module.fail_json( 56 | changed=False, 57 | msg=f"An error occurred while resizing the Droplet: {str(err)}", 58 | error=str(err), 59 | ) 60 | -------------------------------------------------------------------------------- /plugins/modules/balance_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: balance_info 14 | 15 | short_description: Retrieve the balances on a customer's account 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - Retrieve the balances on a customer's account. 21 | - View the API documentation at U(https://docs.digitalocean.com/reference/api/api-reference/#operation/balance_get). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get balance information 36 | digitalocean.cloud.balance_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | balance: 43 | description: Balance information. 44 | returned: always 45 | type: dict 46 | sample: 47 | month_to_date_balance: 23.44 48 | account_balance: 12.23 49 | month_to_date_usage: 11.21 50 | generated_at: '2019-07-09T15:01:12Z' 51 | error: 52 | description: DigitalOcean API error. 53 | returned: failure 54 | type: dict 55 | sample: 56 | Message: Informational error message. 57 | Reason: Unauthorized 58 | Status Code: 401 59 | msg: 60 | description: Balance result information. 61 | returned: always 62 | type: str 63 | sample: 64 | - Current balance information 65 | - Current balance information not found 66 | """ 67 | 68 | from ansible.module_utils.basic import AnsibleModule 69 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 70 | DigitalOceanCommonModule, 71 | DigitalOceanOptions, 72 | ) 73 | 74 | 75 | class BalanceInformation(DigitalOceanCommonModule): 76 | def __init__(self, module): 77 | super().__init__(module) 78 | if self.state == "present": 79 | self.present() 80 | 81 | def present(self): 82 | try: 83 | balance = self.client.balance.get() 84 | if balance: 85 | self.module.exit_json( 86 | changed=False, msg="Current balance information", balance=balance 87 | ) 88 | self.module.fail_json( 89 | changed=False, msg="Current balance information not found" 90 | ) 91 | except DigitalOceanCommonModule.HttpResponseError as err: 92 | error = { 93 | "Message": err.error.message, 94 | "Status Code": err.status_code, 95 | "Reason": err.reason, 96 | } 97 | self.module.fail_json(changed=False, msg=error.get("Message"), error=error) 98 | 99 | 100 | def main(): 101 | argument_spec = DigitalOceanOptions.argument_spec() 102 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 103 | BalanceInformation(module) 104 | 105 | 106 | if __name__ == "__main__": 107 | main() 108 | -------------------------------------------------------------------------------- /plugins/modules/certificates_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: certificates_info 14 | 15 | short_description: List all of the certificates available on your account 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - List all of the certificates available on your account. 21 | - View the API documentation at U(https://docs.digitalocean.com/reference/api/api-reference/#operation/certificates_list). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get certificates 36 | digitalocean.cloud.certificates_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | certificates: 43 | description: Certificates. 44 | returned: always 45 | type: dict 46 | sample: 47 | - id: 892071a0-bb95-49bc-8021-3afd67a210bf 48 | name: web-cert-01 49 | not_after: '2017-02-22T00:23:00Z' 50 | sha1_fingerprint: dfcc9f57d86bf58e321c2c6c31c7a971be244ac7 51 | created_at: '2017-02-08T16:02:37Z' 52 | dns_names: [] 53 | state: verified 54 | type: custom 55 | error: 56 | description: DigitalOcean API error. 57 | returned: failure 58 | type: dict 59 | sample: 60 | Message: Informational error message. 61 | Reason: Unauthorized 62 | Status Code: 401 63 | msg: 64 | description: Certificates result information. 65 | returned: always 66 | type: str 67 | sample: 68 | - Current certificates 69 | - No certificates 70 | """ 71 | 72 | from ansible.module_utils.basic import AnsibleModule 73 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 74 | DigitalOceanCommonModule, 75 | DigitalOceanOptions, 76 | DigitalOceanFunctions, 77 | ) 78 | 79 | 80 | class CertificatesInformation(DigitalOceanCommonModule): 81 | def __init__(self, module): 82 | super().__init__(module) 83 | if self.state == "present": 84 | self.present() 85 | 86 | def present(self): 87 | certificates = DigitalOceanFunctions.get_paginated( 88 | module=self.module, 89 | obj=self.client.certificates, 90 | meth="list", 91 | key="certificates", 92 | exc=DigitalOceanCommonModule.HttpResponseError, 93 | ) 94 | if certificates: 95 | self.module.exit_json( 96 | changed=False, 97 | msg="Current certificates", 98 | certificates=certificates, 99 | ) 100 | self.module.exit_json(changed=False, msg="No certificates", certificates=[]) 101 | 102 | 103 | def main(): 104 | argument_spec = DigitalOceanOptions.argument_spec() 105 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 106 | CertificatesInformation(module) 107 | 108 | 109 | if __name__ == "__main__": 110 | main() 111 | -------------------------------------------------------------------------------- /plugins/modules/load_balancers_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: load_balancers_info 14 | 15 | short_description: Retrieve a list of all of the load balancers in your account 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - Retrieve a list of all of the load balancers in your account. 21 | - View the API documentation at (https://docs.digitalocean.com/reference/api/api-reference/#operation/loadBalancers_list). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get load balancers 36 | digitalocean.cloud.load_balancers_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | load_balancers: 43 | description: Load balancers. 44 | returned: always 45 | type: list 46 | elements: dict 47 | sample: [] 48 | error: 49 | description: DigitalOcean API error. 50 | returned: failure 51 | type: dict 52 | sample: 53 | Message: Informational error message. 54 | Reason: Unauthorized 55 | Status Code: 401 56 | msg: 57 | description: Domain result information. 58 | returned: always 59 | type: str 60 | sample: 61 | - Current domains 62 | - No domains 63 | """ 64 | 65 | from ansible.module_utils.basic import AnsibleModule 66 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 67 | DigitalOceanCommonModule, 68 | DigitalOceanOptions, 69 | DigitalOceanFunctions, 70 | ) 71 | 72 | 73 | class LoadBalancersInformation(DigitalOceanCommonModule): 74 | def __init__(self, module): 75 | super().__init__(module) 76 | if self.state == "present": 77 | self.present() 78 | 79 | def present(self): 80 | load_balancers = DigitalOceanFunctions.get_paginated( 81 | module=self.module, 82 | obj=self.client.load_balancers, 83 | meth="list", 84 | key="load_balancers", 85 | exc=DigitalOceanCommonModule.HttpResponseError, 86 | ) 87 | if load_balancers: 88 | self.module.exit_json( 89 | changed=False, 90 | msg="Current load balancers", 91 | load_balancers=load_balancers, 92 | ) 93 | self.module.exit_json( 94 | changed=False, msg="No load balancers", load_balancers=load_balancers 95 | ) 96 | 97 | 98 | def main(): 99 | argument_spec = DigitalOceanOptions.argument_spec() 100 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 101 | LoadBalancersInformation(module) 102 | 103 | 104 | if __name__ == "__main__": 105 | main() 106 | -------------------------------------------------------------------------------- /plugins/modules/sizes_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: sizes_info 14 | 15 | short_description: List all of available Droplet sizes 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - List all of available Droplet sizes. 21 | - View the API documentation at (https://docs.digitalocean.com/reference/api/api-reference/#operation/sizes_list). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get Droplet sizes 36 | digitalocean.cloud.sizes_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | sizes: 43 | description: Droplet sizes information. 44 | returned: always 45 | type: list 46 | elements: dict 47 | sample: 48 | - available: true 49 | description: Basic 50 | disk: 10 51 | memory: 512 52 | price_hourly: 0.00595 53 | price_monthly: 4.0 54 | regions: 55 | - ams3 56 | - fra1 57 | - nyc1 58 | - sfo3 59 | - sgp1 60 | - syd1 61 | slug: s-1vcpu-512mb-10gb 62 | transfer: 0.5 63 | vcpus: 1 64 | - ... 65 | error: 66 | description: DigitalOcean API error. 67 | returned: failure 68 | type: dict 69 | sample: 70 | Message: Informational error message. 71 | Reason: Unauthorized 72 | Status Code: 401 73 | msg: 74 | description: Droplet sizes result information. 75 | returned: always 76 | type: str 77 | sample: 78 | - Current Droplet sizes 79 | - No Droplet sizes 80 | """ 81 | 82 | from ansible.module_utils.basic import AnsibleModule 83 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 84 | DigitalOceanCommonModule, 85 | DigitalOceanOptions, 86 | DigitalOceanFunctions, 87 | ) 88 | 89 | 90 | class DropletSizesInformation(DigitalOceanCommonModule): 91 | def __init__(self, module): 92 | super().__init__(module) 93 | if self.state == "present": 94 | self.present() 95 | 96 | def present(self): 97 | sizes = DigitalOceanFunctions.get_paginated( 98 | module=self.module, 99 | obj=self.client.sizes, 100 | meth="list", 101 | key="sizes", 102 | exc=DigitalOceanCommonModule.HttpResponseError, 103 | ) 104 | if sizes: 105 | self.module.exit_json( 106 | changed=False, 107 | msg="Current Droplet sizes", 108 | sizes=sizes, 109 | ) 110 | self.module.exit_json(changed=False, msg="No Droplet sizes", sizes=[]) 111 | 112 | 113 | def main(): 114 | argument_spec = DigitalOceanOptions.argument_spec() 115 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 116 | DropletSizesInformation(module) 117 | 118 | 119 | if __name__ == "__main__": 120 | main() 121 | -------------------------------------------------------------------------------- /plugins/modules/ssh_keys_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: ssh_keys_info 14 | 15 | short_description: List all of the keys in your account 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - List all of the keys in your account. 21 | - View the API documentation at U(https://docs.digitalocean.com/reference/api/api-reference/#operation/sshKeys_list). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get SSH keys 36 | digitalocean.cloud.ssh_keys_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | ssh_keys: 43 | description: SSH keys. 44 | returned: always 45 | type: list 46 | elements: dict 47 | sample: 48 | - id: 289794 49 | fingerprint: '3b:16:e4:bf:8b:00:8b:b8:59:8c:a9:d3:f0:19:fa:45' 50 | public_key: 'ssh-rsa ANOTHEREXAMPLEaC1yc2EAAAADAQABAAAAQ...owLh64b72pxekALga2oi4GvT+TlWNhzPH4V anotherexample' 51 | name: Other Public Key 52 | error: 53 | description: DigitalOcean API error. 54 | returned: failure 55 | type: dict 56 | sample: 57 | Message: Informational error message. 58 | Reason: Unauthorized 59 | Status Code: 401 60 | msg: 61 | description: SSH keys result information. 62 | returned: always 63 | type: str 64 | sample: 65 | - Current SSH keys 66 | - No SSH keys 67 | """ 68 | 69 | from ansible.module_utils.basic import AnsibleModule 70 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 71 | DigitalOceanCommonModule, 72 | DigitalOceanOptions, 73 | DigitalOceanFunctions, 74 | ) 75 | 76 | 77 | class SSHKeysInformation(DigitalOceanCommonModule): 78 | def __init__(self, module): 79 | super().__init__(module) 80 | if self.state == "present": 81 | self.present() 82 | 83 | def present(self): 84 | ssh_keys = DigitalOceanFunctions.get_paginated( 85 | module=self.module, 86 | obj=self.client.ssh_keys, 87 | meth="list", 88 | key="ssh_keys", 89 | exc=DigitalOceanCommonModule.HttpResponseError, 90 | ) 91 | if ssh_keys: 92 | self.module.exit_json( 93 | changed=False, 94 | msg="Current SSH keys", 95 | ssh_keys=ssh_keys, 96 | ) 97 | self.module.exit_json(changed=False, msg="No SSH keys", ssh_keys=[]) 98 | 99 | 100 | def main(): 101 | argument_spec = DigitalOceanOptions.argument_spec() 102 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 103 | SSHKeysInformation(module) 104 | 105 | 106 | if __name__ == "__main__": 107 | main() 108 | -------------------------------------------------------------------------------- /plugins/modules/tags_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: tags_info 14 | 15 | short_description: List all of the tags on your account 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - List all of the tags on your account. 21 | - View the API documentation at U(https://docs.digitalocean.com/reference/api/api-reference/#operation/tags_list). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get tags 36 | digitalocean.cloud.tags_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | tags: 43 | description: Tags. 44 | returned: always 45 | type: list 46 | elements: dict 47 | sample: [] 48 | error: 49 | description: DigitalOcean API error. 50 | returned: failure 51 | type: dict 52 | sample: 53 | Message: Informational error message. 54 | Reason: Unauthorized 55 | Status Code: 401 56 | msg: 57 | description: Tag result information. 58 | returned: always 59 | type: str 60 | sample: 61 | - Current tags 62 | - No tags 63 | """ 64 | 65 | from ansible.module_utils.basic import AnsibleModule 66 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 67 | DigitalOceanCommonModule, 68 | DigitalOceanOptions, 69 | DigitalOceanFunctions, 70 | ) 71 | 72 | 73 | class TagsInformation(DigitalOceanCommonModule): 74 | def __init__(self, module): 75 | super().__init__(module) 76 | if self.state == "present": 77 | self.present() 78 | 79 | def present(self): 80 | tags = DigitalOceanFunctions.get_paginated( 81 | module=self.module, 82 | obj=self.client.tags, 83 | meth="list", 84 | key="tags", 85 | exc=DigitalOceanCommonModule.HttpResponseError, 86 | ) 87 | if tags: 88 | self.module.exit_json( 89 | changed=False, 90 | msg="Current tags", 91 | tags=tags, 92 | ) 93 | self.module.exit_json(changed=False, msg="No tags", tags=[]) 94 | 95 | 96 | def main(): 97 | argument_spec = DigitalOceanOptions.argument_spec() 98 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 99 | TagsInformation(module) 100 | 101 | 102 | if __name__ == "__main__": 103 | main() 104 | -------------------------------------------------------------------------------- /plugins/modules/vpcs_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright: (c) 2023, Mark Mercado 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | 11 | DOCUMENTATION = r""" 12 | --- 13 | module: vpcs_info 14 | 15 | short_description: List all of the VPCs on your account 16 | 17 | version_added: 0.2.0 18 | 19 | description: 20 | - List all of the VPCs on your account. 21 | - View the API documentation at U(https://docs.digitalocean.com/reference/api/api-reference/#operation/vpcs_list). 22 | 23 | author: Mark Mercado (@mamercad) 24 | 25 | requirements: 26 | - pydo >= 0.1.3 27 | - azure-core >= 1.26.1 28 | 29 | extends_documentation_fragment: 30 | - digitalocean.cloud.common.documentation 31 | """ 32 | 33 | 34 | EXAMPLES = r""" 35 | - name: Get VPCs 36 | digitalocean.cloud.vpcs_info: 37 | token: "{{ token }}" 38 | """ 39 | 40 | 41 | RETURN = r""" 42 | vpcs: 43 | description: VPCs. 44 | returned: always 45 | type: list 46 | elements: dict 47 | sample: 48 | - created_at: '2021-11-05T21:48:35Z' 49 | default: true 50 | description: '' 51 | id: 30f86d25-414e-434f-852d-993ed8d6815e 52 | ip_range: 10.108.0.0/20 53 | name: default-nyc3 54 | region: nyc3 55 | urn: do:vpc:30f86d25-414e-434f-852d-993ed8d6815e 56 | error: 57 | description: DigitalOcean API error. 58 | returned: failure 59 | type: dict 60 | sample: 61 | Message: Informational error message. 62 | Reason: Unauthorized 63 | Status Code: 401 64 | msg: 65 | description: VPCs kresult information. 66 | returned: always 67 | type: str 68 | sample: 69 | - Current volumes 70 | - No volumes 71 | """ 72 | 73 | from ansible.module_utils.basic import AnsibleModule 74 | from ansible_collections.digitalocean.cloud.plugins.module_utils.common import ( 75 | DigitalOceanCommonModule, 76 | DigitalOceanOptions, 77 | DigitalOceanFunctions, 78 | ) 79 | 80 | 81 | class VPCsInformation(DigitalOceanCommonModule): 82 | def __init__(self, module): 83 | super().__init__(module) 84 | if self.state == "present": 85 | self.present() 86 | 87 | def present(self): 88 | vpcs = DigitalOceanFunctions.get_paginated( 89 | module=self.module, 90 | obj=self.client.vpcs, 91 | meth="list", 92 | key="vpcs", 93 | exc=DigitalOceanCommonModule.HttpResponseError, 94 | ) 95 | if vpcs: 96 | self.module.exit_json( 97 | changed=False, 98 | msg="Current VPCs", 99 | vpcs=vpcs, 100 | ) 101 | self.module.exit_json(changed=False, msg="No VPCs", vpcs=[]) 102 | 103 | 104 | def main(): 105 | argument_spec = DigitalOceanOptions.argument_spec() 106 | module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) 107 | VPCsInformation(module) 108 | 109 | 110 | if __name__ == "__main__": 111 | main() 112 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "digitalocean" 3 | version = "0.0.1" 4 | description = "Ansible DigitalOcean Collection" 5 | authors = ["Mark Mercado ", "Ari Kalfus "] 6 | license = "GPL-3.0" 7 | readme = "README.md" 8 | package-mode = false 9 | 10 | [tool.poetry.dependencies] 11 | python = "~3.11.11" 12 | ansible-core = "^2.15.12" 13 | azure-core = "^1.30.2" 14 | pydo = "^0.4.0" 15 | boto3 = "^1.34.131" 16 | jmespath = "^1.0.1" 17 | setuptools = "70.1.0" 18 | 19 | [tool.poetry.group.dev.dependencies] 20 | ansible-lint = { version = "^6.22.2", markers = "platform_system != 'Windows'" } 21 | black = "^24.4.2" 22 | pre-commit = "^3.7.1" 23 | pylint = "^3.2.3" 24 | pytest = "^8.2.2" 25 | antsibull-changelog = "^0.29.0" 26 | antsibull-docs = "^2.11.0" 27 | autopep8 = "^2.3.1" 28 | 29 | [build-system] 30 | requires = ["poetry-core"] 31 | build-backend = "poetry.core.masonry.api" 32 | -------------------------------------------------------------------------------- /tests/integration/.gitignore: -------------------------------------------------------------------------------- 1 | integration_config.yml 2 | integration_config.yaml 3 | -------------------------------------------------------------------------------- /tests/integration/integration_config.yml.template: -------------------------------------------------------------------------------- 1 | --- 2 | digitalocean_token: ${DIGITALOCEAN_TOKEN} 3 | aws_access_key_id: ${AWS_ACCESS_KEY_ID} 4 | aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY} 5 | pr_number: ${PR_NUMBER} 6 | -------------------------------------------------------------------------------- /tests/integration/requirements.txt: -------------------------------------------------------------------------------- 1 | azure-core==1.26.1 2 | boto3==1.26.142 3 | jmespath==1.0.1 4 | pydo==0.1.7 5 | -------------------------------------------------------------------------------- /tests/integration/targets/.gitkeep: -------------------------------------------------------------------------------- 1 | This is a placeholder file that only exists to keep the current 2 | directory in Git. It is safe to remove it once this directory contains 3 | the actual test files. 4 | -------------------------------------------------------------------------------- /tests/integration/targets/account_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/account_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/account_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Test block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get account information 13 | digitalocean.cloud.account_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify account information 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.msg == "Current account information" 26 | - result.account is defined 27 | - result.account.droplet_limit is defined 28 | - result.account.email is defined 29 | - result.account.email_verified is defined 30 | - result.account.floating_ip_limit is defined 31 | - result.account.reserved_ip_limit is defined 32 | - result.account.status is defined 33 | - result.account.status_message is defined 34 | - result.account.team is defined 35 | - result.account.team.name is defined 36 | - result.account.team.uuid is defined 37 | - result.account.uuid is defined 38 | - result.account.volume_limit is defined 39 | -------------------------------------------------------------------------------- /tests/integration/targets/balance_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/balance_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/balance_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get balance information 13 | digitalocean.cloud.balance_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify balance information 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.msg == "Current balance information" 26 | - result.balance is defined 27 | - result.balance.account_balance is defined 28 | - result.balance.generated_at is defined 29 | - result.balance.month_to_date_balance is defined 30 | - result.balance.month_to_date_usage is defined 31 | -------------------------------------------------------------------------------- /tests/integration/targets/billing_history_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/billing_history_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/billing_history_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Test block 4 | block: 5 | 6 | - name: Verify API token 7 | ansible.builtin.assert: 8 | that: 9 | - digitalocean_token is string 10 | - digitalocean_token | length > 0 11 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 12 | 13 | - name: Get billing history information 14 | digitalocean.cloud.billing_history_info: 15 | token: "{{ digitalocean_token }}" 16 | register: result 17 | 18 | - name: No billing history block 19 | when: result.msg == "No billing history information" 20 | block: 21 | - name: Verify no billing history information 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | 26 | - name: Current billing history information block 27 | when: result.msg == "Current billing history information" 28 | block: 29 | - name: Verify current billing history information 30 | ansible.builtin.assert: 31 | that: 32 | - not result.changed 33 | - result.billing_history is list 34 | -------------------------------------------------------------------------------- /tests/integration/targets/cdn_endpoints/aliases: -------------------------------------------------------------------------------- 1 | disabled 2 | -------------------------------------------------------------------------------- /tests/integration/targets/cdn_endpoints/defaults/main.yml: -------------------------------------------------------------------------------- 1 | endpoint: ansible-gh-ci-space-0.nyc3.cdn.digitaloceanspaces.com 2 | origin: ansible-gh-ci-space-0.nyc3.digitaloceanspaces.com 3 | -------------------------------------------------------------------------------- /tests/integration/targets/cdn_endpoints_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/cdn_endpoints_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/cdn_endpoints_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get CDN endpoints 13 | digitalocean.cloud.cdn_endpoints_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify CDN endpoints 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.endpoints is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/certificate/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/certificate/aliases -------------------------------------------------------------------------------- /tests/integration/targets/certificates_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/certificates_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/certificates_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get certificates 13 | digitalocean.cloud.certificates_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify certificates 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.certificates is iterable 26 | -------------------------------------------------------------------------------- /tests/integration/targets/container_registry_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/container_registry_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/container_registry_info/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/container_registry_info/tasks/01_get.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_get | Testing block 4 | block: 5 | - name: 01_get | Get Container Registry 6 | when: true 7 | digitalocean.cloud.container_registry_info: 8 | token: "{{ digitalocean_token }}" 9 | register: result 10 | 11 | - name: 01_get | Verify get Container Registry structure when exists 12 | when: result.msg == "Current container registry" 13 | ansible.builtin.assert: 14 | that: 15 | - not result.changed 16 | - result.registry is mapping 17 | - result.registry.created_at is string 18 | - result.registry.name is string 19 | - result.registry.read_only is boolean 20 | - result.registry.region is string 21 | - result.registry.storage_usage_bytes is number 22 | - result.registry.storage_usage_updated_at is string 23 | 24 | - name: 01_get | Verify get Container Registry structure when not exists 25 | when: result.msg == "No container registry" 26 | ansible.builtin.assert: 27 | that: 28 | - not result.changed 29 | - result.registry == {} 30 | -------------------------------------------------------------------------------- /tests/integration/targets/container_registry_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Get 10 | ansible.builtin.include_tasks: 11 | file: 01_get.yml 12 | -------------------------------------------------------------------------------- /tests/integration/targets/database_cluster/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/database_cluster/aliases -------------------------------------------------------------------------------- /tests/integration/targets/database_cluster/defaults/main.yml: -------------------------------------------------------------------------------- 1 | region: nyc3 2 | size: db-s-1vcpu-2gb 3 | engine: valkey 4 | database_name: ansible-gh-ci-valkey-0 5 | num_nodes: 1 6 | -------------------------------------------------------------------------------- /tests/integration/targets/database_cluster/tasks/01_create_delete_valkey.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_create_delete_valkey | Testing block 4 | block: 5 | - name: 01_create_delete_valkey | Create database cluster 6 | digitalocean.cloud.database_cluster: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ database_name }}" 10 | region: "{{ region }}" 11 | engine: "{{ engine }}" 12 | size: "{{ size }}" 13 | num_nodes: "{{ num_nodes }}" 14 | timeout: 600 15 | register: result 16 | 17 | - name: 01_create_delete_valkey | Verify create database cluster 18 | ansible.builtin.assert: 19 | that: 20 | - result.changed 21 | - result.msg == "Created " ~ engine ~ " database cluster " ~ database_name ~ " (" ~ result.database.id ~ ") in " ~ region 22 | - result.database.name == database_name 23 | - result.database.engine == engine 24 | - result.database.num_nodes == num_nodes 25 | - result.database.region == region 26 | 27 | - name: 01_create_delete_valkey | Create database cluster again 28 | digitalocean.cloud.database_cluster: 29 | state: present 30 | token: "{{ digitalocean_token }}" 31 | name: "{{ database_name }}" 32 | region: "{{ region }}" 33 | engine: "{{ engine }}" 34 | size: "{{ size }}" 35 | num_nodes: "{{ num_nodes }}" 36 | register: result 37 | 38 | - name: 01_create_delete_valkey | Verify create database cluster idempotency 39 | ansible.builtin.assert: 40 | that: 41 | - not result.changed 42 | - result.msg == engine ~ " database cluster " ~ database_name ~ " (" ~ result.database.id ~ ") in " ~ region ~ " exists" 43 | 44 | - name: 01_create_delete_valkey | Delete database cluster 45 | digitalocean.cloud.database_cluster: 46 | state: absent 47 | token: "{{ digitalocean_token }}" 48 | name: "{{ database_name }}" 49 | region: "{{ region }}" 50 | engine: "{{ engine }}" 51 | register: result 52 | 53 | - name: 01_create_delete_valkey | Verify delete database cluster 54 | ansible.builtin.assert: 55 | that: 56 | - result.changed 57 | - result.msg == "Deleted " ~ engine ~ " database cluster " ~ database_name ~ " (" ~ result.database.id ~ ") in " ~ region 58 | -------------------------------------------------------------------------------- /tests/integration/targets/database_cluster/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 99_teardown | Testing block 4 | block: 5 | - name: 99_teardown | Delete database cluster 6 | digitalocean.cloud.database_cluster: 7 | state: absent 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ database_name }}" 10 | region: "{{ region }}" 11 | engine: "{{ engine }}" 12 | timeout: 600 13 | -------------------------------------------------------------------------------- /tests/integration/targets/database_cluster/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | 6 | - name: Verify API token 7 | ansible.builtin.assert: 8 | that: 9 | - digitalocean_token is string 10 | - digitalocean_token | length > 0 11 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 12 | 13 | - name: Test database | Create and delete valkey 14 | ansible.builtin.include_tasks: 15 | file: 01_create_delete_valkey.yml 16 | 17 | always: 18 | - name: Teardown 19 | ansible.builtin.include_tasks: 20 | file: 99_teardown.yml 21 | -------------------------------------------------------------------------------- /tests/integration/targets/database_clusters_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/database_clusters_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/database_clusters_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get database clusters 13 | digitalocean.cloud.database_clusters_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify database clusters 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.databases is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/domain/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/domain/aliases -------------------------------------------------------------------------------- /tests/integration/targets/domain/defaults/main.yml: -------------------------------------------------------------------------------- 1 | domain_name: "ansible-gh-ci-domain-0-{{ pr_number }}.cloud" 2 | -------------------------------------------------------------------------------- /tests/integration/targets/domain/tasks/01_create_and_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create domain 6 | digitalocean.cloud.domain: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ domain_name }}" 10 | register: result 11 | 12 | - name: Verify create domain 13 | ansible.builtin.assert: 14 | that: 15 | - result.changed 16 | - result.msg == "Created domain " ~ domain_name 17 | - result.domain.name == domain_name 18 | - result.domain.ttl is defined 19 | - result.domain.zone_file is defined 20 | 21 | - name: Sleep for a minute 22 | ansible.builtin.pause: 23 | minutes: 1 24 | 25 | - name: Delete domain 26 | digitalocean.cloud.domain: 27 | token: "{{ digitalocean_token }}" 28 | state: absent 29 | name: "{{ domain_name }}" 30 | register: result 31 | 32 | - name: Verify create domain 33 | ansible.builtin.assert: 34 | that: 35 | - result.changed 36 | - result.msg == "Deleted domain " ~ domain_name 37 | - result.domain == [] 38 | 39 | always: 40 | 41 | - name: Cleanup domain | Leftover from unexpected failure 42 | digitalocean.cloud.domain: 43 | token: "{{ digitalocean_token }}" 44 | state: absent 45 | name: "{{ domain_name }}" 46 | ignore_errors: true 47 | -------------------------------------------------------------------------------- /tests/integration/targets/domain/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test domain | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_and_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_record/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/domain_record/aliases -------------------------------------------------------------------------------- /tests/integration/targets/domain_record/defaults/main.yml: -------------------------------------------------------------------------------- 1 | domain_name: "ansible-gh-ci-domain-0-{{ pr_number }}.do.letsbuildthe.cloud" 2 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_record/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create domain 6 | digitalocean.cloud.domain: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ domain_name }}" 10 | register: result 11 | 12 | - name: Verify create domain 13 | ansible.builtin.assert: 14 | that: 15 | - result.changed 16 | - result.msg == "Created domain " ~ domain_name 17 | - result.domain.name == domain_name 18 | - result.domain.ttl is defined 19 | - result.domain.zone_file is defined 20 | 21 | - name: Sleep for a few seconds 22 | ansible.builtin.pause: 23 | seconds: 10 24 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_record/tasks/01_create_and_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create domain record 6 | digitalocean.cloud.domain_record: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | domain_name: "{{ domain_name }}" 10 | name: www 11 | type: A 12 | data: 192.168.100.50 13 | register: result 14 | 15 | - name: Verify create domain record 16 | ansible.builtin.assert: 17 | that: 18 | - result.changed 19 | - result.msg == "Created domain record www A in " ~ domain_name 20 | - result.domain_record.name == "www" 21 | - result.domain_record.type == "A" 22 | - result.domain_record.data == "192.168.100.50" 23 | 24 | - name: Sleep for a few seconds 25 | ansible.builtin.pause: 26 | seconds: 10 27 | 28 | - name: Delete domain record 29 | digitalocean.cloud.domain_record: 30 | token: "{{ digitalocean_token }}" 31 | state: absent 32 | domain_name: "{{ domain_name }}" 33 | name: www 34 | type: A 35 | data: 192.168.100.50 36 | register: result 37 | 38 | - name: Verify create domain record 39 | ansible.builtin.assert: 40 | that: 41 | - result.changed 42 | - result.msg == "Deleted domain record www A (" ~ result.domain_record.id ~ ") in " ~ domain_name 43 | - result.domain_record.name == "www" 44 | - result.domain_record.type == "A" 45 | - result.domain_record.data == "192.168.100.50" 46 | 47 | - name: Sleep for a few seconds 48 | ansible.builtin.pause: 49 | seconds: 10 50 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_record/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Delete domain 6 | digitalocean.cloud.domain: 7 | token: "{{ digitalocean_token }}" 8 | state: absent 9 | name: "{{ domain_name }}" 10 | register: result 11 | 12 | - name: Verify delete domain 13 | ansible.builtin.assert: 14 | that: 15 | - result.changed 16 | - result.msg == "Deleted domain " ~ domain_name 17 | - result.domain == [] 18 | 19 | always: 20 | 21 | - name: Delete domain | Leftover from unexpected failure 22 | digitalocean.cloud.domain: 23 | token: "{{ digitalocean_token }}" 24 | state: absent 25 | name: "{{ domain_name }}" 26 | ignore_errors: true 27 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_record/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Setup | Create domain 13 | ansible.builtin.include_tasks: 14 | file: 00_setup.yml 15 | 16 | - name: Test domain | Create and delete 17 | ansible.builtin.include_tasks: 18 | file: 01_create_and_delete.yml 19 | 20 | - name: Teardown | Delete domain 21 | ansible.builtin.include_tasks: 22 | file: 99_teardown.yml 23 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_records_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/domain_records_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/domain_records_info/defaults/main.yml: -------------------------------------------------------------------------------- 1 | domain_name: do.letsbuildthe.cloud 2 | -------------------------------------------------------------------------------- /tests/integration/targets/domain_records_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get domain records 13 | digitalocean.cloud.domain_records_info: 14 | token: "{{ digitalocean_token }}" 15 | domain_name: "{{ domain_name }}" 16 | register: result 17 | 18 | - name: Verify domain records 19 | ansible.builtin.assert: 20 | that: 21 | - not result.changed 22 | - result.msg is string 23 | - result.domain_records is iterable 24 | -------------------------------------------------------------------------------- /tests/integration/targets/domains_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/domains_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/domains_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get domains 13 | digitalocean.cloud.domains_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify domains 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.domains is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/droplet/aliases -------------------------------------------------------------------------------- /tests/integration/targets/droplet/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | droplet_name: "ansible-gh-ci-droplet-0-{{ pr_number }}" 4 | droplet_region: nyc3 5 | droplet_size: s-1vcpu-2gb 6 | droplet_bigger_size: s-2vcpu-4gb 7 | droplet_resize: true 8 | droplet_resize_disk: true 9 | droplet_image: ubuntu-22-04-x64 10 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/tasks/02_resize_noop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_resize_noop | Testing block 4 | block: 5 | - name: 02_resize_noop | Create Droplet 6 | digitalocean.cloud.droplet: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | size: "{{ droplet_size }}" 12 | resize: false 13 | resize_disk: false 14 | image: "{{ droplet_image }}" 15 | unique_name: true 16 | register: result 17 | 18 | - name: 02_resize_noop | Verify create Droplet 19 | ansible.builtin.assert: 20 | that: 21 | - result.changed 22 | - result.msg is string 23 | - result.droplet is iterable 24 | - result.droplet.id is integer 25 | - result.droplet.name == droplet_name 26 | - result.droplet.region.slug == droplet_region 27 | - result.droplet.size.slug == droplet_size 28 | - result.msg == "Created Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 29 | 30 | - name: 02_resize_noop | Resize Droplet (no size change) 31 | digitalocean.cloud.droplet: 32 | token: "{{ digitalocean_token }}" 33 | state: present 34 | name: "{{ droplet_name }}" 35 | region: "{{ droplet_region }}" 36 | size: "{{ droplet_size }}" 37 | resize: true 38 | resize_disk: true 39 | image: "{{ droplet_image }}" 40 | unique_name: true 41 | register: result 42 | 43 | - name: 02_resize_noop | Verify resize Droplet (no size change) 44 | ansible.builtin.assert: 45 | that: 46 | - not result.changed 47 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") is already size " ~ droplet_size 48 | 49 | - name: 02_resize_noop | Delete Droplet 50 | digitalocean.cloud.droplet: 51 | token: "{{ digitalocean_token }}" 52 | state: absent 53 | name: "{{ droplet_name }}" 54 | region: "{{ droplet_region }}" 55 | unique_name: true 56 | register: result 57 | 58 | - name: 02_resize_noop | Verify delete Droplet 59 | ansible.builtin.assert: 60 | that: 61 | - result.changed 62 | - result.msg is string 63 | - result.msg == "Deleted Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 64 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/tasks/03_resize_new.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 03_resize_new | Testing block 4 | block: 5 | - name: 03_resize_new | Create Droplet 6 | digitalocean.cloud.droplet: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | size: "{{ droplet_size }}" 12 | resize: true 13 | resize_disk: true 14 | image: "{{ droplet_image }}" 15 | unique_name: true 16 | register: result 17 | 18 | - name: 03_resize_new | Verify create Droplet 19 | ansible.builtin.assert: 20 | that: 21 | - result.changed 22 | - result.msg is string 23 | - result.droplet is iterable 24 | - result.droplet.id is integer 25 | - result.droplet.name == droplet_name 26 | - result.droplet.region.slug == droplet_region 27 | - result.droplet.size.slug == droplet_size 28 | - result.msg == "Created Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 29 | 30 | - name: 03_resize_new | Resize Droplet 31 | digitalocean.cloud.droplet: 32 | token: "{{ digitalocean_token }}" 33 | state: present 34 | name: "{{ droplet_name }}" 35 | region: "{{ droplet_region }}" 36 | size: "{{ droplet_bigger_size }}" 37 | resize: true 38 | resize_disk: true 39 | image: "{{ droplet_image }}" 40 | unique_name: true 41 | register: result 42 | 43 | - name: 03_resize_new | Verify resize Droplet 44 | ansible.builtin.assert: 45 | that: 46 | - result.changed 47 | - result.msg == "Resized Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " 48 | ~ droplet_region ~ " from size " ~ droplet_size ~ " to size " ~ droplet_bigger_size 49 | 50 | - name: 04_resize_bigger | Delete Droplet 51 | digitalocean.cloud.droplet: 52 | token: "{{ digitalocean_token }}" 53 | state: absent 54 | name: "{{ droplet_name }}" 55 | region: "{{ droplet_region }}" 56 | unique_name: true 57 | register: result 58 | 59 | - name: 04_resize_bigger | Verify delete Droplet 60 | ansible.builtin.assert: 61 | that: 62 | - result.changed 63 | - result.msg is string 64 | - result.msg == "Deleted Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 65 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/tasks/04_resize_bigger.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 04_resize_bigger | Testing block 4 | block: 5 | - name: 04_resize_bigger | Create Droplet 6 | digitalocean.cloud.droplet: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | size: "{{ droplet_size }}" 12 | resize: false 13 | resize_disk: false 14 | image: "{{ droplet_image }}" 15 | unique_name: true 16 | register: result 17 | 18 | - name: 04_resize_bigger | Verify create Droplet 19 | ansible.builtin.assert: 20 | that: 21 | - result.changed 22 | - result.msg is string 23 | - result.droplet is iterable 24 | - result.droplet.id is integer 25 | - result.droplet.name == droplet_name 26 | - result.droplet.region.slug == droplet_region 27 | - result.droplet.size.slug == droplet_size 28 | - result.msg == "Created Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 29 | 30 | - name: 04_resize_bigger | Resize Droplet 31 | digitalocean.cloud.droplet: 32 | token: "{{ digitalocean_token }}" 33 | state: present 34 | name: "{{ droplet_name }}" 35 | region: "{{ droplet_region }}" 36 | size: "{{ droplet_bigger_size }}" 37 | resize: true 38 | resize_disk: true 39 | image: "{{ droplet_image }}" 40 | unique_name: true 41 | register: result 42 | 43 | - name: 04_resize_bigger | Verify resize Droplet 44 | ansible.builtin.assert: 45 | that: 46 | - result.changed 47 | - result.msg == "Resized Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " 48 | ~ droplet_region ~ " from size " ~ droplet_size ~ " to size " ~ droplet_bigger_size 49 | 50 | - name: 04_resize_bigger | Delete Droplet 51 | digitalocean.cloud.droplet: 52 | token: "{{ digitalocean_token }}" 53 | state: absent 54 | name: "{{ droplet_name }}" 55 | region: "{{ droplet_region }}" 56 | unique_name: true 57 | register: result 58 | 59 | - name: 04_resize_bigger | Verify delete Droplet 60 | ansible.builtin.assert: 61 | that: 62 | - result.changed 63 | - result.msg is string 64 | - result.msg == "Deleted Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 65 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/tasks/05_resize_smaller.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 05_resize_smaller | Testing block 4 | block: 5 | - name: 05_resize_smaller | Create Droplet 6 | digitalocean.cloud.droplet: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | size: "{{ droplet_bigger_size }}" 12 | resize: false 13 | resize_disk: false 14 | image: "{{ droplet_image }}" 15 | unique_name: true 16 | register: result 17 | 18 | - name: 05_resize_smaller | Verify create Droplet 19 | ansible.builtin.assert: 20 | that: 21 | - result.changed 22 | - result.msg is string 23 | - result.droplet is iterable 24 | - result.droplet.id is integer 25 | - result.droplet.name == droplet_name 26 | - result.droplet.region.slug == droplet_region 27 | - result.droplet.size.slug == droplet_bigger_size 28 | - result.msg == "Created Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 29 | 30 | - name: Resize smaller block 31 | block: 32 | - name: 05_resize_smaller | Resize Droplet 33 | digitalocean.cloud.droplet: 34 | token: "{{ digitalocean_token }}" 35 | state: present 36 | name: "{{ droplet_name }}" 37 | region: "{{ droplet_region }}" 38 | size: "{{ droplet_size }}" 39 | resize: true 40 | resize_disk: true 41 | image: "{{ droplet_image }}" 42 | unique_name: true 43 | register: result 44 | 45 | rescue: 46 | - name: 05_resize_smaller | Ensure blah blah 47 | ansible.builtin.assert: 48 | that: 49 | - not result.changed 50 | - result.failed 51 | - "'This size is not available because it has a smaller disk' in result.msg" 52 | 53 | - name: 05_resize_smaller | Delete Droplet 54 | digitalocean.cloud.droplet: 55 | token: "{{ digitalocean_token }}" 56 | state: absent 57 | name: "{{ droplet_name }}" 58 | region: "{{ droplet_region }}" 59 | unique_name: true 60 | register: result 61 | 62 | - name: 05_resize_smaller | Verify delete Droplet 63 | ansible.builtin.assert: 64 | that: 65 | - result.changed 66 | - result.msg is string 67 | - result.msg == "Deleted Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ droplet_region 68 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 99_teardown | Testing block 4 | block: 5 | - name: 99_teardown | Delete Droplet 6 | digitalocean.cloud.droplet: 7 | state: absent 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | unique_name: true 12 | 13 | rescue: 14 | - name: 99_teardown | All tests passed, no cleanup needed 15 | ansible.builtin.debug: 16 | msg: "All tests passed, no cleanup needed" 17 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Create and delete with unique name and region 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete_unique_name_and_region.yml 15 | 16 | - name: Create and resize noop 17 | ansible.builtin.include_tasks: 18 | file: 02_resize_noop.yml 19 | 20 | - name: Create and resize new 21 | ansible.builtin.include_tasks: 22 | file: 03_resize_new.yml 23 | 24 | - name: Create and resize existing 25 | ansible.builtin.include_tasks: 26 | file: 04_resize_bigger.yml 27 | 28 | - name: Create and resize smaller 29 | ansible.builtin.include_tasks: 30 | file: 05_resize_smaller.yml 31 | 32 | always: 33 | - name: Teardown 34 | ansible.builtin.include_tasks: 35 | file: 99_teardown.yml 36 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/droplet_action_power/aliases -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | droplet_name: "ansible-gh-ci-droplet-6-{{ pr_number }}" 4 | droplet_region: nyc3 5 | droplet_size: s-1vcpu-2gb 6 | droplet_image: ubuntu-22-04-x64 7 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Create Droplet 6 | digitalocean.cloud.droplet: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | size: "{{ droplet_size }}" 12 | image: "{{ droplet_image }}" 13 | unique_name: true 14 | register: droplet 15 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/tasks/01_power_off.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_power_off | Testing block 4 | block: 5 | - name: 01_power_off | Power off Droplet 6 | when: true 7 | digitalocean.cloud.droplet_action_power: 8 | token: "{{ digitalocean_token }}" 9 | state: power_off 10 | name: "{{ droplet_name }}" 11 | region: "{{ droplet_region }}" 12 | register: result 13 | 14 | - name: 01_power_off | Verify power off Droplet 15 | ansible.builtin.assert: 16 | that: 17 | - result.changed 18 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " sent action 'power_off'" 19 | 20 | - name: 01_power_off | Power off Droplet again 21 | when: true 22 | digitalocean.cloud.droplet_action_power: 23 | token: "{{ digitalocean_token }}" 24 | state: power_off 25 | name: "{{ droplet_name }}" 26 | region: "{{ droplet_region }}" 27 | register: result 28 | 29 | - name: 01_power_off | Verify power off Droplet idemopotency 30 | ansible.builtin.assert: 31 | that: 32 | - not result.changed 33 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " not sent action 'power_off', it is 'off'" 34 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/tasks/02_power_on.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_power_on | Testing block 4 | block: 5 | - name: 02_power_on | Power on Droplet 6 | when: true 7 | digitalocean.cloud.droplet_action_power: 8 | token: "{{ digitalocean_token }}" 9 | state: power_on 10 | name: "{{ droplet_name }}" 11 | region: "{{ droplet_region }}" 12 | register: result 13 | 14 | - name: 02_power_on | Verify power on Droplet 15 | ansible.builtin.assert: 16 | that: 17 | - result.changed 18 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " sent action 'power_on'" 19 | 20 | - name: 02_power_on | Power on Droplet again 21 | when: true 22 | digitalocean.cloud.droplet_action_power: 23 | token: "{{ digitalocean_token }}" 24 | state: power_on 25 | name: "{{ droplet_name }}" 26 | region: "{{ droplet_region }}" 27 | register: result 28 | 29 | - name: 02_power_on | Verify power on Droplet idemopotency 30 | ansible.builtin.assert: 31 | that: 32 | - not result.changed 33 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " not sent action 'power_on', it is 'active'" 34 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/tasks/03_shutdown.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 03_shutdown | Outer testing block 4 | block: 5 | - name: 03_shutdown | Inner testing block 6 | block: 7 | - name: 03_shutdown | Shut down Droplet 8 | when: true 9 | digitalocean.cloud.droplet_action_power: 10 | token: "{{ digitalocean_token }}" 11 | state: shutdown 12 | force_power_off: false 13 | name: "{{ droplet_name }}" 14 | region: "{{ droplet_region }}" 15 | register: result 16 | 17 | - name: 03_shutdown | Verify shut down Droplet 18 | ansible.builtin.assert: 19 | that: 20 | - result.changed 21 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " sent action 'shutdown'" 22 | 23 | - name: 03_shutdown | Shut down Droplet again 24 | when: true 25 | digitalocean.cloud.droplet_action_power: 26 | token: "{{ digitalocean_token }}" 27 | state: shutdown 28 | force_power_off: false 29 | name: "{{ droplet_name }}" 30 | region: "{{ droplet_region }}" 31 | register: result 32 | 33 | - name: 03_shutdown | Verify shut down Droplet idemopotency 34 | ansible.builtin.assert: 35 | that: 36 | - not result.changed 37 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " not sent action 'shutdown', it is 'off'" 38 | 39 | rescue: 40 | - name: 03_shutdown | Inner testing block rescue block 41 | block: 42 | - name: 03_shutdown | Shut down failed - forcing 43 | when: true 44 | digitalocean.cloud.droplet_action_power: 45 | token: "{{ digitalocean_token }}" 46 | state: shutdown 47 | force_power_off: true 48 | name: "{{ droplet_name }}" 49 | region: "{{ droplet_region }}" 50 | register: result 51 | 52 | - name: 03_shutdown | Verify shut down Droplet force power off 53 | ansible.builtin.assert: 54 | that: 55 | - result.changed 56 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ droplet.droplet.id ~ ") in " ~ droplet_region ~ " sent action 'shutdown'" 57 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 99_teardown | Testing block 4 | block: 5 | - name: 99_teardown | Delete Droplet 6 | digitalocean.cloud.droplet: 7 | state: absent 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | unique_name: true 12 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_power/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Setup 13 | ansible.builtin.include_tasks: 14 | file: 00_setup.yml 15 | 16 | - name: Power off 17 | ansible.builtin.include_tasks: 18 | file: 01_power_off.yml 19 | 20 | - name: Power on 21 | ansible.builtin.include_tasks: 22 | file: 02_power_on.yml 23 | 24 | - name: Shut down 25 | ansible.builtin.include_tasks: 26 | file: 03_shutdown.yml 27 | 28 | always: 29 | - name: Teardown 30 | ansible.builtin.include_tasks: 31 | file: 99_teardown.yml 32 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_resize/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/droplet_action_resize/aliases -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_resize/defaults/main.yml: -------------------------------------------------------------------------------- 1 | droplet_name: "ansible-gh-ci-droplet-8-{{ pr_number }}" 2 | droplet_region: nyc3 3 | droplet_size: s-1vcpu-2gb 4 | droplet_bigger_size: s-2vcpu-4gb 5 | droplet_image: ubuntu-22-04-x64 6 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_resize/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: 00_setup | Testing block 3 | block: 4 | - name: 00_setup | Create Droplet 5 | digitalocean.cloud.droplet: 6 | token: "{{ digitalocean_token }}" 7 | state: present 8 | name: "{{ droplet_name }}" 9 | region: "{{ droplet_region }}" 10 | size: "{{ droplet_size }}" 11 | image: "{{ droplet_image }}" 12 | unique_name: true 13 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_resize/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: 99_teardown | Testing block 3 | block: 4 | - name: 99_teardown | Delete Droplet 5 | digitalocean.cloud.droplet: 6 | state: absent 7 | token: "{{ digitalocean_token }}" 8 | name: "{{ droplet_name }}" 9 | region: "{{ droplet_region }}" 10 | unique_name: true 11 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_resize/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Setup 13 | ansible.builtin.include_tasks: 14 | file: 00_setup.yml 15 | 16 | - name: Resize 17 | ansible.builtin.include_tasks: 18 | file: 01_resize.yml 19 | 20 | always: 21 | - name: Teardown 22 | ansible.builtin.include_tasks: 23 | file: 99_teardown.yml 24 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_snapshot/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/droplet_action_snapshot/aliases -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_snapshot/defaults/main.yml: -------------------------------------------------------------------------------- 1 | droplet_name: "ansible-gh-ci-droplet-1-{{ pr_number }}" 2 | droplet_region: nyc3 3 | droplet_size: s-1vcpu-2gb 4 | droplet_image: ubuntu-22-04-x64 5 | 6 | snapshot_name: "ansible-gh-ci-droplet-snapshot-1-{{ pr_number }}" 7 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_snapshot/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: 00_setup | Testing block 3 | block: 4 | - name: 00_setup | Create Droplet 5 | digitalocean.cloud.droplet: 6 | token: "{{ digitalocean_token }}" 7 | state: present 8 | name: "{{ droplet_name }}" 9 | region: "{{ droplet_region }}" 10 | size: "{{ droplet_size }}" 11 | image: "{{ droplet_image }}" 12 | unique_name: true 13 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_snapshot/tasks/01_snapshot.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: 01_snapshot | Testing block 3 | block: 4 | - name: 01_snapshot | Create Droplet snapshot 5 | when: true 6 | digitalocean.cloud.droplet_action_snapshot: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ droplet_name }}" 10 | region: "{{ droplet_region }}" 11 | snapshot_name: "{{ snapshot_name }}" 12 | timeout: 600 13 | register: result 14 | 15 | - name: 01_snapshot | Verify create Droplet snapshot 16 | ansible.builtin.assert: 17 | that: 18 | - result.changed 19 | - result.msg == "Droplet " ~ droplet_name ~ " (" ~ result.action.resource_id ~ ") in " ~ droplet_region ~ " sent action 'snapshot'" 20 | 21 | - name: 01_snapshot | Delete snapshot 22 | when: true 23 | digitalocean.cloud.snapshot: 24 | token: "{{ digitalocean_token }}" 25 | state: absent 26 | snapshot_name: "{{ snapshot_name }}" 27 | register: result 28 | 29 | - name: 01_snapshot | Verify delete snapshot 30 | ansible.builtin.assert: 31 | that: 32 | - result.changed 33 | - result.msg == "Deleted snapshot " ~ result.snapshot.id 34 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_snapshot/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: 99_teardown | Testing block 3 | block: 4 | - name: 99_teardown | Delete Droplet 5 | digitalocean.cloud.droplet: 6 | state: absent 7 | token: "{{ digitalocean_token }}" 8 | name: "{{ droplet_name }}" 9 | region: "{{ droplet_region }}" 10 | unique_name: true 11 | 12 | - name: 01_snapshot | Delete snapshot 13 | when: true 14 | digitalocean.cloud.snapshot: 15 | token: "{{ digitalocean_token }}" 16 | state: absent 17 | snapshot_name: "{{ snapshot_name }}" 18 | register: result 19 | # NOTE: Might be deleted already 20 | ignore_errors: true # noqa ignore-errors 21 | -------------------------------------------------------------------------------- /tests/integration/targets/droplet_action_snapshot/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Setup 13 | ansible.builtin.include_tasks: 14 | file: 00_setup.yml 15 | 16 | - name: Snapshot 17 | ansible.builtin.include_tasks: 18 | file: 01_snapshot.yml 19 | 20 | always: 21 | - name: Teardown 22 | ansible.builtin.include_tasks: 23 | file: 99_teardown.yml 24 | -------------------------------------------------------------------------------- /tests/integration/targets/droplets_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/droplets_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/droplets_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get Droplets 13 | digitalocean.cloud.droplets_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify Droplets 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.droplets is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/firewall/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/firewall/aliases -------------------------------------------------------------------------------- /tests/integration/targets/firewall/defaults/main.yml: -------------------------------------------------------------------------------- 1 | firewall_name: ansible-gh-ci-firewall-0 2 | inbound_rules: 3 | - protocol: tcp 4 | ports: 80 5 | sources: 6 | addresses: 7 | - "0.0.0.0/0" 8 | - "::/0" 9 | -------------------------------------------------------------------------------- /tests/integration/targets/firewall/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create firewall 6 | digitalocean.cloud.firewall: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ firewall_name }}" 10 | inbound_rules: "{{ inbound_rules }}" 11 | register: result 12 | 13 | - name: Verify create firewall 14 | ansible.builtin.assert: 15 | that: 16 | - result.changed 17 | - result.msg == "Created firewall " ~ firewall_name ~ " (" ~ result.firewall.id ~ ")" 18 | - result.firewall.name == firewall_name 19 | 20 | - name: Delete firewall 21 | digitalocean.cloud.firewall: 22 | token: "{{ digitalocean_token }}" 23 | state: absent 24 | name: "{{ firewall_name }}" 25 | register: result 26 | 27 | - name: Verify delete firewall 28 | ansible.builtin.assert: 29 | that: 30 | - result.changed 31 | - result.msg == "Deleted firewall " ~ firewall_name ~ " (" ~ result.firewall.id ~ ")" 32 | - result.firewall.name == firewall_name 33 | 34 | always: 35 | 36 | - name: Cleanup firewall | Leftover from unexpected failure 37 | digitalocean.cloud.firewall: 38 | token: "{{ digitalocean_token }}" 39 | state: absent 40 | name: "{{ firewall_name }}" 41 | ignore_errors: true 42 | -------------------------------------------------------------------------------- /tests/integration/targets/firewall/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test firewall | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/firewalls_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/firewalls_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/firewalls_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get firewalls 13 | digitalocean.cloud.firewalls_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify firewalls 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.firewalls is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/images_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/images_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/images_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get images 13 | digitalocean.cloud.images_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify images 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.images is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_cluster/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/kubernetes_cluster/aliases -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_cluster/defaults/main.yml: -------------------------------------------------------------------------------- 1 | kubernetes_cluster: 2 | name: "ansible-gh-ci-k8s-{{ pr_number | default(0, true) }}" 3 | region: nyc3 4 | # version: "1.29.1-do.0" 5 | node_pools: 6 | - size: s-2vcpu-4gb 7 | name: ansible-gh-ci-k8s-pool-0 8 | count: 1 9 | -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_cluster/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | # TODO: Create digitalocean.cloud.kubernetes_options_info module 13 | - name: 00_setup | Get Kubernetes options 14 | ansible.builtin.uri: 15 | url: https://api.digitalocean.com/v2/kubernetes/options 16 | method: GET 17 | return_content: true 18 | headers: 19 | Content-Type: "application/json" 20 | Authorization: "Bearer {{ digitalocean_token }}" 21 | register: kubernetes_options 22 | no_log: true 23 | 24 | - name: 00_setup | Set fact for first Kubernetes version 25 | ansible.builtin.set_fact: 26 | kubernetes_version: "{{ kubernetes_options.json | community.general.json_query('options.versions[*].slug') | first }}" 27 | 28 | - name: 00_setup | Ensure Kubernetes version 29 | ansible.builtin.assert: 30 | that: 31 | - kubernetes_version is string 32 | - kubernetes_version | length 33 | -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_cluster/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_create_delete | Testing block 4 | block: 5 | - name: 01_create_delete | Create Kubernetes cluster 6 | digitalocean.cloud.kubernetes_cluster: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ kubernetes_cluster.name }}" 10 | region: "{{ kubernetes_cluster.region }}" 11 | version: "{{ kubernetes_version }}" 12 | node_pools: "{{ kubernetes_cluster.node_pools }}" 13 | timeout: 600 14 | register: result 15 | 16 | - name: 01_create_delete | Verify create Kubernetes cluster 17 | ansible.builtin.assert: 18 | that: 19 | - result.changed 20 | - result.msg == "Created Kubernetes cluster " ~ kubernetes_cluster.name 21 | ~ " (" ~ result.kubernetes_cluster.id ~ ") in " ~ kubernetes_cluster.region 22 | 23 | - name: 01_create_delete | Create Kubernetes cluster again 24 | digitalocean.cloud.kubernetes_cluster: 25 | state: present 26 | token: "{{ digitalocean_token }}" 27 | name: "{{ kubernetes_cluster.name }}" 28 | region: "{{ kubernetes_cluster.region }}" 29 | version: "{{ kubernetes_version }}" 30 | node_pools: "{{ kubernetes_cluster.node_pools }}" 31 | register: result 32 | 33 | - name: 01_create_delete | Verify create Kubernetes cluster idempotency 34 | ansible.builtin.assert: 35 | that: 36 | - not result.changed 37 | - result.msg == "Kubernetes cluster " ~ kubernetes_cluster.name 38 | ~ " (" ~ result.kubernetes_cluster.id ~ ") in " ~ kubernetes_cluster.region ~ " exists" 39 | 40 | - name: 01_create_delete | Delete Kubernetes cluster 41 | digitalocean.cloud.kubernetes_cluster: 42 | state: absent 43 | token: "{{ digitalocean_token }}" 44 | name: "{{ kubernetes_cluster.name }}" 45 | region: "{{ kubernetes_cluster.region }}" 46 | register: result 47 | 48 | - name: 01_create_delete | Verify delete Kubernetes cluster 49 | ansible.builtin.assert: 50 | that: 51 | - result.changed 52 | - result.msg == "Deleted Kubernetes cluster " ~ kubernetes_cluster.name 53 | ~ " (" ~ result.kubernetes_cluster.id ~ ") in " ~ kubernetes_cluster.region 54 | 55 | - name: 01_create_delete | Delete Kubernetes cluster again 56 | digitalocean.cloud.kubernetes_cluster: 57 | state: absent 58 | token: "{{ digitalocean_token }}" 59 | name: "{{ kubernetes_cluster.name }}" 60 | region: "{{ kubernetes_cluster.region }}" 61 | register: result 62 | 63 | - name: 01_create_delete | Verify delete Kubernetes cluster idempotency 64 | ansible.builtin.assert: 65 | that: 66 | - not result.changed 67 | - result.msg == "Kubernetes cluster " ~ kubernetes_cluster.name ~ " in " 68 | ~ kubernetes_cluster.region ~ " does not exist" 69 | -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_cluster/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 99_teardown | Testing block 4 | block: 5 | - name: 99_teardown | Cleanup Kubernetes cluster | Leftover from unexpected failure 6 | digitalocean.cloud.kubernetes_cluster: 7 | state: absent 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ kubernetes_cluster.name }}" 10 | region: "{{ kubernetes_cluster.region }}" 11 | ignore_errors: true # noqa ignore-errors 12 | -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_cluster/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Test Kubernetes cluster | Create and delete 10 | ansible.builtin.include_tasks: 11 | file: 01_create_delete.yml 12 | 13 | always: 14 | - name: Teardown 15 | ansible.builtin.include_tasks: 16 | file: 99_teardown.yml 17 | -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_clusters_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/kubernetes_clusters_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/kubernetes_clusters_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get Kubernetes clusters 13 | digitalocean.cloud.kubernetes_clusters_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify Kubernetes clusters 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.kubernetes_clusters is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/load_balancer/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/load_balancer/aliases -------------------------------------------------------------------------------- /tests/integration/targets/load_balancer/defaults/main.yml: -------------------------------------------------------------------------------- 1 | droplet: 2 | name: "ansible-gh-ci-droplet-2-{{ pr_number }}" 3 | region: nyc3 4 | size: s-1vcpu-2gb 5 | image: ubuntu-22-04-x64 6 | 7 | load_balancer: 8 | name: ansible-gh-ci-lb-2-{{ pr_number }} 9 | region: nyc3 10 | forwarding_rules: 11 | - entry_protocol: http 12 | entry_port: 80 13 | target_protocol: http 14 | target_port: 80 15 | - entry_protocol: https 16 | entry_port: 443 17 | target_protocol: https 18 | target_port: 443 19 | tls_passthrough: true 20 | disable_lets_encrypt_dns_records: true 21 | http_idle_timeout_seconds: 60 22 | firewall: 23 | deny: 24 | - cidr:1.2.0.0/16 25 | - ip:2.3.4.5 26 | allow: 27 | - ip:1.2.3.4 28 | - cidr:2.3.4.0/24 29 | -------------------------------------------------------------------------------- /tests/integration/targets/load_balancer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test load balancer | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/load_balancers_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/load_balancers_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/load_balancers_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get load balancers 13 | digitalocean.cloud.load_balancers_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify load balancers 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.load_balancers is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/monitoring_alert_policies_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/monitoring_alert_policies_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/monitoring_alert_policies_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get monitoring alert policies 13 | digitalocean.cloud.monitoring_alert_policies_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify monitoring alert policies 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.policies is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/monitoring_alert_policy/aliases: -------------------------------------------------------------------------------- 1 | disabled 2 | -------------------------------------------------------------------------------- /tests/integration/targets/monitoring_alert_policy/defaults/main.yml: -------------------------------------------------------------------------------- 1 | droplet: 2 | name: "ansible-gh-ci-droplet-3-{{ pr_number }}" 3 | region: nyc3 4 | size: s-1vcpu-2gb 5 | image: ubuntu-22-04-x64 6 | 7 | policy: 8 | alerts: 9 | email: 10 | - mmercado@digitalocean.com 11 | function: [] 12 | slack: [] 13 | compare: GreaterThan 14 | description: CPU Alert Testing 15 | enabled: true 16 | entities: [] 17 | tags: 18 | - droplet_tag 19 | type: "v1/insights/droplet/cpu" 20 | value: 80 21 | window: 5m 22 | -------------------------------------------------------------------------------- /tests/integration/targets/monitoring_alert_policy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test monitoring alert policy | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/one_click/aliases: -------------------------------------------------------------------------------- 1 | disabled 2 | -------------------------------------------------------------------------------- /tests/integration/targets/one_click/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | addon_slugs: 4 | - kube-state-metrics 5 | - loki 6 | # NOTE: It's a bit expensive to fire up K8s just for this module, so, we'll 7 | # just test check mode and failure (with an unknown cluster UUID). The DO 8 | # API doesn't give us very much here likely because testing K8s testing 9 | # applications is so complex and variable. If we get a 200 back from the API 10 | # we should also have a message "Successfully kicked off addon job." 11 | cluster_uuid: this-cluster-uuid-does-not-exist 12 | -------------------------------------------------------------------------------- /tests/integration/targets/one_click/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/one_click/tasks/01_check.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_check | Testing block 4 | block: 5 | - name: 01_check | Test check mode 6 | digitalocean.cloud.one_click: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | addon_slugs: "{{ addon_slugs }}" 10 | cluster_uuid: "{{ cluster_uuid }}" 11 | check_mode: true 12 | register: result 13 | 14 | - name: 01_check | Verify check mode 15 | ansible.builtin.assert: 16 | that: 17 | - result.changed 18 | - result.msg == "Would install {{ addon_slugs | join(', ') }} into Kubernetes cluster {{ cluster_uuid }}" 19 | -------------------------------------------------------------------------------- /tests/integration/targets/one_click/tasks/02_fail.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_fail | Testing block 4 | block: 5 | - name: 02_fail | Test fail mode 6 | digitalocean.cloud.one_click: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | addon_slugs: "{{ addon_slugs }}" 10 | cluster_uuid: "{{ cluster_uuid }}" 11 | ignore_errors: true # Expected to fail 12 | register: result 13 | 14 | - name: 02_fail | Verify fail mode 15 | ansible.builtin.assert: 16 | that: 17 | - not result.changed 18 | - result.failed 19 | # NOTE: It feels like the DO API should be a bit more helpful when the cluster UUID is not found 20 | - result.msg == "Server Error" 21 | - result.error.Message == "Server Error" 22 | - result.error.Reason == "Internal Server Error" 23 | - result["error"]["Status Code"] == 500 24 | -------------------------------------------------------------------------------- /tests/integration/targets/one_click/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Check 10 | ansible.builtin.include_tasks: 11 | file: 01_check.yml 12 | 13 | - name: Fail 14 | ansible.builtin.include_tasks: 15 | file: 02_fail.yml 16 | -------------------------------------------------------------------------------- /tests/integration/targets/one_clicks_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/one_clicks_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/one_clicks_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get 1-Click applications 13 | digitalocean.cloud.one_clicks_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify 1-Clicks applications 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.msg == "Current 1-Click applications" 26 | - result.one_clicks is iterable 27 | - result.one_clicks.0.type is string 28 | - result.one_clicks.0.slug is string 29 | 30 | - name: Get Droplet 1-Click applications 31 | digitalocean.cloud.one_clicks_info: 32 | token: "{{ digitalocean_token }}" 33 | type: droplet 34 | register: result 35 | 36 | - name: Verify Droplet 1-Clicks applications 37 | ansible.builtin.assert: 38 | that: 39 | - not result.changed 40 | - result.msg == "Current Droplet 1-Click applications" 41 | - result.one_clicks is iterable 42 | - result.one_clicks.0.type is string 43 | - result.one_clicks.0.slug is string 44 | 45 | - name: Get Kubernetes 1-Click applications 46 | digitalocean.cloud.one_clicks_info: 47 | token: "{{ digitalocean_token }}" 48 | type: kubernetes 49 | register: result 50 | 51 | - name: Verify Kubernetes 1-Clicks applications 52 | ansible.builtin.assert: 53 | that: 54 | - not result.changed 55 | - result.msg == "Current Kubernetes 1-Click applications" 56 | - result.one_clicks is iterable 57 | - result.one_clicks.0.type is string 58 | - result.one_clicks.0.slug is string 59 | -------------------------------------------------------------------------------- /tests/integration/targets/project/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/project/aliases -------------------------------------------------------------------------------- /tests/integration/targets/project/defaults/main.yml: -------------------------------------------------------------------------------- 1 | project_name: ansible-gh-ci-project-{{ pr_number | default(0, true) }} 2 | project_description: My Website API 3 | project_purpose: Service or API 4 | project_environment: Production 5 | -------------------------------------------------------------------------------- /tests/integration/targets/project/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/project/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_create_delete | Testing block 4 | block: 5 | - name: 01_create_delete | Create project 6 | digitalocean.cloud.project: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ project_name }}" 10 | description: "{{ project_description }}" 11 | purpose: "{{ project_purpose }}" 12 | environment: "{{ project_environment }}" 13 | register: result 14 | 15 | - name: 01_create_delete | Verify create Project 16 | ansible.builtin.assert: 17 | that: 18 | - result.changed 19 | - result.msg == "Created project " ~ project_name ~ " (" ~ result.project.id ~ ")" 20 | 21 | - name: 01_create_delete | Create project again 22 | digitalocean.cloud.project: 23 | state: present 24 | token: "{{ digitalocean_token }}" 25 | name: "{{ project_name }}" 26 | description: "{{ project_description }}" 27 | purpose: "{{ project_purpose }}" 28 | environment: "{{ project_environment }}" 29 | register: result 30 | 31 | - name: 01_create_delete | Verify create Project idempotency 32 | ansible.builtin.assert: 33 | that: 34 | - not result.changed 35 | - result.msg == "Project " ~ project_name ~ " (" ~ result.project.id ~ ") exists" 36 | 37 | - name: 01_create_delete | Sleep for a few seconds 38 | ansible.builtin.pause: 39 | seconds: 20 40 | 41 | - name: 01_create_delete | Delete project 42 | digitalocean.cloud.project: 43 | state: absent 44 | token: "{{ digitalocean_token }}" 45 | name: "{{ project_name }}" 46 | register: result 47 | 48 | - name: 01_create_delete | Verify delete Project 49 | ansible.builtin.assert: 50 | that: 51 | - result.changed 52 | - result.msg == "Deleted project " ~ project_name ~ " (" ~ result.project.id ~ ")" 53 | 54 | - name: 01_create_delete | Delete project again 55 | digitalocean.cloud.project: 56 | state: absent 57 | token: "{{ digitalocean_token }}" 58 | name: "{{ project_name }}" 59 | register: result 60 | 61 | - name: 01_create_delete | Verify delete Project idempotency 62 | ansible.builtin.assert: 63 | that: 64 | - not result.changed 65 | - result.msg == "Project " ~ project_name ~ " does not exist" 66 | -------------------------------------------------------------------------------- /tests/integration/targets/project/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Setup 13 | ansible.builtin.include_tasks: 14 | file: 00_setup.yml 15 | 16 | - name: Test Project | Create and delete 17 | ansible.builtin.include_tasks: 18 | file: 01_create_delete.yml 19 | -------------------------------------------------------------------------------- /tests/integration/targets/project_resources_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/project_resources_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/project_resources_info/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | project_ids: 4 | - ac799bee-1627-42c6-ac47-d667279152a6 5 | - 3bd9cfcb-dde9-46f4-9adf-353ed7c6961b 6 | - this-project-should-not-exist 7 | -------------------------------------------------------------------------------- /tests/integration/targets/project_resources_info/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/project_resources_info/tasks/01_get_default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_get_default | Testing block 4 | block: 5 | - name: 01_get_default | Get project resources 6 | digitalocean.cloud.project_resources_info: 7 | token: "{{ digitalocean_token }}" 8 | register: result 9 | 10 | - name: 01_get_default | Verify project resources structure when no resources 11 | when: result.project_resources | length == 0 12 | ansible.builtin.assert: 13 | that: 14 | - not result.changed 15 | - result.msg == "No project resources" 16 | - result.project_resources == [] 17 | 18 | - name: 01_get_default | Verify project resources structure when resources 19 | when: result.project_resources | length > 0 20 | ansible.builtin.assert: 21 | that: 22 | - not result.changed 23 | - result.msg == "Current project resources" 24 | - result.project_resources[0] is mapping 25 | - result.project_resources[0].assigned_at is string 26 | - result.project_resources[0].links is mapping 27 | - result.project_resources[0].status is string 28 | - result.project_resources[0].urn is string 29 | -------------------------------------------------------------------------------- /tests/integration/targets/project_resources_info/tasks/02_get_one.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_get_one | Testing block 4 | block: 5 | - name: 02_get_one | Get project resources 6 | digitalocean.cloud.project_resources_info: 7 | token: "{{ digitalocean_token }}" 8 | project_id: "{{ project_id }}" 9 | register: result 10 | 11 | - name: 02_get_one | Verify project resources structure when no resources 12 | when: result.project_resources | length == 0 13 | ansible.builtin.assert: 14 | that: 15 | - not result.changed 16 | - result.msg == "No project resources" 17 | - result.project_resources == [] 18 | 19 | - name: 02_get_one | Verify project resources structure when resources 20 | when: result.project_resources | length > 0 21 | ansible.builtin.assert: 22 | that: 23 | - not result.changed 24 | - result.msg == "Current project resources" 25 | - result.project_resources[0] is mapping 26 | - result.project_resources[0].assigned_at is string 27 | - result.project_resources[0].links is mapping 28 | - result.project_resources[0].status is string 29 | - result.project_resources[0].urn is string 30 | -------------------------------------------------------------------------------- /tests/integration/targets/project_resources_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Get default project resources 10 | ansible.builtin.include_tasks: 11 | file: 01_get_default.yml 12 | 13 | - name: Get specific project resources 14 | ansible.builtin.include_tasks: 15 | file: 02_get_one.yml 16 | loop: "{{ project_ids }}" 17 | loop_control: 18 | loop_var: project_id 19 | -------------------------------------------------------------------------------- /tests/integration/targets/projects_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/projects_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/projects_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get projects 13 | digitalocean.cloud.projects_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify projects 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.projects is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/regions_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/regions_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/regions_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get regions 13 | digitalocean.cloud.regions_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify regions 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.msg == "Current regions" 26 | - result.regions is iterable 27 | -------------------------------------------------------------------------------- /tests/integration/targets/reserved_ip/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/reserved_ip/aliases -------------------------------------------------------------------------------- /tests/integration/targets/reserved_ip/defaults/main.yml: -------------------------------------------------------------------------------- 1 | region: nyc3 2 | size: s-1vcpu-2gb 3 | image: ubuntu-22-04-x64 4 | droplet_name: "ansible-gh-ci-droplet-4-{{ pr_number }}" 5 | -------------------------------------------------------------------------------- /tests/integration/targets/reserved_ip/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | - name: Create Droplet 5 | digitalocean.cloud.droplet: 6 | token: "{{ digitalocean_token }}" 7 | state: present 8 | name: "{{ droplet_name }}" 9 | region: "{{ region }}" 10 | size: "{{ size }}" 11 | image: "{{ image }}" 12 | unique_name: true 13 | register: result 14 | 15 | # - name: Verify create Droplet 16 | # ansible.builtin.assert: 17 | # that: 18 | # - result.changed 19 | # - result.msg == "Created Droplet " ~ droplet_name ~ " (" ~ result.droplet.id ~ ") in " ~ region 20 | # - result.droplet.name == droplet_name 21 | # - result.droplet.region.slug == region 22 | # - result.droplet.size.slug == size 23 | 24 | - name: Set a fact for the Droplet ID 25 | ansible.builtin.set_fact: 26 | droplet_id: "{{ result.droplet.id }}" 27 | 28 | - name: Created reserved IP 29 | digitalocean.cloud.reserved_ip: 30 | token: "{{ digitalocean_token }}" 31 | state: present 32 | droplet_id: "{{ droplet_id }}" 33 | register: result 34 | 35 | - name: Set a fact for the reserved IP 36 | ansible.builtin.set_fact: 37 | reserved_ip: "{{ result.reserved_ip.ip }}" 38 | 39 | - name: Verify create reserved IP 40 | ansible.builtin.assert: 41 | that: 42 | - result.changed 43 | - result.msg == "Created reserved IP " ~ reserved_ip ~ " for Droplet ID " ~ droplet_id 44 | 45 | - name: Sleep for a few seconds 46 | ansible.builtin.pause: 47 | seconds: 10 48 | 49 | - name: Delete reserved IP 50 | digitalocean.cloud.reserved_ip: 51 | token: "{{ digitalocean_token }}" 52 | state: absent 53 | floating_ip: "{{ reserved_ip }}" 54 | register: result 55 | 56 | - name: Verify delete reserved IP 57 | ansible.builtin.assert: 58 | that: 59 | - result.changed 60 | - result.msg == "Deleted reserved IP " ~ reserved_ip 61 | 62 | - name: Sleep for a few seconds 63 | ansible.builtin.pause: 64 | seconds: 10 65 | 66 | always: 67 | - name: Cleanup Droplet | Leftover from unexpected failure 68 | digitalocean.cloud.droplet: 69 | token: "{{ digitalocean_token }}" 70 | state: absent 71 | name: "{{ droplet_name }}" 72 | region: "{{ region }}" 73 | unique_name: true 74 | ignore_errors: true 75 | 76 | - name: Cleanup reserved IP | Leftover from unexpected failure 77 | digitalocean.cloud.reserved_ip: 78 | token: "{{ digitalocean_token }}" 79 | state: absent 80 | floating_ip: "{{ reserved_ip }}" 81 | ignore_errors: true 82 | -------------------------------------------------------------------------------- /tests/integration/targets/reserved_ip/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test reserved IP | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/reserved_ips_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/reserved_ips_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/reserved_ips_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get reserved IPs 13 | digitalocean.cloud.reserved_ips_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify reserved IPs 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.reserved_ips is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/sizes_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/sizes_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/sizes_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get Droplet sizes 13 | digitalocean.cloud.sizes_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify Droplet sizes 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.msg == "Current Droplet sizes" 26 | - result.sizes is iterable 27 | -------------------------------------------------------------------------------- /tests/integration/targets/snapshot/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/snapshot/aliases -------------------------------------------------------------------------------- /tests/integration/targets/snapshot/defaults/main.yml: -------------------------------------------------------------------------------- 1 | volume_name: ansible-gh-ci-test-vol-0 2 | region: nyc3 3 | size_gigabytes: 1 4 | 5 | volume_snapshot_name: ansible-gh-ci-test-vol-0 6 | volume_snapshot_tags: 7 | - ansible-gh-ci-test-vol-tag-0 8 | - ansible-gh-ci-test-vol-tag-1 9 | -------------------------------------------------------------------------------- /tests/integration/targets/snapshot/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: Testing block 3 | block: 4 | - name: Create volume 5 | digitalocean.cloud.volume: 6 | state: present 7 | token: "{{ digitalocean_token }}" 8 | name: "{{ volume_name }}" 9 | region: "{{ region }}" 10 | size_gigabytes: "{{ size_gigabytes }}" 11 | register: result 12 | 13 | - name: Create a fact for the volume id 14 | ansible.builtin.set_fact: 15 | volume_id: "{{ result.volume.id }}" 16 | 17 | - name: Verify create volume 18 | ansible.builtin.assert: 19 | that: 20 | - result.changed 21 | - result.msg == "Created volume " ~ volume_name ~ " (" ~ volume_id ~ ") in " ~ region 22 | 23 | - name: Sleep for a few seconds 24 | ansible.builtin.pause: 25 | seconds: 10 26 | 27 | - name: Create volume snapshot 28 | digitalocean.cloud.volume_snapshot: 29 | token: "{{ digitalocean_token }}" 30 | state: present 31 | volume_id: "{{ volume_id }}" 32 | name: "{{ volume_snapshot_name }}" 33 | tags: "{{ volume_snapshot_tags }}" 34 | register: result 35 | 36 | - name: Verify create volume snapshot 37 | ansible.builtin.assert: 38 | that: 39 | - result.changed 40 | - result.msg == "Created volume snapshot " ~ volume_snapshot_name ~ " (" ~ result.snapshot.id ~ ") of volume " ~ volume_id 41 | 42 | - name: Sleep for a few seconds 43 | ansible.builtin.pause: 44 | seconds: 10 45 | 46 | - name: Delete snapshot 47 | digitalocean.cloud.snapshot: 48 | token: "{{ digitalocean_token }}" 49 | state: absent 50 | snapshot_id: "{{ result.snapshot.id }}" 51 | register: result 52 | 53 | - name: Verify delete snapshot 54 | ansible.builtin.assert: 55 | that: 56 | - result.changed 57 | - result.msg == "Deleted snapshot " ~ result.snapshot.id 58 | 59 | - name: Delete volume 60 | digitalocean.cloud.volume: 61 | state: absent 62 | token: "{{ digitalocean_token }}" 63 | name: "{{ volume_name }}" 64 | region: "{{ region }}" 65 | register: result 66 | 67 | - name: Verify delete volume 68 | ansible.builtin.assert: 69 | that: 70 | - result.changed 71 | - result.msg == "Deleted volume " ~ volume_name ~ " (" ~ result.volume.id ~ ") in " ~ region 72 | 73 | - name: Sleep for a few seconds 74 | ansible.builtin.pause: 75 | seconds: 10 76 | 77 | always: 78 | - name: Delete volume | Always 79 | digitalocean.cloud.volume: 80 | state: absent 81 | token: "{{ digitalocean_token }}" 82 | name: "{{ volume_name }}" 83 | region: "{{ region }}" 84 | ignore_errors: true # noqa ignore-errors 85 | -------------------------------------------------------------------------------- /tests/integration/targets/snapshot/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test volume snapshot | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/snapshots_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/snapshots_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/snapshots_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get snapshots 13 | digitalocean.cloud.snapshots_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify snapshots 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.snapshots is iterable 23 | -------------------------------------------------------------------------------- /tests/integration/targets/space/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/space/aliases -------------------------------------------------------------------------------- /tests/integration/targets/space/defaults/main.yml: -------------------------------------------------------------------------------- 1 | spaces_tld: digitaloceanspaces.com 2 | 3 | space: 4 | name: ansible-gh-ci-space-0-{{ pr_number | default(0, true) }} 5 | region: nyc3 6 | -------------------------------------------------------------------------------- /tests/integration/targets/space/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: 00_setup | Verify Spaces key 13 | ansible.builtin.assert: 14 | that: 15 | - aws_access_key_id is string 16 | - aws_access_key_id | length > 0 17 | fail_msg: aws_access_key_id should be defined in tests/integration/integration_config.yml 18 | 19 | - name: 00_setup | Verify Spaces secret key 20 | ansible.builtin.assert: 21 | that: 22 | - aws_secret_access_key is string 23 | - aws_secret_access_key | length > 0 24 | fail_msg: aws_secret_access_key should be defined in tests/integration/integration_config.yml 25 | -------------------------------------------------------------------------------- /tests/integration/targets/space/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_create_delete | Testing block 4 | block: 5 | - name: 01_create_delete | Create Space 6 | digitalocean.cloud.space: 7 | state: present 8 | aws_access_key_id: "{{ aws_access_key_id }}" 9 | aws_secret_access_key: "{{ aws_secret_access_key }}" 10 | name: "{{ space.name }}" 11 | region: "{{ space.region }}" 12 | register: result 13 | 14 | - name: 01_create_delete | Verify create Space 15 | ansible.builtin.assert: 16 | that: 17 | - result.changed 18 | - result.msg == "Created Space named " ~ space.name ~ " in " ~ space.region 19 | - result.spaces | length == 1 20 | - result.spaces[0].endpoint_url == "https://{{ space.region }}.{{ spaces_tld }}" 21 | - result.spaces[0].name == space.name 22 | - result.spaces[0].region == space.region 23 | - result.spaces[0].space_url == "https://{{ space.name }}.{{ space.region }}.{{ spaces_tld }}" 24 | 25 | - name: 01_create_delete | Create Space again 26 | digitalocean.cloud.space: 27 | state: present 28 | aws_access_key_id: "{{ aws_access_key_id }}" 29 | aws_secret_access_key: "{{ aws_secret_access_key }}" 30 | name: "{{ space.name }}" 31 | region: "{{ space.region }}" 32 | register: result 33 | 34 | - name: 01_create_delete | Verify create Space idempotency 35 | ansible.builtin.assert: 36 | that: 37 | - not result.changed 38 | - result.msg == "Existing Space named " ~ space.name ~ " in " ~ space.region 39 | - result.spaces | length == 1 40 | - result.spaces[0].endpoint_url == "https://{{ space.region }}.{{ spaces_tld }}" 41 | - result.spaces[0].name == space.name 42 | - result.spaces[0].region == space.region 43 | - result.spaces[0].space_url == "https://{{ space.name }}.{{ space.region }}.{{ spaces_tld }}" 44 | 45 | - name: 01_create_delete | Sleep for a minute 46 | ansible.builtin.pause: 47 | minutes: 1 48 | 49 | - name: 01_create_delete | Delete Space 50 | digitalocean.cloud.space: 51 | state: absent 52 | aws_access_key_id: "{{ aws_access_key_id }}" 53 | aws_secret_access_key: "{{ aws_secret_access_key }}" 54 | name: "{{ space.name }}" 55 | region: "{{ space.region }}" 56 | register: result 57 | 58 | - name: 01_create_delete | Verify delete Space 59 | ansible.builtin.assert: 60 | that: 61 | - result.changed 62 | - result.msg == "Deleted Space named " ~ space.name ~ " in " ~ space.region 63 | - result.spaces | length == 0 64 | 65 | - name: 01_create_delete | Delete Space again 66 | digitalocean.cloud.space: 67 | state: absent 68 | aws_access_key_id: "{{ aws_access_key_id }}" 69 | aws_secret_access_key: "{{ aws_secret_access_key }}" 70 | name: "{{ space.name }}" 71 | region: "{{ space.region }}" 72 | register: result 73 | 74 | - name: 01_create_delete | Verify delete Space idempotency 75 | ansible.builtin.assert: 76 | that: 77 | - not result.changed 78 | - result.msg == "No Spaces named " ~ space.name ~ " in " ~ space.region 79 | - result.spaces | length == 0 80 | -------------------------------------------------------------------------------- /tests/integration/targets/space/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Get all 10 | ansible.builtin.include_tasks: 11 | file: 01_create_delete.yml 12 | -------------------------------------------------------------------------------- /tests/integration/targets/spaces_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/spaces_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/spaces_info/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | spaces_tld: digitaloceanspaces.com 4 | 5 | spaces_regions: 6 | - nyc3 7 | - sfo3 8 | 9 | # NOTE: Expected that this exists 10 | space_exists: 11 | name: ansible-gh-ci-space-0 12 | region: nyc3 13 | 14 | # NOTE: Expected that this does not exist 15 | space_not_exists: 16 | name: ansible-gh-ci-space-0-no-way-this-exists 17 | region: nyc3 18 | -------------------------------------------------------------------------------- /tests/integration/targets/spaces_info/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: 00_setup | Verify Spaces key 13 | ansible.builtin.assert: 14 | that: 15 | - aws_access_key_id is string 16 | - aws_access_key_id | length > 0 17 | fail_msg: aws_access_key_id should be defined in tests/integration/integration_config.yml 18 | 19 | - name: 00_setup | Verify Spaces secret key 20 | ansible.builtin.assert: 21 | that: 22 | - aws_secret_access_key is string 23 | - aws_secret_access_key | length > 0 24 | fail_msg: aws_secret_access_key should be defined in tests/integration/integration_config.yml 25 | -------------------------------------------------------------------------------- /tests/integration/targets/spaces_info/tasks/01_get_all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_get_all | Testing block 4 | block: 5 | - name: 01_get_all | Get Spaces 6 | digitalocean.cloud.spaces_info: 7 | aws_access_key_id: "{{ aws_access_key_id }}" 8 | aws_secret_access_key: "{{ aws_secret_access_key }}" 9 | region: "{{ spaces_region }}" 10 | register: result 11 | 12 | - name: 01_get_all | Verify get Spaces 13 | ansible.builtin.assert: 14 | that: 15 | - not result.changed 16 | - result.msg is string 17 | 18 | - name: 01_get_all | Verify Spaces result when Spaces 19 | when: "'Current Spaces in' in result.msg" 20 | ansible.builtin.assert: 21 | that: 22 | - result.msg == "Current Spaces in " ~ spaces_region 23 | - result.spaces is iterable 24 | - result.spaces | length > 0 25 | - result.spaces[0] is mapping 26 | - result.spaces[0].endpoint_url | length > 0 27 | - result.spaces[0].name | length > 0 28 | - result.spaces[0].region | length > 0 29 | - result.spaces[0].space_url | length > 0 30 | 31 | - name: 01_get_all | Verify Spaces result when no Spaces 32 | when: "'No Spaces in' in result.msg" 33 | ansible.builtin.assert: 34 | that: 35 | - result.msg == "No Spaces in " ~ spaces_region 36 | - result.spaces is iterable 37 | - result.spaces | length == 0 38 | -------------------------------------------------------------------------------- /tests/integration/targets/spaces_info/tasks/02_get_one.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_get_one | Testing block 4 | block: 5 | - name: 02_get_one | Get existing Space 6 | digitalocean.cloud.spaces_info: 7 | aws_access_key_id: "{{ aws_access_key_id }}" 8 | aws_secret_access_key: "{{ aws_secret_access_key }}" 9 | name: "{{ space_exists.name }}" 10 | region: "{{ space_exists.region }}" 11 | register: result 12 | 13 | - name: 02_get_one | Verify get existing Space 14 | ansible.builtin.assert: 15 | that: 16 | - not result.changed 17 | - result.msg == "Existing Space named {{ space_exists.name }} in {{ space_exists.region }}" 18 | - result.spaces | length == 1 19 | - result.spaces[0].endpoint_url == "https://{{ space_exists.region }}.{{ spaces_tld }}" 20 | - result.spaces[0].name == space_exists.name 21 | - result.spaces[0].region == space_exists.region 22 | - result.spaces[0].space_url == "https://{{ space_exists.name }}.{{ space_exists.region }}.{{ spaces_tld }}" 23 | 24 | - name: 02_get_one | Get non-existent Space 25 | digitalocean.cloud.spaces_info: 26 | aws_access_key_id: "{{ aws_access_key_id }}" 27 | aws_secret_access_key: "{{ aws_secret_access_key }}" 28 | name: "{{ space_not_exists.name }}" 29 | region: "{{ space_not_exists.region }}" 30 | register: result 31 | 32 | - name: 02_get_one | Verify get non-existent Space 33 | ansible.builtin.assert: 34 | that: 35 | - not result.changed 36 | - result.msg == "No Space named {{ space_not_exists.name }} in {{ space_not_exists.region }}" 37 | - result.spaces | length == 0 38 | -------------------------------------------------------------------------------- /tests/integration/targets/spaces_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Get all 10 | ansible.builtin.include_tasks: 11 | file: 01_get_all.yml 12 | vars: 13 | spaces_region: "{{ item }}" 14 | # TODO: Improve this: hoping one will have Spaces one will not 15 | loop: "{{ spaces_regions }}" 16 | 17 | - name: Get one 18 | ansible.builtin.include_tasks: 19 | file: 02_get_one.yml 20 | -------------------------------------------------------------------------------- /tests/integration/targets/ssh_key/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/ssh_key/aliases -------------------------------------------------------------------------------- /tests/integration/targets/ssh_key/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ssh_key_name: ansible-gh-ci-ssh-key-0 2 | ssh_public_key: >- 3 | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH6bTtnmZNhXUuxe+SZ6KOPG8JDo01scHYm26jfFmt5tjoYcZffFO5NS+pf7SFQ/0DD1w3O+/hZFKmBVMhbHoT4= mark@Marks-MacBook-Pro.local 4 | ssh_fingerprint: d1:d5:59:5e:7f:b8:5c:4c:3d:0f:5b:c7:e7:a4:67:a5 5 | -------------------------------------------------------------------------------- /tests/integration/targets/ssh_key/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create SSH key 6 | digitalocean.cloud.ssh_key: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | public_key: "{{ ssh_public_key }}" 10 | name: "{{ ssh_key_name }}" 11 | register: result 12 | 13 | - name: Verify create SSH key 14 | ansible.builtin.assert: 15 | that: 16 | - result.changed 17 | - result.msg == "Created SSH key " ~ ssh_key_name ~ " (" ~ result.ssh_key.fingerprint ~ ")" 18 | - result.ssh_key.name == ssh_key_name 19 | - result.ssh_key.fingerprint == ssh_fingerprint 20 | 21 | - name: Delete SSH key 22 | digitalocean.cloud.ssh_key: 23 | token: "{{ digitalocean_token }}" 24 | state: absent 25 | public_key: "{{ ssh_public_key }}" 26 | name: "{{ ssh_key_name }}" 27 | register: result 28 | 29 | - name: Verify delete SSH key 30 | ansible.builtin.assert: 31 | that: 32 | - result.changed 33 | - result.msg == "Deleted SSH key " ~ ssh_key_name ~ " (" ~ result.ssh_key.fingerprint ~ ")" 34 | - result.ssh_key.name == ssh_key_name 35 | - result.ssh_key.fingerprint == ssh_fingerprint 36 | 37 | always: 38 | 39 | - name: Cleanup SSH key | Leftover from unexpected failure 40 | digitalocean.cloud.ssh_key: 41 | token: "{{ digitalocean_token }}" 42 | state: absent 43 | public_key: "{{ ssh_public_key }}" 44 | name: "{{ ssh_key_name }}" 45 | ignore_errors: true 46 | -------------------------------------------------------------------------------- /tests/integration/targets/ssh_key/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test firewall | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/ssh_keys_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/ssh_keys_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/ssh_keys_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get SSH keys 13 | digitalocean.cloud.ssh_keys_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify SSH keys 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.ssh_keys is iterable 26 | -------------------------------------------------------------------------------- /tests/integration/targets/tag/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/tag/aliases -------------------------------------------------------------------------------- /tests/integration/targets/tag/defaults/main.yml: -------------------------------------------------------------------------------- 1 | tag_name: ansible-gh-tag-0 2 | -------------------------------------------------------------------------------- /tests/integration/targets/tag/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create tag 6 | digitalocean.cloud.tag: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ tag_name }}" 10 | register: result 11 | 12 | - name: Verify create tag 13 | ansible.builtin.assert: 14 | that: 15 | - result.changed 16 | - result.msg == "Created tag " ~ tag_name 17 | - result.tag.name == tag_name 18 | 19 | - name: Delete tag 20 | digitalocean.cloud.tag: 21 | token: "{{ digitalocean_token }}" 22 | state: absent 23 | name: "{{ tag_name }}" 24 | register: result 25 | 26 | - name: Verify delete firewall 27 | ansible.builtin.assert: 28 | that: 29 | - result.changed 30 | - result.msg == "Deleted tag " ~ tag_name 31 | - result.tag.name == tag_name 32 | 33 | always: 34 | 35 | - name: Cleanup tag | Leftover from unexpected failure 36 | digitalocean.cloud.tag: 37 | token: "{{ digitalocean_token }}" 38 | state: absent 39 | name: "{{ tag_name }}" 40 | ignore_errors: true 41 | -------------------------------------------------------------------------------- /tests/integration/targets/tag/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test tag | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/tags_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/tags_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/tags_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get tags 13 | digitalocean.cloud.tags_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify tags 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.tags is iterable 26 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_check/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/uptime_check/aliases -------------------------------------------------------------------------------- /tests/integration/targets/uptime_check/defaults/main.yml: -------------------------------------------------------------------------------- 1 | check: 2 | name: "ansible-gh-ci-check-{{ pr_number | default(0, true) }}" 3 | type: ping 4 | target: api.digitalocean.com 5 | regions: [us_east] 6 | enabled: true 7 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_check/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_check/tasks/01_create_delete_not_unique_name.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_create_delete_not_unique_name | Testing block 4 | block: 5 | - name: 01_create_delete_not_unique_name | Create Uptime check 6 | digitalocean.cloud.uptime_check: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ check.name }}" 10 | type: "{{ check.type }}" 11 | target: "{{ check.target }}" 12 | regions: "{{ check.regions }}" 13 | enabled: "{{ check.enabled }}" 14 | register: create_result 15 | 16 | - name: 01_create_delete_not_unique_name | Verify create Uptime check 17 | ansible.builtin.assert: 18 | that: 19 | - create_result.changed 20 | - create_result.msg == "Created Uptime check named " ~ check.name ~ " (" ~ create_result.check.id ~ ")" 21 | - create_result.check.id | length 22 | - create_result.check.name == check.name 23 | - create_result.check.type == check.type 24 | - create_result.check.target == check.target 25 | - create_result.check.regions == check.regions 26 | - create_result.check.enabled == check.enabled 27 | 28 | - name: 01_create_delete_not_unique_name | Sleep for 10 seconds 29 | ansible.builtin.pause: 30 | seconds: 10 31 | 32 | - name: 01_create_delete_not_unique_name | Delete Uptime check 33 | digitalocean.cloud.uptime_check: 34 | state: absent 35 | token: "{{ digitalocean_token }}" 36 | check_id: "{{ create_result.check.id }}" 37 | register: delete_result 38 | 39 | - name: 01_create_delete_not_unique_name | Verify delete Uptime check 40 | ansible.builtin.assert: 41 | that: 42 | - delete_result.changed 43 | - delete_result.msg == "Deleted Uptime check " ~ create_result.check.id 44 | - delete_result.check == [] 45 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_check/tasks/02_create_delete_unique_name.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_create_delete_unique_name | Testing block 4 | block: 5 | - name: 02_create_delete_unique_name | Create Uptime check 6 | digitalocean.cloud.uptime_check: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | name: "{{ check.name }}" 10 | unique_name: true 11 | type: "{{ check.type }}" 12 | target: "{{ check.target }}" 13 | regions: "{{ check.regions }}" 14 | enabled: "{{ check.enabled }}" 15 | register: create_result 16 | 17 | - name: 02_create_delete_unique_name | Verify create Uptime check 18 | ansible.builtin.assert: 19 | that: 20 | - create_result.changed 21 | - create_result.msg == "Created Uptime check named " ~ check.name ~ " (" ~ create_result.check.id ~ ")" 22 | - create_result.check.id | length 23 | - create_result.check.name == check.name 24 | - create_result.check.type == check.type 25 | - create_result.check.target == check.target 26 | - create_result.check.regions == check.regions 27 | - create_result.check.enabled == check.enabled 28 | 29 | - name: 02_create_delete_unique_name | Create Uptime check again 30 | digitalocean.cloud.uptime_check: 31 | state: present 32 | token: "{{ digitalocean_token }}" 33 | name: "{{ check.name }}" 34 | unique_name: true 35 | type: "{{ check.type }}" 36 | target: "{{ check.target }}" 37 | regions: "{{ check.regions }}" 38 | enabled: "{{ check.enabled }}" 39 | register: create_result_again 40 | 41 | - name: 02_create_delete_unique_name | Verify create Uptime check idempotency 42 | ansible.builtin.assert: 43 | that: 44 | - not create_result_again.changed 45 | - create_result_again.msg == "Uptime check named " ~ check.name ~ " (" ~ create_result.check.id ~ ") exists" 46 | 47 | - name: 02_create_delete_unique_name | Sleep for 10 seconds 48 | ansible.builtin.pause: 49 | seconds: 10 50 | 51 | - name: 02_create_delete_unique_name | Delete Uptime check 52 | digitalocean.cloud.uptime_check: 53 | state: absent 54 | token: "{{ digitalocean_token }}" 55 | name: "{{ check.name }}" 56 | unique_name: true 57 | register: delete_result 58 | 59 | - name: 02_create_delete_unique_name | Verify delete Uptime check 60 | ansible.builtin.assert: 61 | that: 62 | - delete_result.changed 63 | - delete_result.msg == "Deleted Uptime check " ~ create_result.check.id 64 | - delete_result.check == [] 65 | 66 | - name: 02_create_delete_unique_name | Delete Uptime check again 67 | digitalocean.cloud.uptime_check: 68 | state: absent 69 | token: "{{ digitalocean_token }}" 70 | name: "{{ check.name }}" 71 | unique_name: true 72 | register: delete_result_again 73 | 74 | - name: 02_create_delete_unique_name | Verify delete Uptime check idempotency 75 | ansible.builtin.assert: 76 | that: 77 | - not delete_result_again.changed 78 | - delete_result_again.msg == "No Uptime check named " ~ check.name 79 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_check/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Create and delete not unique name 10 | ansible.builtin.include_tasks: 11 | file: 01_create_delete_not_unique_name.yml 12 | 13 | - name: Create and delete unique name 14 | ansible.builtin.include_tasks: 15 | file: 02_create_delete_unique_name.yml 16 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/uptime_checks_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_info/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_info/tasks/01_get.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_get | Testing block 4 | block: 5 | - name: 01_get | Get Uptime checks 6 | digitalocean.cloud.uptime_checks_info: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | register: result 10 | 11 | - name: 01_get | Verify get Uptime checks 12 | ansible.builtin.assert: 13 | that: 14 | - not result.changed 15 | - result.checks is iterable 16 | 17 | - name: 01_get | Verify get Uptime checks structure when not exists 18 | when: not (result.checks | length) 19 | ansible.builtin.assert: 20 | that: 21 | - not result.changed 22 | - result.checks == [] 23 | - result.msg == "No Uptime checks" 24 | 25 | - name: 01_get | Verify get Uptime checks structure when exists 26 | when: result.checks | length 27 | ansible.builtin.assert: 28 | that: 29 | - check.enabled is boolean 30 | - check.id is string and check.id | length 31 | - check.name is string and check.name | length 32 | - check.regions is iterable 33 | - check.target is string and check.target | length 34 | - check.type is string and check.type in ["ping", "http", "https"] 35 | loop: "{{ result.checks }}" 36 | loop_control: 37 | loop_var: check 38 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Get 10 | ansible.builtin.include_tasks: 11 | file: 01_get.yml 12 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_state_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/uptime_checks_state_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_state_info/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | check_name: ansible-gh-ci-check-0 4 | check_id: 9b71ecc1-289c-4f95-902e-3427a36c2918 5 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_state_info/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 00_setup | Testing block 4 | block: 5 | - name: 00_setup | Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_state_info/tasks/01_get_existing.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 01_get_existing | Testing block 4 | block: 5 | - name: 01_get_existing | Get Uptime check state by ID 6 | digitalocean.cloud.uptime_checks_state_info: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | check_id: "{{ check_id }}" 10 | register: result 11 | 12 | - name: 01_get_existing | Verify get Uptime check state by ID 13 | when: result.state | length 14 | ansible.builtin.assert: 15 | that: 16 | - not result.changed 17 | - result.msg == "Current Uptime check " ~ check_id ~ " state" 18 | - result.state.alert_count is number 19 | - result.state.previous_outage is mapping 20 | - result.state.regions is mapping 21 | 22 | - name: 01_get_existing | Get Uptime check state by name 23 | digitalocean.cloud.uptime_checks_state_info: 24 | state: present 25 | token: "{{ digitalocean_token }}" 26 | name: "{{ check_name }}" 27 | register: result 28 | 29 | - name: 01_get_existing | Verify get Uptime check state by name 30 | when: result.state | length 31 | ansible.builtin.assert: 32 | that: 33 | - not result.changed 34 | - result.msg == "Current Uptime check named " ~ check_name ~ " state" 35 | - result.state.alert_count is number 36 | - result.state.previous_outage is mapping 37 | - result.state.regions is mapping 38 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_state_info/tasks/02_get_non_existent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: 02_get_non_existent | Testing block 4 | block: 5 | - name: 02_get_non_existent | Get Uptime check state by ID 6 | digitalocean.cloud.uptime_checks_state_info: 7 | state: present 8 | token: "{{ digitalocean_token }}" 9 | check_id: this-should-not-exist 10 | register: result 11 | 12 | - name: 02_get_non_existent | Verify get Uptime check state by ID 13 | ansible.builtin.assert: 14 | that: 15 | - not result.changed 16 | - result.msg == "No Uptime check this-should-not-exist" 17 | - result.state == [] 18 | 19 | - name: 02_get_non_existent | Get Uptime check state by name 20 | digitalocean.cloud.uptime_checks_state_info: 21 | state: present 22 | token: "{{ digitalocean_token }}" 23 | name: this-should-not-exist 24 | register: result 25 | 26 | - name: 02_get_non_existent | Verify get Uptime check state by name 27 | ansible.builtin.assert: 28 | that: 29 | - not result.changed 30 | - result.msg == "No Uptime check named this-should-not-exist" 31 | - result.state == [] 32 | -------------------------------------------------------------------------------- /tests/integration/targets/uptime_checks_state_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # code: language=ansible 3 | - name: Testing block 4 | block: 5 | - name: Setup 6 | ansible.builtin.include_tasks: 7 | file: 00_setup.yml 8 | 9 | - name: Get existing check state 10 | ansible.builtin.include_tasks: 11 | file: 01_get_existing.yml 12 | 13 | - name: Get non-existent check state 14 | ansible.builtin.include_tasks: 15 | file: 02_get_non_existent.yml 16 | -------------------------------------------------------------------------------- /tests/integration/targets/volume/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/volume/aliases -------------------------------------------------------------------------------- /tests/integration/targets/volume/defaults/main.yml: -------------------------------------------------------------------------------- 1 | volume_name: gh-ci-test-vol-1 2 | region: nyc3 3 | size_gigabytes: 1 4 | -------------------------------------------------------------------------------- /tests/integration/targets/volume/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: Testing block 3 | block: 4 | - name: Create volume 5 | digitalocean.cloud.volume: 6 | state: present 7 | token: "{{ digitalocean_token }}" 8 | name: "{{ volume_name }}" 9 | region: "{{ region }}" 10 | size_gigabytes: "{{ size_gigabytes }}" 11 | register: result 12 | 13 | - name: Verify create volume 14 | ansible.builtin.assert: 15 | that: 16 | - result.changed 17 | - result.msg == "Created volume " ~ volume_name ~ " (" ~ result.volume.id ~ ") in " ~ region 18 | 19 | - name: Sleep for a few seconds 20 | ansible.builtin.pause: 21 | seconds: 10 22 | 23 | - name: Delete volume 24 | digitalocean.cloud.volume: 25 | state: absent 26 | token: "{{ digitalocean_token }}" 27 | name: "{{ volume_name }}" 28 | region: "{{ region }}" 29 | register: result 30 | 31 | - name: Verify delete volume 32 | ansible.builtin.assert: 33 | that: 34 | - result.changed 35 | - result.msg == "Deleted volume " ~ volume_name ~ " (" ~ result.volume.id ~ ") in " ~ region 36 | 37 | - name: Sleep for a few seconds 38 | ansible.builtin.pause: 39 | seconds: 10 40 | 41 | always: 42 | - name: Delete volume | Always 43 | digitalocean.cloud.volume: 44 | state: absent 45 | token: "{{ digitalocean_token }}" 46 | name: "{{ volume_name }}" 47 | region: "{{ region }}" 48 | ignore_errors: true # noqa ignore-errors 49 | -------------------------------------------------------------------------------- /tests/integration/targets/volume/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test volume | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/volume_action/aliases -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/defaults/main.yml: -------------------------------------------------------------------------------- 1 | volume_name: "ansible-gh-ci-volume-5-{{ pr_number }}" 2 | volume_region: nyc3 3 | volume_size_gigabytes: 1 4 | 5 | droplet_name: "ansible-gh-ci-droplet-5-{{ pr_number }}" 6 | droplet_region: nyc3 7 | droplet_size: s-1vcpu-2gb 8 | droplet_image: ubuntu-22-04-x64 9 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/tasks/00_setup.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - block: 3 | 4 | - name: Create Droplet 5 | digitalocean.cloud.droplet: 6 | token: "{{ digitalocean_token }}" 7 | state: present 8 | name: "{{ droplet_name }}" 9 | region: "{{ droplet_region }}" 10 | size: "{{ droplet_size }}" 11 | image: "{{ droplet_image }}" 12 | unique_name: true 13 | 14 | - name: Create volume 15 | digitalocean.cloud.volume: 16 | state: present 17 | token: "{{ digitalocean_token }}" 18 | name: "{{ volume_name }}" 19 | region: "{{ volume_region }}" 20 | size_gigabytes: "{{ volume_size_gigabytes }}" 21 | 22 | - name: Sleep for a minute 23 | ansible.builtin.pause: 24 | minutes: 1 25 | 26 | rescue: 27 | 28 | - name: Teardown | Delete volume 29 | digitalocean.cloud.volume: 30 | state: absent 31 | token: "{{ digitalocean_token }}" 32 | name: "{{ volume_name }}" 33 | region: "{{ volume_region }}" 34 | 35 | - name: Teardown | Delete Droplet 36 | digitalocean.cloud.droplet: 37 | state: absent 38 | token: "{{ digitalocean_token }}" 39 | name: "{{ droplet_name }}" 40 | region: "{{ droplet_region }}" 41 | unique_name: true 42 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/tasks/01_attach.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - block: 3 | 4 | - name: Attach block storage volume 5 | when: true 6 | digitalocean.cloud.volume_action: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | volume_name: "{{ volume_name }}" 10 | droplet_name: "{{ droplet_name }}" 11 | region: "{{ volume_region }}" 12 | register: result 13 | 14 | - name: Sleep for a minute 15 | ansible.builtin.pause: 16 | minutes: 1 17 | 18 | - name: Verify attach volume 19 | ansible.builtin.assert: 20 | that: 21 | - result.changed 22 | - result.action is defined 23 | - result.action.type == "attach_volume" 24 | - result.msg == "Attached volume " ~ volume_name ~ " in " ~ volume_region ~ " to " ~ droplet_name 25 | 26 | rescue: 27 | 28 | - name: Detach block storage volume 29 | digitalocean.cloud.volume_action: 30 | token: "{{ digitalocean_token }}" 31 | state: absent 32 | volume_name: "{{ volume_name }}" 33 | droplet_name: "{{ droplet_name }}" 34 | region: "{{ volume_region }}" 35 | 36 | - name: Teardown | Delete volume 37 | digitalocean.cloud.volume: 38 | state: absent 39 | token: "{{ digitalocean_token }}" 40 | name: "{{ volume_name }}" 41 | region: "{{ volume_region }}" 42 | 43 | - name: Teardown | Delete Droplet 44 | digitalocean.cloud.droplet: 45 | state: absent 46 | token: "{{ digitalocean_token }}" 47 | name: "{{ droplet_name }}" 48 | region: "{{ droplet_region }}" 49 | unique_name: true 50 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/tasks/02_detach.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - block: 3 | 4 | - name: Detach block storage volume 5 | digitalocean.cloud.volume_action: 6 | token: "{{ digitalocean_token }}" 7 | state: absent 8 | volume_name: "{{ volume_name }}" 9 | droplet_name: "{{ droplet_name }}" 10 | region: "{{ volume_region }}" 11 | register: result 12 | 13 | - name: Sleep for a minute 14 | ansible.builtin.pause: 15 | minutes: 1 16 | 17 | - name: Verify detach volume 18 | ansible.builtin.assert: 19 | that: 20 | - result.changed 21 | - result.action is defined 22 | - result.action.type == "detach_volume" 23 | - result.msg == "Detached volume " ~ volume_name ~ " in " ~ volume_region ~ " from " ~ droplet_name 24 | 25 | rescue: 26 | 27 | - name: Teardown | Delete volume 28 | digitalocean.cloud.volume: 29 | state: absent 30 | token: "{{ digitalocean_token }}" 31 | name: "{{ volume_name }}" 32 | region: "{{ volume_region }}" 33 | 34 | - name: Teardown | Delete Droplet 35 | digitalocean.cloud.droplet: 36 | state: absent 37 | token: "{{ digitalocean_token }}" 38 | name: "{{ droplet_name }}" 39 | region: "{{ droplet_region }}" 40 | unique_name: true 41 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/tasks/99_teardown.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - block: 3 | 4 | - name: Teardown | Delete volume 5 | digitalocean.cloud.volume: 6 | state: absent 7 | token: "{{ digitalocean_token }}" 8 | name: "{{ volume_name }}" 9 | region: "{{ volume_region }}" 10 | 11 | - name: Teardown | Delete Droplet 12 | digitalocean.cloud.droplet: 13 | state: absent 14 | token: "{{ digitalocean_token }}" 15 | name: "{{ droplet_name }}" 16 | region: "{{ droplet_region }}" 17 | unique_name: true 18 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_action/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Setup | Create Droplet and volume 13 | ansible.builtin.include_tasks: 14 | file: 00_setup.yml 15 | 16 | - name: Test volume action | Attach 17 | ansible.builtin.include_tasks: 18 | file: 01_attach.yml 19 | 20 | - name: Test volume action | Detach 21 | ansible.builtin.include_tasks: 22 | file: 02_detach.yml 23 | 24 | - name: Teardown | Destroy Droplet and volume 25 | ansible.builtin.include_tasks: 26 | file: 99_teardown.yml 27 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_snapshot/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/volume_snapshot/aliases -------------------------------------------------------------------------------- /tests/integration/targets/volume_snapshot/defaults/main.yml: -------------------------------------------------------------------------------- 1 | volume_name: ansible-gh-ci-test-vol-2 2 | region: nyc3 3 | size_gigabytes: 1 4 | 5 | volume_snapshot_name: ansible-gh-ci-test-vol-2 6 | volume_snapshot_tags: 7 | - ansible-gh-ci-test-vol-tag-2 8 | - ansible-gh-ci-test-vol-tag-3 9 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_snapshot/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | - name: Testing block 3 | block: 4 | - name: Create volume 5 | digitalocean.cloud.volume: 6 | state: present 7 | token: "{{ digitalocean_token }}" 8 | name: "{{ volume_name }}" 9 | region: "{{ region }}" 10 | size_gigabytes: "{{ size_gigabytes }}" 11 | register: result 12 | 13 | - name: Create a fact for the volume id 14 | ansible.builtin.set_fact: 15 | volume_id: "{{ result.volume.id }}" 16 | 17 | - name: Verify create volume 18 | ansible.builtin.assert: 19 | that: 20 | - result.changed 21 | - result.msg == "Created volume " ~ volume_name ~ " (" ~ volume_id ~ ") in " ~ region 22 | 23 | - name: Sleep for a few seconds 24 | ansible.builtin.pause: 25 | seconds: 10 26 | 27 | - name: Create volume snapshot 28 | digitalocean.cloud.volume_snapshot: 29 | token: "{{ digitalocean_token }}" 30 | state: present 31 | volume_id: "{{ volume_id }}" 32 | name: "{{ volume_snapshot_name }}" 33 | tags: "{{ volume_snapshot_tags }}" 34 | register: result 35 | 36 | - name: Verify create volume snapshot 37 | ansible.builtin.assert: 38 | that: 39 | - result.changed 40 | - result.msg == "Created volume snapshot " ~ volume_snapshot_name ~ " (" ~ result.snapshot.id ~ ") of volume " ~ volume_id 41 | 42 | - name: Sleep for a few seconds 43 | ansible.builtin.pause: 44 | seconds: 10 45 | 46 | - name: Delete volume snapshot 47 | digitalocean.cloud.volume_snapshot: 48 | token: "{{ digitalocean_token }}" 49 | state: absent 50 | volume_id: "{{ volume_id }}" 51 | name: "{{ volume_snapshot_name }}" 52 | tags: "{{ volume_snapshot_tags }}" 53 | register: result 54 | 55 | - name: Verify delete volume snapshot 56 | ansible.builtin.assert: 57 | that: 58 | - result.changed 59 | - result.msg == "Deleted volume snapshot " ~ volume_snapshot_name ~ " (" ~ result.snapshot.id ~ ") of volume " ~ volume_id 60 | 61 | - name: Delete volume 62 | digitalocean.cloud.volume: 63 | state: absent 64 | token: "{{ digitalocean_token }}" 65 | name: "{{ volume_name }}" 66 | region: "{{ region }}" 67 | register: result 68 | 69 | - name: Verify delete volume 70 | ansible.builtin.assert: 71 | that: 72 | - result.changed 73 | - result.msg == "Deleted volume " ~ volume_name ~ " (" ~ result.volume.id ~ ") in " ~ region 74 | 75 | - name: Sleep for a few seconds 76 | ansible.builtin.pause: 77 | seconds: 10 78 | 79 | always: 80 | - name: Delete volume snapshot | Always 81 | digitalocean.cloud.volume_snapshot: 82 | token: "{{ digitalocean_token }}" 83 | state: absent 84 | volume_id: "{{ volume_id }}" 85 | name: "{{ volume_snapshot_name }}" 86 | tags: "{{ volume_snapshot_tags }}" 87 | ignore_errors: true # noqa ignore-errors 88 | 89 | - name: Delete volume | Always 90 | digitalocean.cloud.volume: 91 | state: absent 92 | token: "{{ digitalocean_token }}" 93 | name: "{{ volume_name }}" 94 | region: "{{ region }}" 95 | ignore_errors: true # noqa ignore-errors 96 | -------------------------------------------------------------------------------- /tests/integration/targets/volume_snapshot/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - name: Testing block 4 | block: 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test volume snapshot | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/volumes_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/volumes_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/volumes_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get volumes 13 | digitalocean.cloud.volumes_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Assert result message 18 | ansible.builtin.assert: 19 | that: result.msg is string 20 | 21 | - name: Verify volumes 22 | ansible.builtin.assert: 23 | that: 24 | - not result.changed 25 | - result.volumes is iterable 26 | -------------------------------------------------------------------------------- /tests/integration/targets/vpc/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/vpc/aliases -------------------------------------------------------------------------------- /tests/integration/targets/vpc/defaults/main.yml: -------------------------------------------------------------------------------- 1 | vpc_name: ansible-gh-vpc-0 2 | region: nyc3 3 | -------------------------------------------------------------------------------- /tests/integration/targets/vpc/tasks/01_create_delete.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Create VPC 6 | digitalocean.cloud.vpc: 7 | token: "{{ digitalocean_token }}" 8 | state: present 9 | name: "{{ vpc_name }}" 10 | region: "{{ region }}" 11 | register: result 12 | 13 | - name: Verify create VPC 14 | ansible.builtin.assert: 15 | that: 16 | - result.changed 17 | - result.msg == "Created VPC " ~ vpc_name ~ " (" ~ result.vpc.id ~ ")" 18 | - result.vpc.name == vpc_name 19 | - result.vpc.region == region 20 | 21 | - name: Sleep a few seconds 22 | ansible.builtin.pause: 23 | seconds: 10 24 | 25 | - name: Delete VPC 26 | digitalocean.cloud.vpc: 27 | token: "{{ digitalocean_token }}" 28 | state: absent 29 | name: "{{ vpc_name }}" 30 | region: "{{ region }}" 31 | register: result 32 | 33 | - name: Verify delete firewall 34 | ansible.builtin.assert: 35 | that: 36 | - result.changed 37 | - result.msg == "Deleted VPC " ~ vpc_name ~ " (" ~ result.vpc.id ~ ")" 38 | - result.vpc.name == vpc_name 39 | - result.vpc.region == region 40 | 41 | always: 42 | 43 | - name: Cleanup tag | Leftover from unexpected failure 44 | digitalocean.cloud.vpc: 45 | token: "{{ digitalocean_token }}" 46 | state: absent 47 | name: "{{ vpc_name }}" 48 | region: "{{ region }}" 49 | ignore_errors: true 50 | -------------------------------------------------------------------------------- /tests/integration/targets/vpc/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Test VPC | Create and delete 13 | ansible.builtin.include_tasks: 14 | file: 01_create_delete.yml 15 | -------------------------------------------------------------------------------- /tests/integration/targets/vpcs_info/aliases: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digitalocean/ansible-collection/85d5d7822068c6dc72b2dbf0cfc2ce647336d793/tests/integration/targets/vpcs_info/aliases -------------------------------------------------------------------------------- /tests/integration/targets/vpcs_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # code: language=ansible 2 | --- 3 | - block: 4 | 5 | - name: Verify API token 6 | ansible.builtin.assert: 7 | that: 8 | - digitalocean_token is string 9 | - digitalocean_token | length > 0 10 | fail_msg: digitalocean_token should be defined in tests/integration/integration_config.yml 11 | 12 | - name: Get VPCs 13 | digitalocean.cloud.vpcs_info: 14 | token: "{{ digitalocean_token }}" 15 | register: result 16 | 17 | - name: Verify VPCs 18 | ansible.builtin.assert: 19 | that: 20 | - not result.changed 21 | - result.msg is string 22 | - result.vpcs is iterable 23 | -------------------------------------------------------------------------------- /tests/run-integration.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | cd ~/.ansible/collections/ansible_collections/digitalocean/cloud 5 | ansible-test integration 6 | -------------------------------------------------------------------------------- /tests/run-sanity.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | cd ~/.ansible/collections/ansible_collections/digitalocean/cloud 5 | ansible-test sanity 6 | -------------------------------------------------------------------------------- /tests/units/.gitkeep: -------------------------------------------------------------------------------- 1 | This is a placeholder file that only exists to keep the current 2 | directory in Git. It is safe to remove it once this directory contains 3 | the actual test files. 4 | -------------------------------------------------------------------------------- /tests/utils/render.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Renders tests/integration/integration_config.yml 3 | set -e 4 | set -o pipefail 5 | set -u 6 | 7 | function main() { 8 | local template 9 | template="$1" 10 | shift 11 | local content 12 | content="$(cat "$template")" 13 | 14 | eval "echo \"$content\"" 15 | } 16 | 17 | main "$@" 18 | --------------------------------------------------------------------------------