40 Commits
1.0.1 ... 1.1.0

Author SHA1 Message Date
Sagi Shnaidman
f448c78dd4 Changelog for Ansible 2.10 release
Story: #2007982
Task: #40608
Change-Id: I74219d8e7f9a8b13bbb17bc070671a1327fd5775
2020-08-17 16:04:54 +03:00
Sagi Shnaidman
33ce7ab9c7 Add volume_info module
Add module for retrieving information about volumes in a cloud.

Story: #2007817
Task: #40095
Change-Id: Ic7551c1737b08b967613e42923f5ea4ec0b606a4
2020-08-16 20:56:45 +03:00
Sagi Shnaidman
03fadf3b43 Fix non existing attribuites in SDK exception
SDK exception may not have extra_data, details or
response attributes. Print None in this case.

Change-Id: Ic4073c28a4e4afb8ca5d2b72c4ea8582da244af1
2020-08-11 14:17:36 +03:00
Zuul
86a5cc3b42 Merge "Do not require ironic_url if cloud or auth.endpoint is provided" 2020-07-28 18:06:27 +00:00
Dmitry Tantsur
8731fcc64b Do not require ironic_url if cloud or auth.endpoint is provided
The endpoint may be specified in clouds.yaml or via auth, do not
force ironic_url in either of these cases.

Finally, accept "none" as a valid no-auth plugin name.

Change-Id: I4d50b7c55727f022d79df85fb4a163fe3e5fca7b
2020-07-28 17:10:01 +02:00
Dmitry Tantsur
f6a7cf5343 Add non-voting bifrost jobs
Bifrost has fully switched to the collection, use its jobs to verify
changes. This adds two jobs: one with no-auth, one with keystone.

Depends-On: https://review.opendev.org/#/c/743167/
Change-Id: I3d46996edb4f8165a559ed70b908316e82a13353
2020-07-27 12:46:52 +02:00
Zuul
284d7871ce Merge "Add support for setting the Flavor when creating a load balancer" 2020-07-26 16:41:19 +00:00
Sagi Shnaidman
fcf6fae499 Add periodic jobs for collections
Add periodic pipeline jobs, add to it another queens jobs with
different ansible versions to increase the coverage.

Change-Id: Ie90547cb17e5c52558b6068e7128f90abffc2e25
2020-07-26 12:32:45 +00:00
Mark Chappell
88b86be33e Add support for setting the Flavor when creating a load balancer
Change-Id: I72c6b60225cacf598ddb9b7df142eced429b7226
2020-07-26 11:22:24 +00:00
Sagi Shnaidman
1f3417cdef Temporarly disable check-import
check-import has ansible as a dependency, which installs only
2.9 ansible version and it conflicts with higher ansible versions
Issue to check-import will be submitted to have ansible-test as
a dep.
Change-Id: Ide46a8a6b45677e82e57eb6a4c5dfe412d7b37fd
2020-07-26 11:49:18 +03:00
Zuul
8792b2b527 Merge "Add openstack logger and Ansible display utility" 2020-07-09 14:30:17 +00:00
Zuul
4a930cf0ec Merge "keypair: make use of OpenStackModule class" 2020-07-09 14:30:16 +00:00
Zuul
e1fe3f6067 Merge "security_group_rule: use OpenStackModule class" 2020-07-09 14:24:08 +00:00
Marc-Antoine Bourgeot
40ce8103f4 Add openstack logger and Ansible display utility
Story: 2007879

Change-Id: I76fc7df8202b4e00b54b5bafe7719e02b49e59ff
2020-07-07 22:21:47 +02:00
Baptiste Mille-Mathias
bbe1d84448 Add a link for issue report and feature request
Change-Id: I00511b314bbc8a6c03a2ee1e6c626147bfe8f49d
2020-07-04 11:31:30 +02:00
Gonéri Le Bouder
9600baec6e security_group_rule: use OpenStackModule class
Refactoring of security_group_rule to depend on the OpenStackModule
class.

See: I487e79fe18c0b9a75df7dacd224ab40ed7f4e1ab

Change-Id: Ide09bdd6a57324a0e1d2ec29c4c49db8dc1c3843
2020-07-02 19:23:15 +00:00
Gonéri Le Bouder
abebbe722c keypair: make use of OpenStackModule class
Convert the keypair module to use the OpenStackModule class.

See: I487e79fe18c0b9a75df7dacd224ab40ed7f4e1ab

Change-Id: I60cd5811f1926f53a7f88b19889fba9ca39c6184
2020-07-02 13:59:36 -04:00
Zuul
94e518e42c Merge "Update author lines" 2020-06-24 15:30:26 +00:00
Monty Taylor
a96d28dfbc Update author lines
We don't use github, so having @ mentions of specific humans is
not valuable. Also, we are a team and own the modules as a team,
so calling out individual authors is philosophically contrary.

We landed a patch upstream to special-case this author string.

Change-Id: I38b4e68f14bbba6e13e8a50e2b202874ab74e3bc
2020-06-23 21:50:43 +03:00
Artem Goncharov
32ef77d9fd Add more useful information from exception
When the module faces API exception we can give much more useful
information to the user. Let us do this for the modules inheriting from
the base class, since all modules should do this at some point in time

Change-Id: I5f1ef01765829900334aa2ecae5dab3ba96f1a49
2020-06-23 18:43:09 +00:00
Sagi Shnaidman
4b64ebe623 Fix typos in job definitions
Change-Id: I654751a879482b1996c863470a6cf68f254eefbb
2020-06-23 16:23:54 +03:00
Sagi Shnaidman
01c2499fb6 New CI jobs configuration
Change-Id: Ib6850184faf1bc0808502c098d610a5e2f41f47e
2020-06-23 12:27:04 +03:00
Sagi Shnaidman
5e3a91a7c6 Add OpenstackModule to os_server_action
Redesign the module for more OOP
Add tests for server_action
Change-Id: I054de32ee3ff34988db53fc87b1cb63b8e551ae3
2020-06-17 12:59:23 +00:00
Sagi Shnaidman
fc852da4bc Fixes for modules generation script
Change-Id: Iffbb8e9f9106860f3d896f65831d2b9283ad1e7b
2020-06-17 13:35:10 +03:00
Sagi Shnaidman
5717f05102 Move action_group to runtime
from https://github.com/openstack/ansible-collections-openstack/pull/2

Change-Id: I82c68c31bccd54d5c2624bf2081820c09791b466
2020-06-17 10:17:23 +00:00
Sagi Shnaidman
4d0df9f022 Fix ansible-test errors
Add tox to requirements
Use only 3.6 python
Set ansible-test 2.9 as a gate job

Change-Id: I40757e1efc3ee297b44cda6c35cdce4c64ebaa4f
2020-06-17 12:53:05 +03:00
Zuul
f8c768ae61 Merge "Don't pass tenant_id for remote group" 2020-06-13 16:34:06 +00:00
Sagi Shnaidman
4d1017d5d9 Add note about py3 in readme
Change-Id: I7ac15d84d54e9ebc1260b633326e19b612a83170
2020-06-11 14:24:03 +00:00
Sagi Shnaidman
c75ab0924a Fix ansible-devel sanity tests for deprecations
Change-Id: I02c3f2cb5a8bb4c891a8f0e36628925208251bf7
2020-06-11 12:55:43 +03:00
Sagi Shnaidman
dfa7983a78 Add notes to README about deps and versions
Change-Id: Ied2ac325af5aee174fc0d20d9aada67a859fa81b
2020-06-09 14:33:40 +00:00
Sagi Shnaidman
8e2e5966b7 Don't pass tenant_id for remote group
When security group is from different project, don't pass tenant
Fixes https://github.com/ansible/ansible/issues/69673
Change-Id: I230c41d1ace179390744287102fead5ddf420157
2020-06-07 18:12:30 +00:00
Sagi Shnaidman
c9da50e7e7 Add setup.py for install with pip
Make possible installation with pip.
Change-Id: I8eec015142c4f29eadff0dac2781782b76dea308
2020-06-04 14:23:23 +00:00
Sagi Shnaidman
f3610ad0e1 Redesign OpenstackModule class
don't inherit OpenstackModule class from AnsibleModule class to
prevent occasional overriding Ansible methods or vars and failing
module.

Change-Id: Ic34fff0c938eb87cc0d2c5e98fbafed64bf349f6
2020-06-04 13:49:48 +03:00
Sagi Shnaidman
7e4fbcf568 Fix ansible-tests for devel branch
Ignore for now deprecation warnings
(see https://github.com/ansible-collections/overview/issues/45#issuecomment-628262697)
Current there are bugs in ansible-test that prevent to run these
tests.

Change-Id: I9829bb23a45699e61d7b0af5ecc3e1a94bbbca85
2020-06-03 00:05:07 +03:00
Zuul
f89644973d Merge "Add template for generation of artibtrary module" 2020-05-28 19:55:17 +00:00
Zuul
b4f015ebd7 Merge "Remove unnecessary requirements file" 2020-05-25 18:12:16 +00:00
Sagi Shnaidman
f0da22da7e Remove unnecessary requirements file
for reference:
https://github.com/ansible-collections/overview/issues/43
Change-Id: I0136b4d173cb7e1d45a2b4535d8772c68f8d5783
2020-05-25 14:43:18 +03:00
Matt Parkinson
d206ea000a Minor spelling fixes in floating_ip documentation
Change-Id: Ib888b4890ff91a9bccaaa1e8b582a478243e47a3
2020-05-25 13:38:25 +10:00
Sagi Shnaidman
5667600420 Add template for generation of artibtrary module
One is for resource changing module, like server start or delete,
second one is for info collection about a specific resource.

Change-Id: I78b35075111731fff2fd50837fa4e6e0c61c55a0
2020-05-25 02:27:40 +03:00
Sagi Shnaidman
98ce765383 Exclude docs and text files form CI jobs
Change-Id: I9645d05a65d8608d7e53ae107eed1f53cca0b0e9
2020-05-24 20:44:10 +03:00
94 changed files with 2456 additions and 905 deletions

View File

@@ -10,7 +10,7 @@
- openstack/ansible-collections-openstack
vars:
zuul_work_dir: src/opendev.org/openstack/ansible-collections-openstack
tox_envlist: ansible
tox_envlist: ansible-2.9
tox_install_siblings: true
fetch_subunit: false
@@ -21,46 +21,74 @@
Run openstack collections functional tests against a master devstack
using releases of openstacksdk and latest ansible release
vars:
tox_envlist: ansible-2.9
tox_install_siblings: false
- job:
name: ansible-collections-openstack-functional-devstack-ansible-2.10
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a master devstack
using master of openstacksdk and stable 2.10 branch of ansible
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.10
vars:
tox_envlist: ansible
- job:
name: ansible-collections-openstack-functional-devstack-ansible-2.9
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a master devstack
using master of openstacksdk and stable 2.9 branch of ansible
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.9
vars:
tox_envlist: ansible-2.9
- job:
name: ansible-collections-openstack-functional-devstack-ansible-devel
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a master devstack
using master of openstacksdk and devel branch of ansible
# non-voting because we can't prevent ansible devel from breaking us
voting: false
required-projects:
- name: github.com/ansible/ansible
override-checkout: devel
vars:
tox_envlist: ansible
# Pip installation job
- job:
name: ansible-collections-openstack-functional-devstack-ansible-2.9
parent: ansible-collections-openstack-functional-devstack-ansible-devel
name: ansible-collections-openstack-functional-devstack-ansible-pip
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a master devstack
using master of openstacksdk and stable 2.9 branch of ansible
using master of openstacksdk with latest ansible release.
Ansible collection is built using PIP.
vars:
tox_envlist: ansible-pip
# Stable branches
- job:
name: ansible-collections-openstack-functional-devstack-ussuri-ansible-2.9
parent: ansible-collections-openstack-functional-devstack-ansible-devel
description: |
Run openstack collections functional tests against a ussuri devstack
using ussuri brach of openstacksdk and stable 2.9 branch of ansible
voting: true
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.9
- job:
name: ansible-collections-openstack-functional-devstack-train-ansible-devel
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a train devstack
using train brach of openstacksdk and devel branch of ansible
# non-voting because we can't prevent ansible devel from breaking us
voting: false
required-projects:
- name: github.com/ansible/ansible
override-checkout: devel
- name: openstack/openstacksdk
override-branch: train
override-branch: ussuri
- name: openstack/devstack
override-checkout: train
override-checkout: ussuri
vars:
tox_envlist: ansible-2.9
- job:
name: ansible-collections-openstack-functional-devstack-train-ansible-2.9
@@ -76,22 +104,8 @@
override-branch: train
- name: openstack/devstack
override-checkout: train
- job:
name: ansible-collections-openstack-functional-devstack-stein-ansible-devel
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a stein devstack
using stein brach of openstacksdk and devel branch of ansible
# non-voting because we can't prevent ansible devel from breaking us
voting: false
required-projects:
- name: github.com/ansible/ansible
override-checkout: devel
- name: openstack/openstacksdk
override-branch: stein
- name: openstack/devstack
override-checkout: stein
vars:
tox_envlist: ansible-2.9
- job:
name: ansible-collections-openstack-functional-devstack-stein-ansible-2.9
@@ -107,22 +121,8 @@
override-branch: stein
- name: openstack/devstack
override-checkout: stein
- job:
name: ansible-collections-openstack-functional-devstack-rocky-ansible-devel
parent: ansible-collections-openstack-functional-devstack
description: |
Run openstack collections functional tests against a rocky devstack
using rocky brach of openstacksdk and devel branch of ansible
# non-voting because we can't prevent ansible devel from breaking us
voting: false
required-projects:
- name: github.com/ansible/ansible
override-checkout: devel
- name: openstack/openstacksdk
override-branch: rocky
- name: openstack/devstack
override-checkout: rocky
vars:
tox_envlist: ansible-2.9
- job:
name: ansible-collections-openstack-functional-devstack-rocky-ansible-2.9
@@ -138,6 +138,8 @@
override-branch: rocky
- name: openstack/devstack
override-checkout: rocky
vars:
tox_envlist: ansible-2.9
- job:
name: ansible-collections-openstack-functional-devstack-queens-ansible-2.9
@@ -153,7 +155,45 @@
override-branch: master
- name: openstack/devstack
override-checkout: queens
vars:
tox_envlist: ansible-2.9
- job:
name: ansible-collections-openstack-functional-devstack-queens-ansible-2.10
parent: ansible-collections-openstack-functional-devstack-ansible-devel
description: |
Run openstack collections functional tests against a queens devstack
using master brach of openstacksdk and stable 2.10 branch of ansible
voting: true
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.10
- name: openstack/openstacksdk
override-branch: master
- name: openstack/devstack
override-checkout: queens
vars:
tox_envlist: ansible
- job:
name: ansible-collections-openstack-functional-devstack-queens-ansible-devel
parent: ansible-collections-openstack-functional-devstack-ansible-devel
description: |
Run openstack collections functional tests against a queens devstack
using master brach of openstacksdk and devel branch of ansible
voting: true
required-projects:
- name: github.com/ansible/ansible
override-checkout: devel
- name: openstack/openstacksdk
override-branch: master
- name: openstack/devstack
override-checkout: queens
vars:
tox_envlist: ansible
# Linters
- job:
name: openstack-tox-linters-ansible-devel
parent: openstack-tox-linters
@@ -165,6 +205,16 @@
- name: github.com/ansible/ansible
override-checkout: devel
- job:
name: openstack-tox-linters-ansible-2.10
parent: openstack-tox-linters
description: |
Run openstack collections linter tests using the 2.10 branch of ansible
voting: true
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.10
- job:
name: openstack-tox-linters-ansible-2.9
parent: openstack-tox-linters
@@ -174,12 +224,28 @@
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.9
vars:
tox_envlist: linters-2.9
# Cross-checks with other projects
- job:
name: bifrost-collections-src
parent: bifrost-integration-tinyipa-ubuntu-bionic
required-projects:
- openstack/ansible-collections-openstack
- job:
name: bifrost-keystone-collections-src
parent: bifrost-integration-tinyipa-keystone-ubuntu-bionic
required-projects:
- openstack/ansible-collections-openstack
- project:
check:
jobs:
- tox-pep8
- openstack-tox-linters-ansible-devel
- openstack-tox-linters-ansible-2.10
- openstack-tox-linters-ansible-2.9
- ansible-collections-openstack-functional-devstack:
dependencies: &deps_unit_lint
@@ -189,34 +255,39 @@
- changelogs/.*
- COPYING
- docs/.*
- README.md
- .*\.md
- .*\.rst
- tools/run-ansible-sanity.sh
- tests/sanity/.*
- contrib/.*
- ansible-collections-openstack-functional-devstack-releases:
- ansible-collections-openstack-functional-devstack:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-ansible-devel:
- ansible-collections-openstack-functional-devstack-releases:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-ansible-2.9:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-train-ansible-devel:
- ansible-collections-openstack-functional-devstack-ansible-2.10:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-ansible-devel:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-ansible-pip:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.9:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-train-ansible-2.9:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-stein-ansible-devel:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-stein-ansible-2.9:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-rocky-ansible-devel:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.9:
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
@@ -224,16 +295,44 @@
dependencies: *deps_unit_lint
irrelevant-files: *ignore_files
- bifrost-collections-src:
voting: false
- bifrost-keystone-collections-src:
voting: false
gate:
jobs:
- tox-pep8
- openstack-tox-linters
- openstack-tox-linters-ansible-2.10
- openstack-tox-linters-ansible-2.9
- ansible-collections-openstack-functional-devstack
- ansible-collections-openstack-functional-devstack-releases
- ansible-collections-openstack-functional-devstack-ansible-2.9
- ansible-collections-openstack-functional-devstack-ansible-2.10
- ansible-collections-openstack-functional-devstack-ansible-pip
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.9
- ansible-collections-openstack-functional-devstack-train-ansible-2.9
- ansible-collections-openstack-functional-devstack-stein-ansible-2.9
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.9
- ansible-collections-openstack-functional-devstack-queens-ansible-2.9
periodic:
jobs:
- openstack-tox-linters-ansible-devel
- openstack-tox-linters-ansible-2.10
- openstack-tox-linters-ansible-2.9
- ansible-collections-openstack-functional-devstack
- ansible-collections-openstack-functional-devstack-releases
- ansible-collections-openstack-functional-devstack-ansible-2.9
- ansible-collections-openstack-functional-devstack-ansible-2.10
- ansible-collections-openstack-functional-devstack-ansible-devel
- ansible-collections-openstack-functional-devstack-ansible-pip
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.9
- ansible-collections-openstack-functional-devstack-train-ansible-2.9
- ansible-collections-openstack-functional-devstack-stein-ansible-2.9
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.9
- ansible-collections-openstack-functional-devstack-queens-ansible-2.9
- ansible-collections-openstack-functional-devstack-queens-ansible-2.10
- ansible-collections-openstack-functional-devstack-queens-ansible-devel
- bifrost-collections-src
- bifrost-keystone-collections-src

96
CHANGELOG.rst Normal file
View File

@@ -0,0 +1,96 @@
=============================================
Openstack Cloud Ansilbe modules Release Notes
=============================================
.. contents:: Topics
v1.1.0
======
Release Summary
---------------
Starting redesign modules and bugfixes.
Minor Changes
-------------
- A basic module subclass was introduced and a few modules moved to inherit from it.
- Add more useful information from exception
- Added pip installation option for collection.
- Added template for generation of artibtrary module.
- baremetal modules - Do not require ironic_url if cloud or auth.endpoint is provided
- inventory_openstack - Add openstack logger and Ansible display utility
- loadbalancer - Add support for setting the Flavor when creating a load balancer
Deprecated Features
-------------------
- foo - The bar option has been deprecated. Use the username option instead.
- send_request - The quic option has been deprecated. Use the protocol option instead.
Bugfixes
--------
- Fix non existing attribuites in SDK exception
- security_group_rule - Don't pass tenant_id for remote group
New Modules
-----------
- openstack.cloud.volume_info - Retrieve information about Openstack volumes.
v1.0.1
======
Release Summary
---------------
Bugfix for server_info
Bugfixes
--------
- server_info - Fix broken server_info module and add tests
v1.0.0
======
Release Summary
---------------
Initial release of collection.
Minor Changes
-------------
- Renaming all modules and removing "os" prefix from names.
- baremetal_node_action - Support json type for the ironic_node config_drive parameter
- config - Update os_client_config to use openstacksdk
- host_aggregate - Add support for not 'purging' missing hosts
- project - Add properties for os_project
- server_action - pass imageRef to rebuild
- subnet - Updated allocation pool checks
Bugfixes
--------
- baremetal_node - Correct parameter name
- coe_cluster - Retrive id/uuid correctly
- federation_mapping - Fixup some minor nits found in followup reviews
- inventory_openstack - Fix constructed compose
- network - Bump minimum openstacksdk version when using os_network/dns_domain
- role_assignment - Fix os_user_role for groups in multidomain context
- role_assignment - Fix os_user_role issue to grant a role in a domain
New Modules
-----------
- openstack.cloud.federation_idp - Add support for Keystone Identity Providers
- openstack.cloud.federation_idp_info - Add support for fetching the information about federation IDPs
- openstack.cloud.federation_mapping - Add support for Keystone mappings
- openstack.cloud.federation_mapping_info - Add support for fetching the information about Keystone mappings
- openstack.cloud.keystone_federation_protocol - Add support for Keystone federation Protocols
- openstack.cloud.keystone_federation_protocol_info - Add support for getting information about Keystone federation Protocols
- openstack.cloud.routers_info - Retrieve information about one or more OpenStack routers.

View File

@@ -9,6 +9,30 @@ The collection includes the Openstack modules and plugins supported by Openstack
## Installation and Usage
### Installing dependencies
For using Openstack Cloud collection firstly need to install `ansible` and `openstacksdk` Python modules on Ansible controller.
For example with pip:
```bash
pip install ansible openstacksdk
```
OpenStackSDK has to be available to Ansible and to the Python interpreter on the host, where Ansible executes the module (target host).
Please note, that under some circumstances Ansible might invoke not standard Python interpreter on the target host.
Using Python verison 3 is highly recommended for OpenstackSDK and strongly required from OpenstackSDK version 0.39.0.
---
#### NOTE
OpenstackSDK is better to be the last stable version. It should NOT be installed on Openstack nodes,
but rather on operators host (aka "Ansible controller"). OpenstackSDK from last version supports
operations on all Openstack cloud versions. Therefore OpenstackSDK module version doesn't have to match
Openstack cloud version usually.
---
### Installing the Collection from Ansible Galaxy
Before using the Openstack Cloud collection, you need to install the collection with the `ansible-galaxy` CLI:
@@ -65,7 +89,7 @@ For information on contributing, please see [CONTRIBUTING](https://opendev.org/o
There are many ways in which you can participate in the project, for example:
- Submit bugs and feature requests, and help us verify them
- Submit [bugs and feature requests](https://storyboard.openstack.org/#!/project/openstack/ansible-collections-openstack), and help us verify them
- Submit and review source code changes in [Openstack Gerrit](https://review.opendev.org/#/q/project:openstack/ansible-collections-openstack)
- Add new modules for Openstack Cloud

72
changelogs/changelog.yaml Normal file
View File

@@ -0,0 +1,72 @@
releases:
1.1.0:
release_date: '2020-08-17'
changes:
release_summary: Starting redesign modules and bugfixes.
minor_changes:
- Added changelog.
- A basic module subclass was introduced and a few modules moved to inherit from it.
- Added pip installation option for collection.
- Added template for generation of artibtrary module.
- Added more useful information from exception
- inventory_openstack - Add openstack logger and Ansible display utility
- loadbalancer - Add support for setting the Flavor when creating a load balancer
- baremetal modules - Do not require ironic_url if cloud or auth.endpoint is provided
deprecated_features:
- foo - The bar option has been deprecated. Use the username option instead.
- send_request - The quic option has been deprecated. Use the protocol option instead.
bugfixes:
- security_group_rule - Don't pass tenant_id for remote group
- Fix non existing attribuites in SDK exception
modules:
- name: volume_info
description: Retrieve information about Openstack volumes.
namespace: ''
1.0.1:
release_date: '2020-05-22'
changes:
release_summary: Bugfix for server_info
bugfixes:
- server_info - Fix broken server_info module and add tests
1.0.0:
release_date: '2020-05-19'
changes:
release_summary: Initial release of collection.
minor_changes:
- Renaming all modules and removing "os" prefix from names.
- server_action - pass imageRef to rebuild
- subnet - Updated allocation pool checks
- project - Add properties for os_project
- config - Update os_client_config to use openstacksdk
- host_aggregate - Add support for not 'purging' missing hosts
- baremetal_node_action - Support json type for the ironic_node config_drive parameter
bugfixes:
- federation_mapping - Fixup some minor nits found in followup reviews
- coe_cluster - Retrive id/uuid correctly
- baremetal_node - Correct parameter name
- network - Bump minimum openstacksdk version when using os_network/dns_domain
- inventory_openstack - Fix constructed compose
- role_assignment - Fix os_user_role for groups in multidomain context
- role_assignment - Fix os_user_role issue to grant a role in a domain
modules:
- name: keystone_federation_protocol_info
description: Add support for getting information about Keystone federation Protocols
namespace: ''
- name: keystone_federation_protocol
description: Add support for Keystone federation Protocols
namespace: ''
- name: federation_idp_info
description: Add support for fetching the information about federation IDPs
namespace: ''
- name: federation_idp
description: Add support for Keystone Identity Providers
namespace: ''
- name: federation_mapping_info
description: Add support for fetching the information about Keystone mappings
namespace: ''
- name: federation_mapping
description: Add support for Keystone mappings
namespace: ''
- name: routers_info
description: Retrieve information about one or more OpenStack routers.
namespace: ''

31
changelogs/config.yaml Normal file
View File

@@ -0,0 +1,31 @@
changelog_filename_template: ../CHANGELOG.rst
changelog_filename_version_depth: 0
changes_file: changelog.yaml
changes_format: combined
ignore_other_fragment_extensions: true
keep_fragments: false
mention_ancestor: true
new_plugins_after_name: removed_features
notesdir: fragments
prelude_section_name: release_summary
prelude_section_title: Release Summary
sections:
- - major_changes
- Major Changes
- - minor_changes
- Minor Changes
- - breaking_changes
- Breaking Changes / Porting Guide
- - deprecated_features
- Deprecated Features
- - removed_features
- Removed Features (previously deprecated)
- - security_fixes
- Security Fixes
- - bugfixes
- Bugfixes
- - known_issues
- Known Issues
title: Openstack Cloud Ansilbe modules
trivial_section_name: trivial
use_fqcn: true

View File

View File

@@ -1,3 +0,0 @@
bugfixes:
- Bump the minimum openstacksdk version to 0.18.0 when os_network
uses the port_security_enabled or mtu arguments.

View File

@@ -1,3 +0,0 @@
bugfixes:
- Bump the minimum openstacksdk version to 0.29.0 when os_network
uses the dns_domain argument.

View File

@@ -1,2 +0,0 @@
bugfixes:
- os_coe_cluster: Retrieve the correct id/uuid depending on whether it is a create/get request.

View File

@@ -1,2 +0,0 @@
minor_changes:
- Moved Openstack inventory script from Ansible community.general to openstack collection.

View File

@@ -17,6 +17,12 @@
- name: Get info about all servers
openstack.cloud.server_info:
cloud: "{{ cloud }}"
register: info
- name: Check info about servers
assert:
that:
info.openstack_servers|length > 0
- name: Delete server with meta as CSV
openstack.cloud.server:
@@ -25,6 +31,16 @@
name: "{{ server_name }}"
wait: true
- name: Get info about all servers
openstack.cloud.server_info:
cloud: "{{ cloud }}"
register: info
- name: Check info about no servers
assert:
that:
info.openstack_servers|length == 0
- name: Create server with meta as dict
openstack.cloud.server:
cloud: "{{ cloud }}"
@@ -46,6 +62,12 @@
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info
- name: Check info about server name
assert:
that:
info.openstack_servers[0].name == "{{ server_name }}"
- name: Delete server with meta as dict
openstack.cloud.server:
@@ -74,6 +96,12 @@
cloud: "{{ cloud }}"
server: "{{ server_name }}"
detailed: true
register: info
- name: Check info about server image name
assert:
that:
info.openstack_servers[0].image.name == "{{ image }}"
- name: Delete server (FIP from pool/network)
openstack.cloud.server:
@@ -99,11 +127,28 @@
- debug: var=server
- name: Get info about servers in all projects
openstack.cloud.server_info:
cloud: "{{ cloud }}"
all_projects: true
register: info
- name: Check info about servers in all projects
assert:
that:
info.openstack_servers|length > 0
- name: Get info about one server in all projects
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
all_projects: true
register: info
- name: Check info about one server in all projects
assert:
that:
info.openstack_servers|length > 0
- name: Delete server with volume
openstack.cloud.server:
@@ -111,3 +156,5 @@
state: absent
name: "{{ server_name }}"
wait: true
- include_tasks: server_actions.yml

View File

@@ -0,0 +1,408 @@
- name: Create server
openstack.cloud.server:
cloud: "{{ cloud }}"
state: present
name: "{{ server_name }}"
image: "{{ image }}"
flavor: "{{ flavor }}"
network: "{{ server_network }}"
auto_floating_ip: false
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info1
- name: Ensure status for server is ACTIVE
assert:
that:
- info1.openstack_servers.0.status == 'ACTIVE'
- name: Stop server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: stop
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info2
- name: Ensure status for server is SHUTOFF
assert:
that:
- info2.openstack_servers.0.status == 'SHUTOFF'
- server is changed
- name: Stop server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: stop
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info3
- name: Ensure status for server is SHUTOFF
assert:
that:
- info3.openstack_servers.0.status == 'SHUTOFF'
- server is not changed
- name: Start server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: start
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info4
- name: Ensure status for server is ACTIVE
assert:
that:
- info4.openstack_servers.0.status == 'ACTIVE'
- server is changed
- name: Start server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: start
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info5
- name: Ensure status for server is ACTIVE
assert:
that:
- info5.openstack_servers.0.status == 'ACTIVE'
- server is not changed
- name: Pause server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: pause
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info6
- name: Ensure status for server is PAUSED
assert:
that:
- info6.openstack_servers.0.status == 'PAUSED'
- server is changed
- name: Pause server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: pause
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info7
- name: Ensure status for server is PAUSED
assert:
that:
- info7.openstack_servers.0.status == 'PAUSED'
- server is not changed
- name: Unpause server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: unpause
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info8
- name: Ensure status for server is ACTIVE
assert:
that:
- info8.openstack_servers.0.status == 'ACTIVE'
- server is changed
- name: Unpause server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: unpause
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info9
- name: Ensure status for server is ACTIVE
assert:
that:
- info9.openstack_servers.0.status == 'ACTIVE'
- server is not changed
- name: Lock server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: lock
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info10
- name: Ensure status for server is ACTIVE
assert:
that:
- info10.openstack_servers.0.status == 'ACTIVE'
# not in all versions 'locked' is supported
- info10.openstack_servers.0.locked in (None, True)
- server is changed
- name: Lock server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: lock
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info11
- name: Ensure status for server is ACTIVE
assert:
that:
- info11.openstack_servers.0.status == 'ACTIVE'
# not in all versions 'locked' is supported
- info11.openstack_servers.0.locked in (None, True)
- server is changed # no support for lock idempotency
- name: Unock server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: unlock
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info12
- name: Ensure status for server is ACTIVE
assert:
that:
- info12.openstack_servers.0.status == 'ACTIVE'
# not in all versions 'locked' is supported
- info12.openstack_servers.0.locked in (None, False)
- server is changed
- name: Unlock server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: unlock
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info13
- name: Ensure status for server is ACTIVE
assert:
that:
- info13.openstack_servers.0.status == 'ACTIVE'
- server is changed # no support for unlock idempotency
# not in all versions 'locked' is supported
- info13.openstack_servers.0.locked in (None, False)
- name: Suspend server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: suspend
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info14
- name: Ensure status for server is SUSPENDED
assert:
that:
- info14.openstack_servers.0.status == 'SUSPENDED'
- server is changed
- name: Suspend server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: suspend
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info15
- name: Ensure status for server is SUSPENDED
assert:
that:
- info15.openstack_servers.0.status == 'SUSPENDED'
- server is not changed
- name: Resume server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: resume
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info16
- name: Ensure status for server is ACTIVE
assert:
that:
- info16.openstack_servers.0.status == 'ACTIVE'
- server is changed
- name: Resume server again
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: resume
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info17
- name: Ensure status for server is ACTIVE
assert:
that:
- info17.openstack_servers.0.status == 'ACTIVE'
- server is not changed
- name: Rebuild server - error
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
action: rebuild
wait: true
register: server
ignore_errors: true
- name: Ensure server rebuild failed
assert:
that:
- server is failed
- "'missing: image' in server.msg "
- name: Rebuild server
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
image: "{{ image }}"
action: rebuild
wait: true
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info18
- name: Ensure status for server is ACTIVE
assert:
that:
- info18.openstack_servers.0.status in ('ACTIVE', 'REBUILD')
- server is changed
- name: Rebuild server with admin password
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
image: "{{ image }}"
action: rebuild
wait: true
admin_password: random
register: server
- name: Get info about server
openstack.cloud.server_info:
cloud: "{{ cloud }}"
server: "{{ server_name }}"
register: info19
- name: Ensure status for server is ACTIVE
assert:
that:
- info19.openstack_servers.0.status in ('ACTIVE', 'REBUILD')
- server is changed

View File

@@ -54,6 +54,16 @@ fi
shift $((OPTIND-1))
TAGS=$( echo "$*" | tr ' ' , )
# Install collections before dealing with Ansible virtual environments
if [[ -z "$PIP_INSTALL" ]]; then
tox -ebuild
ansible-galaxy collection install $(ls build_artifact/openstack-cloud-*) --force
TEST_COLLECTIONS_PATHS=${HOME}/.ansible/collections:$ANSIBLE_COLLECTIONS_PATHS
else
pip freeze | grep ansible-collections-openstack
TEST_COLLECTIONS_PATHS=$VIRTUAL_ENV/share/ansible/collections:$ANSIBLE_COLLECTIONS_PATHS
fi
# We need to source the current tox environment so that Ansible will
# be setup for the correct python environment.
source $ENVDIR/bin/activate
@@ -96,15 +106,11 @@ then
exit 1
fi
# install collections
tox -ebuild
ansible-galaxy collection build --force . --output-path ./build_artifact
ansible-galaxy collection install $(ls build_artifact/openstack-cloud-*) --force
# Discover openstackSDK version
SDK_VER=$(python -c "import openstack; print(openstack.version.__version__)")
pushd ci/
# run tests
ANSIBLE_COLLECTIONS_PATHS=${HOME}/.ansible/collections ansible-playbook \
ANSIBLE_COLLECTIONS_PATHS=$TEST_COLLECTIONS_PATHS ansible-playbook \
-vvv ./run-collection.yml \
-e "sdk_version=${SDK_VER} cloud=${CLOUD} image=${IMAGE} ${ANSIBLE_VARS}" \
${tag_opt}

5
contrib/generate_module.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
# For resource changing module
ansible localhost -c local -m template -a "src=module_template.py.j2 dest=my_module.py" -e @module_template_vars.yaml
# For resource info collection module
ansible localhost -c local -m template -a "src=module_info_template.py.j2 dest=my_module_info.py" -e @module_template_vars.yaml

View File

@@ -0,0 +1,110 @@
#!/usr/bin/python
# coding: utf-8 -*-
# Copyright (c) 2020, {{ author_name }} <{{ author_mail }}>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = '''
---
module: {{ module_name }}
short_description: {{ module_short_description }}
author: OpenStack Ansible SIG
description:
- {{ module_long_description }}
options:
{{ options|to_nice_yaml(indent=2,sort_keys=false)|indent(width=2)|trim }}
requirements:
- "python >= 3.6"
- "openstacksdk"
extends_documentation_fragment:
- openstack.cloud.openstack
'''
RETURN = '''
{{ module_returns_example|to_nice_yaml(indent=2,sort_keys=false) }}
'''
EXAMPLES = '''
# What modules does for example
- {{ module_name }}:
name:
- name1
- name2
timeout: 200
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class {{ module_name.split("_")|map("capitalize")|list|join("") }}Module(OpenStackModule):
argument_spec = dict(
{% for k, v in options.items() %}
{{ k | indent( width=8, indentfirst=True) }}=dict(type='{{ v.type }}'
{%- if 'required' in v %}, required={{ v.required }}{% endif %}
{%- if 'elements' in v %}, elements={{ v.elements }}{% endif %}
{%- if 'default' in v %}, default={% if v.type == 'str' %}"{{ v.default }}"{% else %}{{ v.default }}{% endif %}{% endif %}
{%- if 'aliases' in v %}, aliases={{ v.aliases }}{% endif %}
{%- if 'choices' in v %}, choices={{ v.choices }}{% endif %}),
{% endfor %}
),
# Optional arguments requirements
module_kwargs = dict(
required_if=[
['action', 'rebuild', ['image']], # if need to rebuild image (only), the 'image' is required
["state", "present", ["username", "user_roles"]], # for creating user 'user_roles' is required
["state", "absent", ["username"]], # for state 'absent' only username is required
],
required_by=dict( # for weather and population 'city' is required to set
weather=('city'),
population=('city'),
),
mutually_exclusive=[
['use_cloud1', 'use_cloud2'] # can't run on both, choose only one to set
],
required_together=[
['remove_image', 'image_name'] # if need to remove image, must to specify which one
],
required_one_of_args=[["password", "password_hash"]], # one of these args must be set
supports_check_mode={{ check_mode_support }}, # good practice is to support check_mode
)
# you main funciton is here
def run(self):
# do any arguments check if needed
data = self.preliminary_checks()
# check if we need to prepare various filters for results
filters = self.prepare_filters()
# run SDK call to get information about requested resource
result = self.conn.compute.resource_list(
filters=filters,
detailed=self.params['detailed'],
# any other parameters
)
# process results if they require a change
result = self.normalize_result()
self.results.update({'resource_name': result})
def preliminary_checks(self):
# you checks before running like arguments and options checks, etc
return data
def prepare_filters(self):
# process filters if they require additional checks
return filters
def normalize_result(self):
# process filters if they require additional checks
return result
def main():
module = {{ module_name.split("_")|map("capitalize")|list|join("") }}Module()
module()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,149 @@
#!/usr/bin/python
# coding: utf-8 -*-
# Copyright (c) 2020, {{ author_name }} <{{ author_mail }}>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = '''
---
module: {{ module_name }}
short_description: {{ module_short_description }}
author: OpenStack Ansible SIG
description:
- {{ module_long_description }}
options:
{{ options|to_nice_yaml(indent=2,sort_keys=false)|indent(width=2)|trim }}
requirements:
- "python >= 3.6"
- "openstacksdk"
extends_documentation_fragment:
- openstack.cloud.openstack
'''
RETURN = '''
{{ module_returns_example|to_nice_yaml(indent=2,sort_keys=false) }}
'''
EXAMPLES = '''
# What modules does for example
- {{ module_name }}:
action: pause
auth:
auth_url: https://identity.example.com
username: admin
password: admin
project_name: admin
server: vm1
timeout: 200
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class {{ module_name.split("_")|map("capitalize")|list|join("") }}Module(OpenStackModule):
argument_spec = dict(
{% for k, v in options.items() %}
{{ k | indent( width=8, indentfirst=True) }}=dict(type='{{ v.type }}'
{%- if 'required' in v %}, required={{ v.required }}{% endif %}
{%- if 'elements' in v %}, elements={{ v.elements }}{% endif %}
{%- if 'default' in v %}, default={% if v.type == 'str' %}"{{ v.default }}"{% else %}{{ v.default }}{% endif %}{% endif %}
{%- if 'aliases' in v %}, aliases={{ v.aliases }}{% endif %}
{%- if 'choices' in v %}, choices={{ v.choices }}{% endif %}),
{% endfor %}
),
# Optional arguments requirements
module_kwargs = dict(
required_if=[
['action', 'rebuild', ['image']], # if need to rebuild image (only), the 'image' is required
["state", "present", ["username", "user_roles"]], # for creating user 'user_roles' is required
["state", "absent", ["username"]], # for state 'absent' only username is required
],
required_by=dict( # for weather and population 'city' is required to set
weather=('city'),
population=('city'),
),
mutually_exclusive=[
['use_cloud1', 'use_cloud2'] # can't run on both, choose only one to set
],
required_together=[
['remove_image', 'image_name'] # if need to remove image, must to specify which one
],
required_one_of_args=[["password", "password_hash"]], # one of these args must be set
supports_check_mode={{ check_mode_support }}, # good practice is to support check_mode
)
# you main funciton is here
def run(self):
# do any arguments check if needed
data = self.preliminary_checks()
# check if we need to run or the resource is in desired state already
must_run = self.check_mode_test()
# if the resource is good
if not must_run:
# updated returned results if need
self.results.update({"returning_data": some_data})
# returning {changed: False, ...} because we didn't change resource
self.exit_json(self.results)
# do something if must to run the module
self.execute()
def preliminary_checks(self):
# you checks before running like arguments and options checks, etc
return data
def check_mode_test(self):
# check the idempotency - does module should do anything or
# it's already in the desired state?
return must_run
def execute(self):
# doing here what should be done, using OpenstackSDK
# for example actions for resource:
# self.params['action'] = "rebuild"
action_name = self.params['action'] + "_resource" # action_name='rebuild_resource'
try:
# find a method "rebuild_resource" in openstack SDK compute:
func_name = getattr(self.conn.compute, action_name)
# found self.conn.compute.rebuild_resource
except AttributeError:
self.fail_json(
msg="Method %s wasn't found in OpenstackSDK compute" % action_name)
summary = func_name(data) # summary = self.conn.compute.rebuild_resource(data)
self.results.update({"returning_data": summary})
# that's it, exiting, results will be returned from module automatically
# another option for states
def execute_with_action_map(self):
actions_map = {
'start': self._start_resource,
'stop': self._stop_resource,
'restart': self._restart_resource,
'absent': self._absent_resource,
}
summary = actions_map(self.params['action'])() # summary = self.start_resource()
self.results.update({"changed": True, "data2return": summary})
def _start_resource(self, some_other_data):
pass
def _stop_resource(self, some_other_data):
pass
def _restart_resource(self, some_other_data):
pass
def _absent_resource(self, some_other_data):
pass
def main():
module = {{ module_name.split("_")|map("capitalize")|list|join("") }}Module()
module()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,81 @@
##### PLEASE READ BEFORE #####
# Module format and documentation
# https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#module-format-and-documentation
module_name: server_manage
author_name: 'Happy Ansible User'
author_mail: dontwriteme@example.com
module_short_description: "Doing something very useful"
module_long_description: "Here is the place to release your inner writer"
check_mode_support: True # good practice to support check_mode:
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html#check-mode-dry-run
module_returns_example:
image:
description: Image inspection results for the image that was pulled, pushed, or built.
returned: always # or 'success' in case of success only
type: dict
sample:
Image Name: Sample Image
Image ID: e6471d00796a13de8142c15d7ad3a44f
Nested:
images list:
- data 1
- image 1234
boolean_1: True
options:
optional_string:
description:
- This variable is set for having string argument, for example 'action'
type: str
required: true
default: "my_lovely_action"
choices:
- allowed_option1
- allowed_option1
optional_boolean:
description:
- This variable is set for having a boolean argument, for example whether
to wait for resource creation or not
type: bool
required: false # may be omitted if false
# and no default because not required
optional_integer:
description:
- This variable is set for having a integer argument, for example how many
seconds to wait for the resource to come alive
required: true
default: 60
type: int
aliases: # sometimes we allow to pass the same option with different name
- old_optional_integer_name
- different_option_name
optional_list:
description:
- This variable is set for having a list argument, for example files need
to create with the resource
type: list
elements: str # type of elements of the list, can be dict, str, int, list
optional_dictionary:
description:
- This variable is set for having a dictionary argument, for example to
set environment variables or to pass more complex data to SDK
required: true
default: {}
type: dict
suboptions:
suboption_1:
description:
- suboption_1 description, what it does
type: str
aliases:
- suboption_1_another_name
suboption_2:
description:
- suboption_2 description, what it does
type: list
elements: str
default: []

View File

@@ -1,269 +0,0 @@
openstack:
- auth
- baremetal_inspect
- baremetal_inspect
- baremetal_node
- baremetal_node
- baremetal_node_action
- baremetal_node_action
- catalog_endpoint
- catalog_service
- catalog_service
- coe_cluster
- coe_cluster_template
- compute_flavor
- compute_flavor
- compute_flavor
- compute_flavor_info
- compute_flavor_info
- config
- config
- dns_zone
- dns_zone
- endpoint
- endpoint
- federation_idp
- federation_idp
- federation_idp_info
- federation_idp_info
- federation_mapping
- federation_mapping
- federation_mapping_info
- federation_mapping_info
- floating_ip
- group_assignment
- group_assignment
- host_aggregate
- host_aggregate
- identity_domain
- identity_domain
- identity_domain_info
- identity_domain_info
- identity_group
- identity_group
- identity_group_info
- identity_group_info
- identity_role
- identity_role
- identity_user
- identity_user
- identity_user_info
- identity_user_info
- image
- image_info
- keypair
- keystone_federation_protocol
- keystone_federation_protocol_info
- lb_listener
- lb_listener
- lb_member
- lb_member
- lb_pool
- lb_pool
- loadbalancer
- network
- networks_info
- object
- port
- port_info
- project
- project_access
- project_info
- quota
- recordset
- role_assignment
- role_assignment
- router
- routers_info
- security_group
- security_group_rule
- server
- server_action
- server_group
- server_info
- server_metadata
- server_volume
- stack
- subnet
- subnets_info
- volume
- volume_snapshot
os:
- auth
- baremetal_inspect
- baremetal_inspect
- baremetal_node
- baremetal_node
- baremetal_node_action
- baremetal_node_action
- catalog_endpoint
- catalog_service
- catalog_service
- coe_cluster
- coe_cluster_template
- compute_flavor
- compute_flavor
- compute_flavor
- compute_flavor_info
- compute_flavor_info
- config
- config
- dns_zone
- dns_zone
- endpoint
- endpoint
- federation_idp
- federation_idp
- federation_idp_info
- federation_idp_info
- federation_mapping
- federation_mapping
- federation_mapping_info
- federation_mapping_info
- floating_ip
- group_assignment
- group_assignment
- host_aggregate
- host_aggregate
- identity_domain
- identity_domain
- identity_domain_info
- identity_domain_info
- identity_group
- identity_group
- identity_group_info
- identity_group_info
- identity_role
- identity_role
- identity_user
- identity_user
- identity_user_info
- identity_user_info
- image
- image_info
- keypair
- keystone_federation_protocol
- keystone_federation_protocol_info
- lb_listener
- lb_listener
- lb_member
- lb_member
- lb_pool
- lb_pool
- loadbalancer
- network
- networks_info
- object
- port
- port_info
- project
- project_access
- project_info
- quota
- recordset
- role_assignment
- role_assignment
- router
- routers_info
- security_group
- security_group_rule
- server
- server_action
- server_group
- server_info
- server_metadata
- server_volume
- stack
- subnet
- subnets_info
- volume
- volume_snapshot
- os_auth
- os_client_config
- os_client_config
- os_coe_cluster
- os_coe_cluster_template
- os_endpoint
- os_flavor
- os_flavor_info
- os_flavor_info
- os_floating_ip
- os_group
- os_group
- os_group_info
- os_group_info
- os_image
- os_image_info
- os_ironic
- os_ironic
- os_ironic_inspect
- os_ironic_inspect
- os_ironic_node
- os_ironic_node
- os_keypair
- os_keystone_domain
- os_keystone_domain
- os_keystone_domain_info
- os_keystone_domain_info
- os_keystone_endpoint
- os_keystone_endpoint
- os_keystone_federation_protocol
- os_keystone_federation_protocol_info
- os_keystone_identity_provider
- os_keystone_identity_provider
- os_keystone_identity_provider_info
- os_keystone_identity_provider_info
- os_keystone_mapping
- os_keystone_mapping
- os_keystone_mapping_info
- os_keystone_mapping_info
- os_keystone_role
- os_keystone_role
- os_keystone_service
- os_keystone_service
- os_listener
- os_listener
- os_loadbalancer
- os_member
- os_member
- os_network
- os_networks_info
- os_nova_flavor
- os_nova_flavor
- os_nova_host_aggregate
- os_nova_host_aggregate
- os_object
- os_pool
- os_pool
- os_port
- os_port_info
- os_project
- os_project_access
- os_project_info
- os_quota
- os_recordset
- os_router
- os_routers_info
- os_security_group
- os_security_group_rule
- os_server
- os_server_action
- os_server_group
- os_server_info
- os_server_metadata
- os_server_volume
- os_stack
- os_subnet
- os_subnets_info
- os_user
- os_user
- os_user_group
- os_user_group
- os_user_info
- os_user_info
- os_user_role
- os_user_role
- os_volume
- os_volume_snapshot
- os_zone
- os_zone

View File

@@ -1,317 +1,590 @@
action_groups:
openstack:
- auth
- baremetal_inspect
- baremetal_inspect
- baremetal_node
- baremetal_node
- baremetal_node_action
- baremetal_node_action
- catalog_endpoint
- catalog_service
- catalog_service
- coe_cluster
- coe_cluster_template
- compute_flavor
- compute_flavor
- compute_flavor
- compute_flavor_info
- compute_flavor_info
- config
- config
- dns_zone
- dns_zone
- endpoint
- endpoint
- federation_idp
- federation_idp
- federation_idp_info
- federation_idp_info
- federation_mapping
- federation_mapping
- federation_mapping_info
- federation_mapping_info
- floating_ip
- group_assignment
- group_assignment
- host_aggregate
- host_aggregate
- identity_domain
- identity_domain
- identity_domain_info
- identity_domain_info
- identity_group
- identity_group
- identity_group_info
- identity_group_info
- identity_role
- identity_role
- identity_user
- identity_user
- identity_user_info
- identity_user_info
- image
- image_info
- keypair
- keystone_federation_protocol
- keystone_federation_protocol_info
- lb_listener
- lb_listener
- lb_member
- lb_member
- lb_pool
- lb_pool
- loadbalancer
- network
- networks_info
- object
- port
- port_info
- project
- project_access
- project_info
- quota
- recordset
- role_assignment
- role_assignment
- router
- routers_info
- security_group
- security_group_rule
- server
- server_action
- server_group
- server_info
- server_metadata
- server_volume
- stack
- subnet
- subnets_info
- volume
- volume_info
- volume_snapshot
os:
- auth
- baremetal_inspect
- baremetal_inspect
- baremetal_node
- baremetal_node
- baremetal_node_action
- baremetal_node_action
- catalog_endpoint
- catalog_service
- catalog_service
- coe_cluster
- coe_cluster_template
- compute_flavor
- compute_flavor
- compute_flavor
- compute_flavor_info
- compute_flavor_info
- config
- config
- dns_zone
- dns_zone
- endpoint
- endpoint
- federation_idp
- federation_idp
- federation_idp_info
- federation_idp_info
- federation_mapping
- federation_mapping
- federation_mapping_info
- federation_mapping_info
- floating_ip
- group_assignment
- group_assignment
- host_aggregate
- host_aggregate
- identity_domain
- identity_domain
- identity_domain_info
- identity_domain_info
- identity_group
- identity_group
- identity_group_info
- identity_group_info
- identity_role
- identity_role
- identity_user
- identity_user
- identity_user_info
- identity_user_info
- image
- image_info
- keypair
- keystone_federation_protocol
- keystone_federation_protocol_info
- lb_listener
- lb_listener
- lb_member
- lb_member
- lb_pool
- lb_pool
- loadbalancer
- network
- networks_info
- object
- port
- port_info
- project
- project_access
- project_info
- quota
- recordset
- role_assignment
- role_assignment
- router
- routers_info
- security_group
- security_group_rule
- server
- server_action
- server_group
- server_info
- server_metadata
- server_volume
- stack
- subnet
- subnets_info
- volume
- volume_info
- volume_snapshot
- os_auth
- os_client_config
- os_client_config
- os_coe_cluster
- os_coe_cluster_template
- os_endpoint
- os_flavor
- os_flavor_info
- os_flavor_info
- os_floating_ip
- os_group
- os_group
- os_group_info
- os_group_info
- os_image
- os_image_info
- os_ironic
- os_ironic
- os_ironic_inspect
- os_ironic_inspect
- os_ironic_node
- os_ironic_node
- os_keypair
- os_keystone_domain
- os_keystone_domain
- os_keystone_domain_info
- os_keystone_domain_info
- os_keystone_endpoint
- os_keystone_endpoint
- os_keystone_federation_protocol
- os_keystone_federation_protocol_info
- os_keystone_identity_provider
- os_keystone_identity_provider
- os_keystone_identity_provider_info
- os_keystone_identity_provider_info
- os_keystone_mapping
- os_keystone_mapping
- os_keystone_mapping_info
- os_keystone_mapping_info
- os_keystone_role
- os_keystone_role
- os_keystone_service
- os_keystone_service
- os_listener
- os_listener
- os_loadbalancer
- os_member
- os_member
- os_network
- os_networks_info
- os_nova_flavor
- os_nova_flavor
- os_nova_host_aggregate
- os_nova_host_aggregate
- os_object
- os_pool
- os_pool
- os_port
- os_port_info
- os_project
- os_project_access
- os_project_info
- os_quota
- os_recordset
- os_router
- os_routers_info
- os_security_group
- os_security_group_rule
- os_server
- os_server_action
- os_server_group
- os_server_info
- os_server_metadata
- os_server_volume
- os_stack
- os_subnet
- os_subnets_info
- os_user
- os_user
- os_user_group
- os_user_group
- os_user_info
- os_user_info
- os_user_role
- os_user_role
- os_volume
- os_volume_snapshot
- os_zone
- os_zone
plugin_routing:
modules:
os_auth:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.auth
redirect: openstack.cloud.auth
os_client_config:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.config
redirect: openstack.cloud.config
os_coe_cluster:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.coe_cluster
redirect: openstack.cloud.coe_cluster
os_coe_cluster_template:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.coe_cluster_template
redirect: openstack.cloud.coe_cluster_template
os_endpoint:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.catalog_endpoint
redirect: openstack.cloud.catalog_endpoint
os_flavor:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.compute_flavor
redirect: openstack.cloud.compute_flavor
os_flavor_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.compute_flavor_info
redirect: openstack.cloud.compute_flavor_info
os_floating_ip:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.floating_ip
redirect: openstack.cloud.floating_ip
os_group:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_group
redirect: openstack.cloud.identity_group
os_group_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_group_info
redirect: openstack.cloud.identity_group_info
os_image:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.image
redirect: openstack.cloud.image
os_image_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.image_info
redirect: openstack.cloud.image_info
os_ironic:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.baremetal_node
redirect: openstack.cloud.baremetal_node
os_ironic_inspect:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.baremetal_inspect
redirect: openstack.cloud.baremetal_inspect
os_ironic_node:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.baremetal_node_action
redirect: openstack.cloud.baremetal_node_action
os_keypair:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.keypair
redirect: openstack.cloud.keypair
os_keystone_domain:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_domain
redirect: openstack.cloud.identity_domain
os_keystone_domain_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_domain_info
redirect: openstack.cloud.identity_domain_info
os_keystone_endpoint:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.endpoint
redirect: openstack.cloud.endpoint
os_keystone_federation_protocol:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.keystone_federation_protocol
redirect: openstack.cloud.keystone_federation_protocol
os_keystone_federation_protocol_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.keystone_federation_protocol_info
redirect: openstack.cloud.keystone_federation_protocol_info
os_keystone_identity_provider:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.federation_idp
redirect: openstack.cloud.federation_idp
os_keystone_identity_provider_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.federation_idp_info
redirect: openstack.cloud.federation_idp_info
os_keystone_mapping:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.federation_mapping
redirect: openstack.cloud.federation_mapping
os_keystone_mapping_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.federation_mapping_info
redirect: openstack.cloud.federation_mapping_info
os_keystone_role:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_role
redirect: openstack.cloud.identity_role
os_keystone_service:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.catalog_service
redirect: openstack.cloud.catalog_service
os_listener:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.lb_listener
redirect: openstack.cloud.lb_listener
os_loadbalancer:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.loadbalancer
redirect: openstack.cloud.loadbalancer
os_member:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.lb_member
redirect: openstack.cloud.lb_member
os_network:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.network
redirect: openstack.cloud.network
os_networks_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.networks_info
redirect: openstack.cloud.networks_info
os_nova_flavor:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.compute_flavor
redirect: openstack.cloud.compute_flavor
os_nova_host_aggregate:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.host_aggregate
redirect: openstack.cloud.host_aggregate
os_object:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.object
redirect: openstack.cloud.object
os_pool:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.lb_pool
redirect: openstack.cloud.lb_pool
os_port:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.port
redirect: openstack.cloud.port
os_port_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.port_info
redirect: openstack.cloud.port_info
os_project:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.project
redirect: openstack.cloud.project
os_project_access:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.project_access
redirect: openstack.cloud.project_access
os_project_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.project_info
redirect: openstack.cloud.project_info
os_quota:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.quota
redirect: openstack.cloud.quota
os_recordset:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.recordset
redirect: openstack.cloud.recordset
os_router:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.router
redirect: openstack.cloud.router
os_routers_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.routers_info
redirect: openstack.cloud.routers_info
os_security_group:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.security_group
redirect: openstack.cloud.security_group
os_security_group_rule:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.security_group_rule
redirect: openstack.cloud.security_group_rule
os_server:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.server
redirect: openstack.cloud.server
os_server_action:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.server_action
redirect: openstack.cloud.server_action
os_server_group:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.server_group
redirect: openstack.cloud.server_group
os_server_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.server_info
redirect: openstack.cloud.server_info
os_server_metadata:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.server_metadata
redirect: openstack.cloud.server_metadata
os_server_volume:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.server_volume
redirect: openstack.cloud.server_volume
os_stack:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.stack
redirect: openstack.cloud.stack
os_subnet:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.subnet
redirect: openstack.cloud.subnet
os_subnets_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.subnets_info
redirect: openstack.cloud.subnets_info
os_user:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_user
redirect: openstack.cloud.identity_user
os_user_group:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.group_assignment
redirect: openstack.cloud.group_assignment
os_user_info:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.identity_user_info
redirect: openstack.cloud.identity_user_info
os_user_role:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.role_assignment
redirect: openstack.cloud.role_assignment
os_volume:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.volume
redirect: openstack.cloud.volume
os_volume_snapshot:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.volume_snapshot
redirect: openstack.cloud.volume_snapshot
os_zone:
deprecation:
removal_date: TBD
removal_date: 2021-12-12
warning_text: os_ prefixed module names are deprecated, use openstack.cloud.dns_zone
redirect: openstack.cloud.dns_zone

View File

@@ -10,9 +10,7 @@ DOCUMENTATION = '''
---
name: openstack
plugin_type: inventory
author:
- "Marco Vito Moscaritolo <marco@agavee.com>"
- "Jesse Keating <jesse.keating@rackspace.com>"
author: OpenStack Ansible SIG
short_description: OpenStack inventory source
requirements:
- "openstacksdk >= 0.28"
@@ -118,9 +116,14 @@ all_projects: yes
import collections
import sys
import logging
from ansible.errors import AnsibleParserError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.utils.display import Display
display = Display()
os_logger = logging.getLogger("openstack")
try:
# Due to the name shadowing we should import other way
@@ -128,8 +131,10 @@ try:
sdk = importlib.import_module('openstack')
sdk_inventory = importlib.import_module('openstack.cloud.inventory')
client_config = importlib.import_module('openstack.config.loader')
sdk_exceptions = importlib.import_module("openstack.exceptions")
HAS_SDK = True
except ImportError:
display.vvvv("Couldn't import Openstack SDK modules")
HAS_SDK = False
@@ -158,11 +163,14 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
msg = "openstacksdk is required for the OpenStack inventory plugin. OpenStack inventory sources will be skipped."
if msg:
display.vvvv(msg)
raise AnsibleParserError(msg)
# The user has pointed us at a clouds.yaml file. Use defaults for
# everything.
if 'clouds' in self._config_data:
self.display.vvvv(
"Found clouds config file instead of plugin config. "
"Using default configuration."
)
self._config_data = {}
# update cache if the user has caching enabled and the cache is being refreshed
@@ -173,13 +181,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
cache = self.get_option('cache')
source_data = None
if cache:
self.display.vvvv("Reading inventory data from cache: %s" % cache_key)
try:
source_data = self._cache[cache_key]
except KeyError:
# cache expired or doesn't exist yet
display.vvvv("Inventory data cache not found")
cache_needs_update = True
if not source_data:
self.display.vvvv("Getting hosts from Openstack clouds")
clouds_yaml_path = self._config_data.get('clouds_yaml_path')
if clouds_yaml_path:
config_files = (
@@ -192,11 +203,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# Redict logging to stderr so it does not mix with output
# particular ansible-inventory JSON output
# TODO(mordred) Integrate openstack's logging with ansible's logging
sdk.enable_logging(stream=sys.stderr)
if self.display.verbosity > 3:
sdk.enable_logging(debug=True, stream=sys.stderr)
else:
sdk.enable_logging(stream=sys.stderr)
cloud_inventory = sdk_inventory.OpenStackInventory(
config_files=config_files,
private=self._config_data.get('private', False))
self.display.vvvv("Found %d cloud(s) in Openstack" %
len(cloud_inventory.clouds))
only_clouds = self._config_data.get('only_clouds', [])
if only_clouds and not isinstance(only_clouds, list):
raise ValueError(
@@ -205,20 +221,31 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
if only_clouds:
new_clouds = []
for cloud in cloud_inventory.clouds:
self.display.vvvv("Looking at cloud : %s" % cloud.name)
if cloud.name in only_clouds:
self.display.vvvv("Selecting cloud : %s" % cloud.name)
new_clouds.append(cloud)
cloud_inventory.clouds = new_clouds
self.display.vvvv("Selected %d cloud(s)" %
len(cloud_inventory.clouds))
expand_hostvars = self._config_data.get('expand_hostvars', False)
fail_on_errors = self._config_data.get('fail_on_errors', False)
all_projects = self._config_data.get('all_projects', False)
source_data = cloud_inventory.list_hosts(
expand=expand_hostvars, fail_on_cloud_config=fail_on_errors,
all_projects=all_projects)
if cache_needs_update:
self._cache[cache_key] = source_data
source_data = []
try:
source_data = cloud_inventory.list_hosts(
expand=expand_hostvars, fail_on_cloud_config=fail_on_errors,
all_projects=all_projects)
except Exception as e:
self.display.warning("Couldn't list Openstack hosts. "
"See logs for details")
os_logger.error(e.message)
finally:
if cache_needs_update:
self._cache[cache_key] = source_data
self._populate_from_source(source_data)
@@ -344,5 +371,6 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
for suffix in ('yaml', 'yml'):
maybe = '{fn}.{suffix}'.format(fn=fn, suffix=suffix)
if path.endswith(maybe):
self.display.vvvv("Valid plugin config file found")
return True
return False

View File

@@ -28,6 +28,7 @@
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import abc
import copy
from distutils.version import StrictVersion
import importlib
import os
@@ -35,6 +36,37 @@ import os
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems
OVERRIDES = {'os_client_config': 'config',
'os_endpoint': 'catalog_endpoint',
'os_flavor': 'compute_flavor',
'os_flavor_info': 'compute_flavor_info',
'os_group': 'identity_group',
'os_group_info': 'identity_group_info',
'os_ironic': 'baremetal_node',
'os_ironic_inspect': 'baremetal_inspect',
'os_ironic_node': 'baremetal_node_action',
'os_keystone_domain': 'identity_domain',
'os_keystone_domain_info': 'identity_domain_info',
'os_keystone_endpoint': 'endpoint',
'os_keystone_identity_provider': 'federation_idp',
'os_keystone_identity_provider_info': 'federation_idp_info',
'os_keystone_mapping': 'federation_mapping',
'os_keystone_mapping_info': 'federation_mapping_info',
'os_keystone_role': 'identity_role',
'os_keystone_service': 'catalog_service',
'os_listener': 'lb_listener',
'os_member': 'lb_member',
'os_nova_flavor': 'compute_flavor',
'os_nova_host_aggregate': 'host_aggregate',
'os_pool': 'lb_pool',
'os_user': 'identity_user',
'os_user_group': 'group_assignment',
'os_user_info': 'identity_user_info',
'os_user_role': 'role_assignment',
'os_zone': 'dns_zone'}
CUSTOM_VAR_PARAMS = ['min_ver', 'max_ver']
def openstack_argument_spec():
# DEPRECATED: This argument spec is only used for the deprecated old
@@ -97,7 +129,12 @@ def openstack_full_argument_spec(**kwargs):
default='public', choices=['public', 'internal', 'admin'],
aliases=['endpoint_type']),
)
spec.update(kwargs)
# Filter out all our custom parameters before passing to AnsibleModule
kwargs_copy = copy.deepcopy(kwargs)
for v in kwargs_copy.values():
for c in CUSTOM_VAR_PARAMS:
v.pop(c, None)
spec.update(kwargs_copy)
return spec
@@ -109,10 +146,10 @@ def openstack_module_kwargs(**kwargs):
ret[key].extend(kwargs[key])
else:
ret[key] = kwargs[key]
return ret
# for compatibility with old versions
def openstack_cloud_from_module(module, min_version='0.12.0'):
try:
# Due to the name shadowing we should import other way
@@ -166,25 +203,201 @@ def openstack_cloud_from_module(module, min_version='0.12.0'):
module.fail_json(msg=str(e))
class OpenStackModule(AnsibleModule):
class OpenStackModule:
"""Openstack Module is a base class for all Openstack Module classes.
The class has `run` function that should be overriden in child classes,
the provided methods include:
Methods:
params: Dictionary of Ansible module parameters.
module_name: Module name (i.e. server_action)
sdk_version: Version of used OpenstackSDK.
results: Dictionary for return of Ansible module,
must include `changed` keyword.
exit, exit_json: Exit module and return data inside, must include
changed` keyword in a data.
fail, fail_json: Exit module with failure, has `msg` keyword to
specify a reason of failure.
conn: Connection to SDK object.
log: Print message to system log.
debug: Print debug message to system log, prints if Ansible Debug is
enabled or verbosity is more than 2.
check_deprecated_names: Function that checks if module was called with
a deprecated name and prints the correct name
with deprecation warning.
check_versioned: helper function to check that all arguments are known
in the current SDK version.
run: method that executes and shall be overriden in inherited classes.
Args:
deprecated_names: Should specify deprecated modules names for current
module.
argument_spec: Used for construction of Openstack common arguments.
module_kwargs: Additional arguments for Ansible Module.
"""
deprecated_names = ()
argument_spec = {}
module_kwargs = {}
def __init__(self):
"""Initialize Openstack base class.
super(OpenStackModule, self).__init__(
Set up variables, connection to SDK and check if there are
deprecated names.
"""
self.ansible = AnsibleModule(
openstack_full_argument_spec(**self.argument_spec),
**self.module_kwargs)
self.params = self.ansible.params
self.module_name = self.ansible._name
self.sdk_version = None
self.results = {'changed': False}
self.exit = self.exit_json = self.ansible.exit_json
self.fail = self.fail_json = self.ansible.fail_json
self.sdk, self.conn = self.openstack_cloud_from_module()
self.check_deprecated_names()
self.sdk, self.conn = openstack_cloud_from_module(self)
def log(self, msg):
"""Prints log message to system log.
Arguments:
msg {str} -- Log message
"""
self.ansible.log(msg)
def debug(self, msg):
"""Prints debug message to system log
Arguments:
msg {str} -- Debug message.
"""
if self.ansible._debug or self.ansible._verbosity > 2:
self.ansible.log(
" ".join(['[DEBUG]', msg]))
def check_deprecated_names(self):
"""Check deprecated module names if `deprecated_names` variable is set.
"""
new_module_name = OVERRIDES.get(self.module_name)
if self.module_name in self.deprecated_names and new_module_name:
self.ansible.deprecate(
"The '%s' module has been renamed to '%s' in openstack "
"collection: openstack.cloud.%s" % (
self.module_name, new_module_name, new_module_name),
version='2.10')
def openstack_cloud_from_module(self):
"""Sets up connection to cloud using provided options. Checks if all
provided variables are supported for the used SDK version.
"""
try:
# Due to the name shadowing we should import other way
sdk = importlib.import_module('openstack')
sdk_version_lib = importlib.import_module('openstack.version')
self.sdk_version = sdk_version_lib.__version__
except ImportError:
self.fail_json(msg='openstacksdk is required for this module')
# Fail if there are set unsupported for this version parameters
# New parameters should NOT use 'default' but rely on SDK defaults
for param in self.argument_spec:
if (self.params[param] is not None
and 'min_ver' in self.argument_spec[param]
and StrictVersion(self.sdk_version) < self.argument_spec[param]['min_ver']):
self.fail_json(
msg="To use parameter '{param}' with module '{module}', the installed version of "
"the openstacksdk library MUST be >={min_version}.".format(
min_version=self.argument_spec[param]['min_ver'],
param=param,
module=self.module_name))
if (self.params[param] is not None
and 'max_ver' in self.argument_spec[param]
and StrictVersion(self.sdk_version) > self.argument_spec[param]['max_ver']):
self.fail_json(
msg="To use parameter '{param}' with module '{module}', the installed version of "
"the openstacksdk library MUST be <={max_version}.".format(
max_version=self.argument_spec[param]['max_ver'],
param=param,
module=self.module_name))
cloud_config = self.params.pop('cloud', None)
if isinstance(cloud_config, dict):
fail_message = (
"A cloud config dict was provided to the cloud parameter"
" but also a value was provided for {param}. If a cloud"
" config dict is provided, {param} should be"
" excluded.")
for param in (
'auth', 'region_name', 'validate_certs',
'ca_cert', 'client_key', 'api_timeout', 'auth_type'):
if self.params[param] is not None:
self.fail_json(msg=fail_message.format(param=param))
# For 'interface' parameter, fail if we receive a non-default value
if self.params['interface'] != 'public':
self.fail_json(msg=fail_message.format(param='interface'))
else:
cloud_config = dict(
cloud=cloud_config,
auth_type=self.params['auth_type'],
auth=self.params['auth'],
region_name=self.params['region_name'],
verify=self.params['validate_certs'],
cacert=self.params['ca_cert'],
key=self.params['client_key'],
api_timeout=self.params['api_timeout'],
interface=self.params['interface'],
)
try:
return sdk, sdk.connect(**cloud_config)
except sdk.exceptions.SDKException as e:
# Probably a cloud configuration/login error
self.fail_json(msg=str(e))
# Filter out all arguments that are not from current SDK version
def check_versioned(self, **kwargs):
"""Check that provided arguments are supported by current SDK version
Returns:
versioned_result {dict} dictionary of only arguments that are
supported by current SDK version. All others
are dropped.
"""
versioned_result = {}
for var_name in kwargs:
if ('min_ver' in self.argument_spec[var_name]
and StrictVersion(self.sdk_version) < self.argument_spec[var_name]['min_ver']):
continue
if ('max_ver' in self.argument_spec[var_name]
and StrictVersion(self.sdk_version) > self.argument_spec[var_name]['max_ver']):
continue
versioned_result.update({var_name: kwargs[var_name]})
return versioned_result
@abc.abstractmethod
def run(self):
"""Function for overriding in inhetired classes, it's executed by default.
"""
pass
def __call__(self):
"""Execute `run` function when calling the class.
"""
try:
self.run()
results = self.run()
if results and isinstance(results, dict):
self.ansible.exit_json(**results)
except self.sdk.exceptions.OpenStackCloudException as e:
self.fail_json(msg=str(e), extra_data=e.extra_data)
params = {
'msg': str(e),
'extra_data': {
'data': getattr(e, 'extra_data', 'None'),
'details': getattr(e, 'details', 'None'),
'response': getattr(getattr(e, 'response', ''),
'text', 'None')
}
}
self.ansible.fail_json(**params)
# if we got to this place, modules didn't exit
self.ansible.exit_json(**self.results)

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: auth
short_description: Retrieve an auth token
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Retrieve an auth token from an OpenStack Cloud
requirements:

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: baremetal_inspect
short_description: Explicitly triggers baremetal node introspection in ironic.
author: "Julia Kreger (@juliakreger)"
author: OpenStack Ansible SIG
description:
- Requests Ironic to set a node into inspect state in order to collect metadata regarding the node.
This command may be out of band or in-band depending on the ironic driver configuration.
@@ -102,15 +102,21 @@ def main():
module = AnsibleModule(argument_spec, **module_kwargs)
if (
module.params['auth_type'] in [None, 'None']
module.params['auth_type'] in [None, 'None', 'none']
and module.params['ironic_url'] is None
and not module.params['cloud']
and not (module.params['auth']
and module.params['auth'].get('endpoint'))
):
module.fail_json(msg="Authentication appears to be disabled, "
"Please define an ironic_url parameter")
"Please define either ironic_url, or cloud, "
"or auth.endpoint")
if (
module.params['ironic_url']
and module.params['auth_type'] in [None, 'None']
and module.params['auth_type'] in [None, 'None', 'none']
and not (module.params['auth']
and module.params['auth'].get('endpoint'))
):
module.params['auth'] = dict(
endpoint=module.params['ironic_url']

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: baremetal_node
short_description: Create/Delete Bare Metal Resources from OpenStack
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Create or Remove Ironic nodes from OpenStack.
options:
@@ -118,10 +118,11 @@ options:
- As of Kilo, by default, passwords are always masked to API
requests, which means the logic as a result always attempts to
re-assert the password field.
- C(skip_update_of_driver_password) is deprecated alias and will be removed in 2.14.
- C(skip_update_of_driver_password) is deprecated alias and will be removed in openstack.cloud 2.0.0.
type: bool
default: 'no'
aliases: [ skip_update_of_driver_password ]
aliases:
- skip_update_of_driver_password
requirements:
- "python >= 3.6"
- "openstacksdk"
@@ -237,7 +238,7 @@ def main():
required=False,
type='bool',
aliases=['skip_update_of_driver_password'],
deprecated_aliases=[dict(name='skip_update_of_driver_password', version='2.14')]
deprecated_aliases=[dict(name='skip_update_of_driver_password', version='2.0.0')]
),
state=dict(required=False, default='present', choices=['present', 'absent'])
)
@@ -247,15 +248,21 @@ def main():
if not HAS_JSONPATCH:
module.fail_json(msg='jsonpatch is required for this module')
if (
module.params['auth_type'] in [None, 'None']
module.params['auth_type'] in [None, 'None', 'none']
and module.params['ironic_url'] is None
and not module.params['cloud']
and not (module.params['auth']
and module.params['auth'].get('endpoint'))
):
module.fail_json(msg="Authentication appears to be disabled, "
"Please define an ironic_url parameter")
"Please define either ironic_url, or cloud, "
"or auth.endpoint")
if (
module.params['ironic_url']
and module.params['auth_type'] in [None, 'None']
and module.params['auth_type'] in [None, 'None', 'none']
and not (module.params['auth']
and module.params['auth'].get('endpoint'))
):
module.params['auth'] = dict(
endpoint=module.params['ironic_url']

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: baremetal_node_action
short_description: Activate/Deactivate Bare Metal Resources from OpenStack
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Deploy to nodes controlled by Ironic.
options:
@@ -245,15 +245,21 @@ def main():
module = AnsibleModule(argument_spec, **module_kwargs)
if (
module.params['auth_type'] in [None, 'None']
module.params['auth_type'] in [None, 'None', 'none']
and module.params['ironic_url'] is None
and not module.params['cloud']
and not (module.params['auth']
and module.params['auth'].get('endpoint'))
):
module.fail_json(msg="Authentication appears disabled, Please "
"define an ironic_url parameter")
module.fail_json(msg="Authentication appears to be disabled, "
"Please define either ironic_url, or cloud, "
"or auth.endpoint")
if (
module.params['ironic_url']
and module.params['auth_type'] in [None, 'None']
and module.params['auth_type'] in [None, 'None', 'none']
and not (module.params['auth']
and module.params['auth'].get('endpoint'))
):
module.params['auth'] = dict(
endpoint=module.params['ironic_url']

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: catalog_service
short_description: Manage OpenStack Identity services
author: "Sam Yaple (@SamYaple)"
author: OpenStack Ansible SIG
description:
- Create, update, or delete OpenStack Identity service. If a service
with the supplied name already exists, it will be updated with the

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: coe_cluster
short_description: Add/Remove COE cluster from OpenStack Cloud
author: "Feilong Wang (@flwang)"
author: OpenStack Ansible SIG
description:
- Add or Remove COE cluster from the OpenStack Container Infra service.
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: coe_cluster_template
short_description: Add/Remove COE cluster template from OpenStack Cloud
author: "Feilong Wang (@flwang)"
author: OpenStack Ansible SIG
description:
- Add or Remove COE cluster template from the OpenStack Container Infra
service.

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: compute_flavor
short_description: Manage OpenStack compute flavors
author: "David Shrewsbury (@Shrews)"
author: OpenStack Ansible SIG
description:
- Add or remove flavors from OpenStack.
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: compute_flavor_info
short_description: Retrieve information about one or more flavors
author: "David Shrewsbury (@Shrews)"
author: OpenStack Ansible SIG
description:
- Retrieve information about available OpenStack instance flavors. By default,
information about ALL flavors are retrieved. Filters can be applied to get

View File

@@ -23,7 +23,7 @@ options:
requirements:
- "python >= 3.6"
- "openstacksdk"
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
'''
EXAMPLES = '''

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: dns_zone
short_description: Manage OpenStack DNS zones
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
author: OpenStack Ansible SIG
description:
- Manage OpenStack DNS zones. Zones can be created, deleted or
updated. Only the I(email), I(description), I(ttl) and I(masters) values

View File

@@ -7,9 +7,7 @@ DOCUMENTATION = '''
---
module: endpoint
short_description: Manage OpenStack Identity service endpoints
author:
- Mohammed Naser (@mnaser)
- Alberto Murillo (@albertomurillo)
author: OpenStack Ansible SIG
description:
- Create, update, or delete OpenStack Identity service endpoints. If a
service with the same combination of I(service), I(interface) and I(region)

View File

@@ -6,8 +6,7 @@ DOCUMENTATION = '''
---
module: federation_idp
short_description: manage a federation Identity Provider
author:
- "Mark Chappell (@tremble) <mchappel@redhat.com>"
author: OpenStack Ansible SIG
description:
- Manage a federation Identity Provider.
options:

View File

@@ -7,8 +7,7 @@ DOCUMENTATION = '''
module: federation_idp_info
short_description: Get the information about the available federation identity
providers
author:
- "Mark Chappell (@tremble) <mchappel@redhat.com>"
author: OpenStack Ansible SIG
description:
- Fetch a federation identity provider.
options:

View File

@@ -6,8 +6,7 @@ DOCUMENTATION = '''
---
module: federation_mapping
short_description: Manage a federation mapping
author:
- "Mark Chappell (@tremble) <mchappel@redhat.com>"
author: OpenStack Ansible SIG
description:
- Manage a federation mapping.
options:

View File

@@ -6,8 +6,7 @@ DOCUMENTATION = '''
---
module: federation_mapping_info
short_description: Get the information about the available federation mappings
author:
- "Mark Chappell (@tremble) <mchappel@redhat.com>"
author: OpenStack Ansible SIG
description:
- Fetch a federation mapping.
options:

View File

@@ -6,7 +6,7 @@
DOCUMENTATION = '''
---
module: floating_ip
author: Davide Guerri (@dguerri) <davide.guerri@hp.com>
author: OpenStack Ansible SIG
short_description: Add/Remove floating IP from an instance
description:
- Add or Remove a floating IP to an instance.
@@ -79,7 +79,7 @@ extends_documentation_fragment:
'''
EXAMPLES = '''
# Assign a floating IP to the fist interface of `cattle001` from an exiting
# Assign a floating IP to the first interface of `cattle001` from an existing
# external network or nova pool. A new floating IP from the first available
# external network is allocated to the project.
- openstack.cloud.floating_ip:

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: group_assignment
short_description: Associate OpenStack Identity users and groups
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Add and remove users from groups
options:

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: host_aggregate
short_description: Manage OpenStack host aggregates
author: "Jakub Jursa (@kuboj)"
author: OpenStack Ansible SIG
description:
- Create, update, or delete OpenStack host aggregates. If a aggregate
with the supplied name already exists, it will be updated with the

View File

@@ -6,9 +6,7 @@ DOCUMENTATION = '''
---
module: identity_domain
short_description: Manage OpenStack Identity Domains
author:
- Monty Taylor (@emonty)
- Haneef Ali (@haneefs)
author: OpenStack Ansible SIG
description:
- Create, update, or delete OpenStack Identity domains. If a domain
with the supplied name already exists, it will be updated with the

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: identity_domain_info
short_description: Retrieve information about one or more OpenStack domains
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
author: OpenStack Ansible SIG
description:
- Retrieve information about a one or more OpenStack domains
- This module was called C(openstack.cloud.identity_domain_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: identity_group
short_description: Manage OpenStack Identity Groups
author: "Monty Taylor (@emonty), David Shrewsbury (@Shrews)"
author: OpenStack Ansible SIG
description:
- Manage OpenStack Identity Groups. Groups can be created, deleted or
updated. Only the I(description) value can be updated.

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: identity_group_info
short_description: Retrieve info about one or more OpenStack groups
author: "Phillipe Smith (@phsmith)"
author: OpenStack Ansible SIG
description:
- Retrieve info about a one or more OpenStack groups.
options:

View File

@@ -6,9 +6,7 @@ DOCUMENTATION = '''
---
module: identity_role
short_description: Manage OpenStack Identity Roles
author:
- Monty Taylor (@emonty)
- David Shrewsbury (@Shrews)
author: OpenStack Ansible SIG
description:
- Manage OpenStack Identity Roles.
options:

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: identity_user
short_description: Manage OpenStack Identity Users
author: David Shrewsbury (@Shrews)
author: OpenStack Ansible SIG
description:
- Manage OpenStack Identity users. Users can be created,
updated or deleted using this module. A user will be updated

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: identity_user_info
short_description: Retrieve information about one or more OpenStack users
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
author: OpenStack Ansible SIG
description:
- Retrieve information about a one or more OpenStack users
- This module was called C(openstack.cloud.identity_user_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -11,7 +11,7 @@ DOCUMENTATION = '''
---
module: image
short_description: Add/Delete images from OpenStack Cloud
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Add or Remove images from the OpenStack Image Repository
options:

View File

@@ -6,7 +6,7 @@
DOCUMENTATION = '''
module: image_info
short_description: Retrieve information about an image within OpenStack.
author: "Davide Agnello (@dagnello)"
author: OpenStack Ansible SIG
description:
- Retrieve information about a image image from OpenStack.
- This module was called C(openstack.cloud.image_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
---
module: keypair
short_description: Add/Delete a keypair from OpenStack
author: "Benno Joy (@bennojoy)"
author: OpenStack Ansible SIG
description:
- Add or Remove key pair from OpenStack
options:
@@ -79,23 +79,14 @@ private_key:
type: str
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec,
openstack_module_kwargs,
openstack_cloud_from_module)
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
OpenStackModule)
def _system_state_change(module, keypair):
state = module.params['state']
if state == 'present' and not keypair:
return True
if state == 'absent' and keypair:
return True
return False
class KeyPairModule(OpenStackModule):
deprecated_names = ('os_keypair', 'openstack.cloud.os_keypair')
def main():
argument_spec = openstack_full_argument_spec(
argument_spec = dict(
name=dict(required=True),
public_key=dict(default=None),
public_key_file=dict(default=None),
@@ -103,58 +94,62 @@ def main():
choices=['absent', 'present', 'replace']),
)
module_kwargs = openstack_module_kwargs(
module_kwargs = dict(
mutually_exclusive=[['public_key', 'public_key_file']])
module = AnsibleModule(argument_spec,
supports_check_mode=True,
**module_kwargs)
def _system_state_change(self, keypair):
state = self.params['state']
if state == 'present' and not keypair:
return True
if state == 'absent' and keypair:
return True
return False
state = module.params['state']
name = module.params['name']
public_key = module.params['public_key']
def run(self):
if module.params['public_key_file']:
with open(module.params['public_key_file']) as public_key_fh:
public_key = public_key_fh.read().rstrip()
state = self.params['state']
name = self.params['name']
public_key = self.params['public_key']
sdk, cloud = openstack_cloud_from_module(module)
try:
keypair = cloud.get_keypair(name)
if self.params['public_key_file']:
with open(self.params['public_key_file']) as public_key_fh:
public_key = public_key_fh.read().rstrip()
if module.check_mode:
module.exit_json(changed=_system_state_change(module, keypair))
keypair = self.conn.get_keypair(name)
if self.ansible.check_mode:
self.exit_json(changed=self._system_state_change(keypair))
if state in ('present', 'replace'):
if keypair and keypair['name'] == name:
if public_key and (public_key != keypair['public_key']):
if state == 'present':
module.fail_json(
self.fail_json(
msg="Key name %s present but key hash not the same"
" as offered. Delete key first." % name
)
else:
cloud.delete_keypair(name)
keypair = cloud.create_keypair(name, public_key)
self.conn.delete_keypair(name)
keypair = self.conn.create_keypair(name, public_key)
changed = True
else:
changed = False
else:
keypair = cloud.create_keypair(name, public_key)
keypair = self.conn.create_keypair(name, public_key)
changed = True
module.exit_json(changed=changed,
key=keypair,
id=keypair['id'])
self.exit_json(changed=changed, key=keypair, id=keypair['id'])
elif state == 'absent':
if keypair:
cloud.delete_keypair(name)
module.exit_json(changed=True)
module.exit_json(changed=False)
self.conn.delete_keypair(name)
self.exit_json(changed=True)
self.exit_json(changed=False)
except sdk.exceptions.OpenStackCloudException as e:
module.fail_json(msg=str(e))
def main():
module = KeyPairModule()
module()
if __name__ == '__main__':

View File

@@ -6,8 +6,7 @@ DOCUMENTATION = '''
---
module: keystone_federation_protocol
short_description: manage a federation Protocol
author:
- "Mark Chappell (@tremble) <mchappel@redhat.com>"
author: OpenStack Ansible SIG
description:
- Manage a federation Protocol.
options:

View File

@@ -6,8 +6,7 @@ DOCUMENTATION = '''
---
module: keystone_federation_protocol_info
short_description: get information about federation Protocols
author:
- "Mark Chappell (@tremble) <mchappel@redhat.com>"
author: OpenStack Ansible SIG
description:
- Get information about federation Protocols.
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: lb_listener
short_description: Add/Delete a listener for a load balancer from OpenStack Cloud
author: "Lingxian Kong (@lingxiankong)"
author: OpenStack Ansible SIG
description:
- Add or Remove a listener for a load balancer from the OpenStack load-balancer service.
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: lb_member
short_description: Add/Delete a member for a pool in load balancer from OpenStack Cloud
author: "Lingxian Kong (@lingxiankong)"
author: OpenStack Ansible SIG
description:
- Add or Remove a member for a pool from the OpenStack load-balancer service.
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: lb_pool
short_description: Add/Delete a pool in the load balancing service from OpenStack Cloud
author: "Lingxian Kong (@lingxiankong)"
author: OpenStack Ansible SIG
description:
- Add or Remove a pool from the OpenStack load-balancer service.
options:

View File

@@ -7,14 +7,14 @@ DOCUMENTATION = '''
---
module: loadbalancer
short_description: Add/Delete load balancer from OpenStack Cloud
author: "Lingxian Kong (@lingxiankong)"
author: OpenStack Ansible SIG
description:
- Add or Remove load balancer from the OpenStack load-balancer
service(Octavia). Load balancer update is not supported for now.
options:
name:
description:
- Name that has to be given to the load balancer
- The name of the load balancer.
required: true
type: str
state:
@@ -23,6 +23,10 @@ options:
choices: [present, absent]
default: present
type: str
flavor:
description:
- The flavor of the load balancer.
type: str
vip_network:
description:
- The name or id of the network for the virtual IP of the load balancer.
@@ -327,6 +331,7 @@ def _wait_for_lb(module, cloud, lb, status, failures, interval=5):
def main():
argument_spec = openstack_full_argument_spec(
name=dict(required=True),
flavor=dict(required=False),
state=dict(default='present', choices=['absent', 'present']),
vip_network=dict(required=False),
vip_subnet=dict(required=False),
@@ -342,6 +347,7 @@ def main():
module = AnsibleModule(argument_spec, **module_kwargs)
sdk, cloud = openstack_cloud_from_module(module)
flavor = module.params['flavor']
vip_network = module.params['vip_network']
vip_subnet = module.params['vip_subnet']
vip_port = module.params['vip_port']
@@ -354,6 +360,7 @@ def main():
vip_network_id = None
vip_subnet_id = None
vip_port_id = None
flavor_id = None
try:
changed = False
@@ -368,6 +375,14 @@ def main():
"be specified for load balancer creation"
)
if flavor:
_flavor = cloud.load_balancer.find_flavor(flavor)
if not _flavor:
module.fail_json(
msg='flavor %s not found' % flavor
)
flavor_id = _flavor.id
if vip_network:
network = cloud.get_network(vip_network)
if not network:
@@ -392,6 +407,7 @@ def main():
lb = cloud.load_balancer.create_load_balancer(
name=module.params['name'],
flavor_id=flavor_id,
vip_network_id=vip_network_id,
vip_subnet_id=vip_subnet_id,
vip_port_id=vip_port_id,

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: network
short_description: Creates/removes networks from OpenStack
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Add or remove network from OpenStack.
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: networks_info
short_description: Retrieve information about one or more OpenStack networks.
author: "Davide Agnello (@dagnello)"
author: OpenStack Ansible SIG
description:
- Retrieve information about one or more networks from OpenStack.
- This module was called C(openstack.cloud.networks_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: object
short_description: Create or Delete objects and containers from OpenStack
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Create or Delete objects and containers from OpenStack
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: port
short_description: Add/Update/Delete ports from an OpenStack cloud.
author: "Davide Agnello (@dagnello)"
author: OpenStack Ansible SIG
description:
- Add, Update or Remove ports from an OpenStack cloud. A I(state) of
'present' will ensure the port is created or updated if required.

View File

@@ -6,7 +6,7 @@
DOCUMENTATION = '''
module: port_info
short_description: Retrieve information about ports within OpenStack.
author: "David Shrewsbury (@Shrews)"
author: OpenStack Ansible SIG
description:
- Retrieve information about ports from OpenStack.
- This module was called C(openstack.cloud.port_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: project
short_description: Manage OpenStack Projects
author: "Alberto Gireud (@agireud)"
author: OpenStack Ansible SIG
description:
- Manage OpenStack Projects. Projects can be created,
updated or deleted using this module. A project will be updated

View File

@@ -17,7 +17,7 @@ DOCUMENTATION = '''
---
module: project_access
short_description: Manage OpenStack compute flavors access
author: "Roberto Polli (@ioggstream)"
author: OpenStack Ansible SIG
description:
- Add or remove flavor, volume_type or other resources access
from OpenStack.

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: project_info
short_description: Retrieve information about one or more OpenStack projects
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
author: OpenStack Ansible SIG
description:
- Retrieve information about a one or more OpenStack projects
- This module was called C(openstack.cloud.project_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: quota
short_description: Manage OpenStack Quotas
author: "Michael Gale (@mgale) <gale.michael@gmail.com>"
author: OpenStack Ansible SIG
description:
- Manage OpenStack Quotas. Quotas can be created,
updated or deleted using this module. A quota will be updated

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: recordset
short_description: Manage OpenStack DNS recordsets
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
author: OpenStack Ansible SIG
description:
- Manage OpenStack DNS recordsets. Recordsets can be created, deleted or
updated. Only the I(records), I(description), and I(ttl) values

View File

@@ -6,7 +6,7 @@ DOCUMENTATION = '''
---
module: role_assignment
short_description: Associate OpenStack Identity users and roles
author: "Monty Taylor (@emonty), David Shrewsbury (@Shrews)"
author: OpenStack Ansible SIG
description:
- Grant and revoke roles in either project or domain context for
OpenStack Identity Users.

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: router
short_description: Create or delete routers from OpenStack
author: "David Shrewsbury (@Shrews)"
author: OpenStack Ansible SIG
description:
- Create or Delete routers from OpenStack. Although Neutron allows
routers to share the same name, this module enforces name uniqueness

View File

@@ -7,8 +7,7 @@ DOCUMENTATION = '''
---
module: routers_info
short_description: Retrieve information about one or more OpenStack routers.
version_added: "2.10"
author: "Bram Verschueren (@bverschueren)"
author: OpenStack Ansible SIG
description:
- Retrieve information about one or more routers from OpenStack.
options:

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: security_group
short_description: Add/Delete security groups from an OpenStack cloud.
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Add or Remove security groups from an OpenStack cloud.
options:

View File

@@ -8,9 +8,7 @@ DOCUMENTATION = '''
---
module: security_group_rule
short_description: Add/Delete rule from an existing security group
author:
- "Benno Joy (@bennojoy)"
- "Jeffrey van Pelt (@Thulium-Drake)"
author: OpenStack Ansible SIG
description:
- Add or Remove rule from an existing security group
options:
@@ -181,10 +179,8 @@ security_group_id:
returned: state == present
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec,
openstack_module_kwargs,
openstack_cloud_from_module)
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
OpenStackModule)
def _ports_match(protocol, module_min, module_max, rule_min, rule_max):
@@ -246,51 +242,10 @@ def _ports_match(protocol, module_min, module_max, rule_min, rule_max):
return module_min == rule_min and module_max == rule_max
def _find_matching_rule(module, secgroup, remotegroup):
"""
Find a rule in the group that matches the module parameters.
:returns: The matching rule dict, or None if no matches.
"""
protocol = module.params['protocol']
remote_ip_prefix = module.params['remote_ip_prefix']
ethertype = module.params['ethertype']
direction = module.params['direction']
remote_group_id = remotegroup['id']
class SecurityGroupRuleModule(OpenStackModule):
deprecated_names = ('os_security_group_rule', 'openstack.cloud.os_security_group_rule')
for rule in secgroup['security_group_rules']:
if (
protocol == rule['protocol']
and remote_ip_prefix == rule['remote_ip_prefix']
and ethertype == rule['ethertype']
and direction == rule['direction']
and remote_group_id == rule['remote_group_id']
and _ports_match(
protocol,
module.params['port_range_min'],
module.params['port_range_max'],
rule['port_range_min'],
rule['port_range_max'])
):
return rule
return None
def _system_state_change(module, secgroup, remotegroup):
state = module.params['state']
if secgroup:
rule_exists = _find_matching_rule(module, secgroup, remotegroup)
else:
return False
if state == 'present' and not rule_exists:
return True
if state == 'absent' and rule_exists:
return True
return False
def main():
argument_spec = openstack_full_argument_spec(
argument_spec = dict(
security_group=dict(required=True),
# NOTE(Shrews): None is an acceptable protocol value for
# Neutron, but Nova will balk at this.
@@ -309,85 +264,122 @@ def main():
project=dict(default=None),
)
module_kwargs = openstack_module_kwargs(
module_kwargs = dict(
mutually_exclusive=[
['remote_ip_prefix', 'remote_group'],
]
)
module = AnsibleModule(argument_spec,
supports_check_mode=True,
**module_kwargs)
def _find_matching_rule(self, secgroup, remotegroup):
"""
Find a rule in the group that matches the module parameters.
:returns: The matching rule dict, or None if no matches.
"""
protocol = self.params['protocol']
remote_ip_prefix = self.params['remote_ip_prefix']
ethertype = self.params['ethertype']
direction = self.params['direction']
remote_group_id = remotegroup['id']
state = module.params['state']
security_group = module.params['security_group']
remote_group = module.params['remote_group']
project = module.params['project']
changed = False
for rule in secgroup['security_group_rules']:
if (
protocol == rule['protocol']
and remote_ip_prefix == rule['remote_ip_prefix']
and ethertype == rule['ethertype']
and direction == rule['direction']
and remote_group_id == rule['remote_group_id']
and _ports_match(
protocol,
self.params['port_range_min'],
self.params['port_range_max'],
rule['port_range_min'],
rule['port_range_max'])
):
return rule
return None
def _system_state_change(self, secgroup, remotegroup):
state = self.params['state']
if secgroup:
rule_exists = self._find_matching_rule(secgroup, remotegroup)
else:
return False
if state == 'present' and not rule_exists:
return True
if state == 'absent' and rule_exists:
return True
return False
def run(self):
state = self.params['state']
security_group = self.params['security_group']
remote_group = self.params['remote_group']
project = self.params['project']
changed = False
sdk, cloud = openstack_cloud_from_module(module)
try:
if project is not None:
proj = cloud.get_project(project)
proj = self.conn.get_project(project)
if proj is None:
module.fail_json(msg='Project %s could not be found' % project)
self.fail_json(msg='Project %s could not be found' % project)
project_id = proj['id']
else:
project_id = cloud.current_project_id
project_id = self.conn.current_project_id
if project_id:
if project_id and not remote_group:
filters = {'tenant_id': project_id}
else:
filters = None
secgroup = cloud.get_security_group(security_group, filters=filters)
secgroup = self.conn.get_security_group(security_group, filters=filters)
if remote_group:
remotegroup = cloud.get_security_group(remote_group,
filters=filters)
remotegroup = self.conn.get_security_group(remote_group, filters=filters)
else:
remotegroup = {'id': None}
if module.check_mode:
module.exit_json(changed=_system_state_change(module, secgroup, remotegroup))
if self.ansible.check_mode:
self.exit_json(changed=self._system_state_change(secgroup, remotegroup))
if state == 'present':
if module.params['protocol'] == 'any':
module.params['protocol'] = None
if self.params['protocol'] == 'any':
self.params['protocol'] = None
if not secgroup:
module.fail_json(msg='Could not find security group %s' %
security_group)
self.fail_json(msg='Could not find security group %s' % security_group)
rule = _find_matching_rule(module, secgroup, remotegroup)
rule = self._find_matching_rule(secgroup, remotegroup)
if not rule:
kwargs = {}
if project_id:
kwargs['project_id'] = project_id
rule = cloud.create_security_group_rule(
rule = self.conn.create_security_group_rule(
secgroup['id'],
port_range_min=module.params['port_range_min'],
port_range_max=module.params['port_range_max'],
protocol=module.params['protocol'],
remote_ip_prefix=module.params['remote_ip_prefix'],
port_range_min=self.params['port_range_min'],
port_range_max=self.params['port_range_max'],
protocol=self.params['protocol'],
remote_ip_prefix=self.params['remote_ip_prefix'],
remote_group_id=remotegroup['id'],
direction=module.params['direction'],
ethertype=module.params['ethertype'],
direction=self.params['direction'],
ethertype=self.params['ethertype'],
**kwargs
)
changed = True
module.exit_json(changed=changed, rule=rule, id=rule['id'])
self.exit_json(changed=changed, rule=rule, id=rule['id'])
if state == 'absent' and secgroup:
rule = _find_matching_rule(module, secgroup, remotegroup)
rule = self._find_matching_rule(secgroup, remotegroup)
if rule:
cloud.delete_security_group_rule(rule['id'])
self.conn.delete_security_group_rule(rule['id'])
changed = True
module.exit_json(changed=changed)
self.exit_json(changed=changed)
except sdk.exceptions.OpenStackCloudException as e:
module.fail_json(msg=str(e))
def main():
module = SecurityGroupRuleModule()
module()
if __name__ == '__main__':

View File

@@ -11,8 +11,7 @@ DOCUMENTATION = '''
---
module: server
short_description: Create/Delete Compute Instances from OpenStack
version_added: "2.0"
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Create or Remove compute instances from OpenStack.
options:
@@ -162,7 +161,6 @@ options:
scheduler_hints:
description:
- Arbitrary key/value pairs to the scheduler for custom use
version_added: "2.1"
type: dict
state:
description:
@@ -176,7 +174,6 @@ options:
associated with the instance will be deleted along with the instance.
type: bool
default: 'no'
version_added: "2.2"
reuse_ips:
description:
- When I(auto_ip) is true and this option is true, the I(auto_ip) code
@@ -188,7 +185,6 @@ options:
the server is deleted using I(delete_fip).
type: bool
default: 'yes'
version_added: "2.2"
availability_zone:
description:
- Availability zone in which to create the server.
@@ -473,11 +469,11 @@ def _network_args(module, cloud):
nics = module.params['nics']
if not isinstance(nics, list):
module.fail_json(msg='The \'nics\' parameter must be a list.')
module.fail(msg='The \'nics\' parameter must be a list.')
for num, net in enumerate(_parse_nics(nics)):
if not isinstance(net, dict):
module.fail_json(
module.fail(
msg='Each entry in the \'nics\' parameter must be a dict.')
if net.get('net-id'):
@@ -485,7 +481,7 @@ def _network_args(module, cloud):
elif net.get('net-name'):
by_name = cloud.get_network(net['net-name'])
if not by_name:
module.fail_json(
module.fail(
msg='Could not find network by net-name: %s' %
net['net-name'])
resolved_net = net.copy()
@@ -497,7 +493,7 @@ def _network_args(module, cloud):
elif net.get('port-name'):
by_name = cloud.get_port(net['port-name'])
if not by_name:
module.fail_json(
module.fail(
msg='Could not find port by port-name: %s' %
net['port-name'])
resolved_net = net.copy()
@@ -618,6 +614,7 @@ def _check_security_groups(module, cloud, server):
class ServerModule(OpenStackModule):
deprecated_names = ('os_server', 'openstack.cloud.os_server')
argument_spec = dict(
name=dict(required=True),
@@ -662,6 +659,7 @@ class ServerModule(OpenStackModule):
)
def run(self):
state = self.params['state']
image = self.params['image']
boot_volume = self.params['boot_volume']
@@ -670,12 +668,12 @@ class ServerModule(OpenStackModule):
if state == 'present':
if not (image or boot_volume):
self.fail_json(
self.fail(
msg="Parameter 'image' or 'boot_volume' is required "
"if state == 'present'"
)
if not flavor and not flavor_ram:
self.fail_json(
self.fail(
msg="Parameter 'flavor' or 'flavor_ram' is required "
"if state == 'present'"
)
@@ -689,7 +687,7 @@ class ServerModule(OpenStackModule):
def _exit_hostvars(self, server, changed=True):
hostvars = self.conn.get_openstack_vars(server)
self.exit_json(
self.exit(
changed=changed, server=server, id=server.id, openstack=hostvars)
def _get_server_state(self):
@@ -697,7 +695,7 @@ class ServerModule(OpenStackModule):
server = self.conn.get_server(self.params['name'])
if server and state == 'present':
if server.status not in ('ACTIVE', 'SHUTOFF', 'PAUSED', 'SUSPENDED'):
self.fail_json(
self.fail(
msg="The instance is available but not Active state: " + server.status)
(ip_changed, server) = _check_ips(self, self.conn, server)
(sg_changed, server) = _check_security_groups(self, self.conn, server)
@@ -706,7 +704,7 @@ class ServerModule(OpenStackModule):
if server and state == 'absent':
return True
if state == 'absent':
self.exit_json(changed=False, result="not present")
self.exit(changed=False, result="not present")
return True
def _create_server(self):
@@ -719,23 +717,23 @@ class ServerModule(OpenStackModule):
image_id = self.conn.get_image_id(
self.params['image'], self.params['image_exclude'])
if not image_id:
self.fail_json(
self.fail(
msg="Could not find image %s" % self.params['image'])
if flavor:
flavor_dict = self.conn.get_flavor(flavor)
if not flavor_dict:
self.fail_json(msg="Could not find flavor %s" % flavor)
self.fail(msg="Could not find flavor %s" % flavor)
else:
flavor_dict = self.conn.get_flavor_by_ram(flavor_ram, flavor_include)
if not flavor_dict:
self.fail_json(msg="Could not find any matching flavor")
self.fail(msg="Could not find any matching flavor")
nics = _network_args(self, self.conn)
self.params['meta'] = _parse_meta(self.params['meta'])
bootkwargs = dict(
bootkwargs = self.check_versioned(
name=self.params['name'],
image=image_id,
flavor=flavor_dict['id'],
@@ -792,8 +790,8 @@ class ServerModule(OpenStackModule):
timeout=self.params['timeout'],
delete_ips=self.params['delete_fip'])
except Exception as e:
self.fail_json(msg="Error in deleting vm: %s" % e.message)
self.exit_json(changed=True, result='deleted')
self.fail(msg="Error in deleting vm: %s" % e)
self.exit(changed=True, result='deleted')
def main():

View File

@@ -8,40 +8,45 @@ DOCUMENTATION = '''
---
module: server_action
short_description: Perform actions on Compute Instances from OpenStack
author: "Jesse Keating (@omgjlk)"
author: OpenStack Ansible SIG
description:
- Perform server actions on an existing compute instance from OpenStack.
This module does not return any data other than changed true/false.
When I(action) is 'rebuild', then I(image) parameter is required.
- Perform server actions on an existing compute instance from OpenStack.
This module does not return any data other than changed true/false.
When I(action) is 'rebuild', then I(image) parameter is required.
options:
server:
description:
server:
description:
- Name or ID of the instance
required: true
type: str
wait:
description:
required: true
type: str
wait:
description:
- If the module should wait for the instance action to be performed.
type: bool
default: 'yes'
timeout:
description:
type: bool
default: 'yes'
timeout:
description:
- The amount of time the module should wait for the instance to perform
the requested action.
default: 180
type: int
action:
description:
- Perform the given action. The lock and unlock actions always return
changed as the servers API does not provide lock status.
choices: [stop, start, pause, unpause, lock, unlock, suspend, resume,
rebuild]
type: str
required: true
image:
description:
- Image the server should be rebuilt with
type: str
the requested action.
default: 180
type: int
action:
description:
- Perform the given action. The lock and unlock actions always return
changed as the servers API does not provide lock status.
choices: [stop, start, pause, unpause, lock, unlock, suspend, resume,
rebuild]
type: str
required: true
image:
description:
- Image the server should be rebuilt with
type: str
admin_password:
description:
- Admin password for server to rebuild
type: str
requirements:
- "python >= 3.6"
- "openstacksdk"
@@ -63,10 +68,9 @@ EXAMPLES = '''
timeout: 200
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec,
openstack_module_kwargs,
openstack_cloud_from_module)
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
_action_map = {'stop': 'SHUTOFF',
'start': 'ACTIVE',
'pause': 'PAUSED',
@@ -80,160 +84,98 @@ _action_map = {'stop': 'SHUTOFF',
_admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock']
def _action_url(server_id):
return '/servers/{server_id}/action'.format(server_id=server_id)
class ServerActionModule(OpenStackModule):
deprecated_names = ('os_server_action', 'openstack.cloud.os_server_action')
argument_spec = dict(
server=dict(required=True, type='str'),
action=dict(required=True, type='str',
choices=['stop', 'start', 'pause', 'unpause',
'lock', 'unlock', 'suspend', 'resume',
'rebuild']),
image=dict(required=False, type='str'),
admin_password=dict(required=False, type='str'),
)
module_kwargs = dict(
required_if=[('action', 'rebuild', ['image'])],
supports_check_mode=True,
)
def _wait(timeout, cloud, server, action, module, sdk):
"""Wait for the server to reach the desired state for the given action."""
def run(self):
os_server = self._preliminary_checks()
self._execute_server_action(os_server)
# for some reason we don't wait for lock and unlock before exit
if self.params['action'] not in ('lock', 'unlock'):
if self.params['wait']:
self._wait(os_server)
self.exit_json(changed=True)
for count in sdk.utils.iterate_timeout(
timeout,
"Timeout waiting for server to complete %s" % action):
def _preliminary_checks(self):
# Using Munch object for getting information about a server
os_server = self.conn.get_server(self.params['server'])
if not os_server:
self.fail_json(msg='Could not find server %s' % self.params['server'])
# check mode
if self.ansible.check_mode:
self.exit_json(changed=self.__system_state_change(os_server))
# examine special cases
# lock, unlock and rebuild don't depend on state, just do it
if self.params['action'] not in ('lock', 'unlock', 'rebuild'):
if not self.__system_state_change(os_server):
self.exit_json(changed=False)
return os_server
def _execute_server_action(self, os_server):
if self.params['action'] == 'rebuild':
return self._rebuild_server(os_server)
action_name = self.params['action'] + "_server"
try:
server = cloud.get_server(server.id)
except Exception:
continue
func_name = getattr(self.conn.compute, action_name)
except AttributeError:
self.fail_json(
msg="Method %s wasn't found in OpenstackSDK compute" % action_name)
func_name(os_server)
if server.status == _action_map[action]:
return
def _rebuild_server(self, os_server):
# rebuild should ensure images exists
try:
image = self.conn.get_image(self.params['image'])
except Exception as e:
self.fail_json(
msg="Can't find the image %s: %s" % (self.params['image'], e))
if not image:
self.fail_json(msg="Image %s was not found!" % self.params['image'])
# admin_password is required by SDK, but not required by Nova API
if self.params['admin_password']:
self.conn.compute.rebuild_server(
server=os_server,
name=os_server['name'],
image=image['id'],
admin_password=self.params['admin_password']
)
else:
self.conn.compute.post(
'/servers/{server_id}/action'.format(
server_id=os_server['id']),
json={'rebuild': {'imageRef': image['id']}})
if server.status == 'ERROR':
module.fail_json(msg="Server reached ERROR state while attempting to %s" % action)
def _wait(self, os_server):
"""Wait for the server to reach the desired state for the given action."""
# Using Server object for wait_for_server function
server = self.conn.compute.find_server(self.params['server'])
self.conn.compute.wait_for_server(
server,
status=_action_map[self.params['action']],
wait=self.params['timeout'])
def _system_state_change(action, status):
"""Check if system state would change."""
if status == _action_map[action]:
return False
return True
def __system_state_change(self, os_server):
"""Check if system state would change."""
return os_server.status != _action_map[self.params['action']]
def main():
argument_spec = openstack_full_argument_spec(
server=dict(required=True),
action=dict(required=True, choices=['stop', 'start', 'pause', 'unpause',
'lock', 'unlock', 'suspend', 'resume',
'rebuild']),
image=dict(required=False),
)
module_kwargs = openstack_module_kwargs()
module = AnsibleModule(argument_spec, supports_check_mode=True,
required_if=[('action', 'rebuild', ['image'])],
**module_kwargs)
action = module.params['action']
wait = module.params['wait']
timeout = module.params['timeout']
image = module.params['image']
sdk, cloud = openstack_cloud_from_module(module)
try:
server = cloud.get_server(module.params['server'])
if not server:
module.fail_json(msg='Could not find server %s' % server)
status = server.status
if module.check_mode:
module.exit_json(changed=_system_state_change(action, status))
if action == 'stop':
if not _system_state_change(action, status):
module.exit_json(changed=False)
cloud.compute.post(
_action_url(server.id),
json={'os-stop': None})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
if action == 'start':
if not _system_state_change(action, status):
module.exit_json(changed=False)
cloud.compute.post(
_action_url(server.id),
json={'os-start': None})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
if action == 'pause':
if not _system_state_change(action, status):
module.exit_json(changed=False)
cloud.compute.post(
_action_url(server.id),
json={'pause': None})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
elif action == 'unpause':
if not _system_state_change(action, status):
module.exit_json(changed=False)
cloud.compute.post(
_action_url(server.id),
json={'unpause': None})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
elif action == 'lock':
# lock doesn't set a state, just do it
cloud.compute.post(
_action_url(server.id),
json={'lock': None})
module.exit_json(changed=True)
elif action == 'unlock':
# unlock doesn't set a state, just do it
cloud.compute.post(
_action_url(server.id),
json={'unlock': None})
module.exit_json(changed=True)
elif action == 'suspend':
if not _system_state_change(action, status):
module.exit_json(changed=False)
cloud.compute.post(
_action_url(server.id),
json={'suspend': None})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
elif action == 'resume':
if not _system_state_change(action, status):
module.exit_json(changed=False)
cloud.compute.post(
_action_url(server.id),
json={'resume': None})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
elif action == 'rebuild':
image = cloud.get_image(image)
if image is None:
module.fail_json(msg="Image does not exist")
# rebuild doesn't set a state, just do it
cloud.compute.post(
_action_url(server.id),
json={'rebuild': {'imageRef': image.id}})
if wait:
_wait(timeout, cloud, server, action, module, sdk)
module.exit_json(changed=True)
except sdk.exceptions.OpenStackCloudException as e:
module.fail_json(msg=str(e), extra_data=e.extra_data)
module = ServerActionModule()
module()
if __name__ == '__main__':

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: server_group
short_description: Manage OpenStack server groups
author: "Lingxian Kong (@kong)"
author: OpenStack Ansible SIG
description:
- Add or remove server groups from OpenStack.
options:

View File

@@ -7,36 +7,36 @@ DOCUMENTATION = '''
---
module: server_info
short_description: Retrieve information about one or more compute instances
author: Monty (@emonty)
author: OpenStack Ansible SIG
description:
- Retrieve information about server instances from OpenStack.
- This module was called C(openstack.cloud.server_facts) before Ansible 2.9, returning C(ansible_facts).
- This module was called C(os_server_facts) before Ansible 2.9, returning C(ansible_facts).
Note that the M(openstack.cloud.server_info) module no longer returns C(ansible_facts)!
notes:
- The result contains a list of servers.
options:
server:
description:
- restrict results to servers with names or UUID matching
this glob expression (e.g., <web*>).
type: str
detailed:
description:
- when true, return additional detail about servers at the expense
of additional API calls.
type: bool
default: 'no'
filters:
description:
- restrict results to servers matching a dictionary of
filters
type: dict
all_projects:
description:
- Whether to list servers from all projects or just the current auth
scoped project.
type: bool
default: 'no'
server:
description:
- restrict results to servers with names or UUID matching
this glob expression (e.g., <web*>).
type: str
detailed:
description:
- when true, return additional detail about servers at the expense
of additional API calls.
type: bool
default: 'no'
filters:
description:
- restrict results to servers matching a dictionary of
filters
type: dict
all_projects:
description:
- Whether to list servers from all projects or just the current auth
scoped project.
type: bool
default: 'no'
requirements:
- "python >= 3.6"
- "openstacksdk"
@@ -57,13 +57,13 @@ EXAMPLES = '''
msg: "{{ result.openstack_servers }}"
'''
import fnmatch
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class ServerInfoModule(OpenStackModule):
deprecated_names = ('os_server_info', 'openstack.cloud.os_server_info')
argument_spec = dict(
server=dict(required=False),
detailed=dict(required=False, type='bool', default=False),
@@ -72,26 +72,16 @@ class ServerInfoModule(OpenStackModule):
)
def run(self):
is_old_facts = self._name == 'openstack.cloud.server_facts'
if is_old_facts:
self.deprecate("The 'openstack.cloud.server_facts' module has been renamed to 'openstack.cloud.server_info', "
"and the renamed one no longer returns ansible_facts", version='2.13')
openstack_servers = self.conn.search_servers(
detailed=self.params['detailed'], filters=self.params['filters'],
all_projects=self.params['all_projects'])
kwargs = self.check_versioned(
detailed=self.params['detailed'],
filters=self.params['filters'],
all_projects=self.params['all_projects']
)
if self.params['server']:
# filter servers by name
pattern = self.params['server']
# TODO(mordred) This is handled by sdk now
openstack_servers = [server for server in openstack_servers
if fnmatch.fnmatch(server['name'], pattern)
or fnmatch.fnmatch(server['id'], pattern)]
if is_old_facts:
self.exit_json(changed=False, ansible_facts=dict(
openstack_servers=openstack_servers))
else:
self.exit_json(changed=False, openstack_servers=openstack_servers)
kwargs['name_or_id'] = self.params['server']
openstack_servers = self.conn.search_servers(**kwargs)
self.exit(changed=False, openstack_servers=openstack_servers)
def main():

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: server_metadata
short_description: Add/Update/Delete Metadata in Compute Instances from OpenStack
author: "Mario Santos (@ruizink)"
author: OpenStack Ansible SIG
description:
- Add, Update or Remove metadata in compute instances from OpenStack.
options:

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: server_volume
short_description: Attach/Detach Volumes from OpenStack VM's
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Attach or Detach volumes from OpenStack VM's
options:

View File

@@ -9,9 +9,7 @@ DOCUMENTATION = '''
---
module: stack
short_description: Add/Remove Heat Stack
author:
- "Mathieu Bultel (@matbu)"
- "Steve Baker (@steveb)"
author: OpenStack Ansible SIG
description:
- Add or Remove a Stack to an OpenStack Heat
options:

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: subnet
short_description: Add/Remove subnet to an OpenStack network
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Add or Remove a subnet to an OpenStack network
options:

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: subnets_info
short_description: Retrieve information about one or more OpenStack subnets.
author: "Davide Agnello (@dagnello)"
author: OpenStack Ansible SIG
description:
- Retrieve information about one or more subnets from OpenStack.
- This module was called C(openstack.cloud.subnets_facts) before Ansible 2.9, returning C(ansible_facts).

View File

@@ -7,7 +7,7 @@ DOCUMENTATION = '''
---
module: volume
short_description: Create/Delete Cinder Volumes
author: "Monty Taylor (@emonty)"
author: OpenStack Ansible SIG
description:
- Create or Remove cinder block storage volumes
options:

View File

@@ -0,0 +1,147 @@
#!/usr/bin/python
# coding: utf-8 -*-
# Copyright (c) 2020, Sagi Shnaidman <sshnaidm@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = '''
---
module: volume_info
short_description: Retrive information about volumes
author: Sagi Shnaidman (@sshnaidm)
description:
- Get information about block storage in openstack
options:
details:
description:
- Whether to provide additional information about volumes
type: bool
default: false
all_projects:
description:
- Whether return the volumes in all projects
type: bool
default: false
name:
description:
- Name of the volume as a string.
type: str
required: false
status:
description:
- Value of the status of the volume so that you can filter on "available" for example
type: str
required: false
requirements:
- "python >= 3.6"
- "openstacksdk"
extends_documentation_fragment:
- openstack.cloud.openstack
'''
RETURN = '''
volumes:
description: Volumes in project
returned: always
type: list
elements: dict
sample:
- attachments: []
availability_zone: nova
consistency_group_id: null
created_at: '2017-11-15T10:51:19.000000'
description: ''
extended_replication_status: null
host: null
id: 103ac6ed-527f-4781-8484-7ff4467e34f5
image_id: null
is_bootable: true
is_encrypted: false
links:
- href: https://...
rel: self
- href: https://...
rel: bookmark
location:
cloud: cloud
project:
domain_id: null
domain_name: Default
id: cfe04702154742fc964d9403c691c76e
name: username
region_name: regionOne
zone: nova
metadata:
readonly: 'False'
migration_id: null
migration_status: null
name: ''
project_id: cab34702154a42fc96ed9403c691c76e
replication_driver_data: null
replication_status: disabled
size: 9
snapshot_id: null
source_volume_id: null
status: available
volume_image_metadata:
checksum: a14e113deeee3a3392462f167ed28cb5
container_format: bare
disk_format: raw
family: centos-7
image_id: afcf3320-1bf8-4a9a-a24d-5abd639a6e33
image_name: CentOS-7-x86_64-GenericCloud-1708
latest: centos-7-latest
min_disk: '0'
min_ram: '0'
official: 'True'
official-image: 'True'
size: '8589934592'
volume_type: null
'''
EXAMPLES = '''
- openstack.cloud.volume_info:
- openstack.cloud.volume_info:
name: myvolume
- openstack.cloud.volume_info:
all_projects: true
- openstack.cloud.volume_info:
all_projects: true
details: true
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class VolumeInfoModule(OpenStackModule):
argument_spec = dict(
details=dict(type='bool', default=False),
all_projects=dict(type='bool', default=False),
name=dict(type='str', required=False),
status=dict(type='str', required=False),
)
def run(self):
result = self.conn.block_storage.volumes(
details=self.params['details'],
name=self.params['name'],
all_projects=self.params['all_projects'],
status=self.params['status'],
)
result = list(result)
self.results.update({'volumes': result})
def main():
module = VolumeInfoModule()
module()
if __name__ == '__main__':
main()

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
---
module: volume_snapshot
short_description: Create/Delete Cinder Volume Snapshots
author: "Mario Santos (@ruizink)"
author: OpenStack Ansible SIG
description:
- Create or Delete cinder block storage volume snapshots
options:

View File

@@ -1,3 +1,38 @@
[metadata]
# This is a stub file to enable tox-siblings to work
name = ansible-collections-openstack
name = ansible-collections-openstack.cloud
summary = Ansible collections for Openstack cloud
description-file =
README.md
author = OpenStack
author-email = openstack-discuss@lists.openstack.org
home-page = https://opendev.org/openstack/ansible-collections-openstack/
classifier =
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Development Status :: 5 - Production/Stable
Intended Audience :: Developers
Intended Audience :: System Administrators
Intended Audience :: Information Technology
Topic :: System :: Systems Administration
Topic :: Utilities
[global]
setup-hooks =
pbr.hooks.setup_hook
[files]
data_files =
share/ansible/collections/ansible_collections/openstack/cloud/ = README.md
share/ansible/collections/ansible_collections/openstack/cloud/roles/ = roles/*
share/ansible/collections/ansible_collections/openstack/cloud/plugins/ = plugins/*
share/ansible/collections/ansible_collections/openstack/cloud/playbooks/ = playbooks/*
share/ansible/collections/ansible_collections/openstack/cloud/scripts/ = scripts/*
share/ansible/collections/ansible_collections/openstack/cloud/docs/ = docs/*
share/ansible/collections/ansible_collections/openstack/cloud/meta/ = meta/*
[wheel]
universal = 1
[pbr]
skip_authors = True
skip_changelog = True

8
setup.py Normal file
View File

@@ -0,0 +1,8 @@
# Copyright Red Hat, Inc. All Rights Reserved.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
import setuptools
setuptools.setup(
setup_requires=['pbr'],
pbr=True)

11
test-requirements-2.9.txt Normal file
View File

@@ -0,0 +1,11 @@
openstacksdk
ansible
pycodestyle
flake8
pylint
voluptuous
yamllint
rstcheck
ruamel.yaml
#galaxy-importer # see https://review.opendev.org/#/c/743054
tox

View File

@@ -1,6 +1,5 @@
ansible
ansible-base
openstacksdk
ansible-base
pycodestyle
flake8
pylint
@@ -8,4 +7,5 @@ voluptuous
yamllint
rstcheck
ruamel.yaml
galaxy-importer
#galaxy-importer # see https://review.opendev.org/#/c/743054
tox

View File

@@ -0,0 +1,9 @@
plugins/modules/compute_flavor_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/identity_domain_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/identity_user_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/image_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/networks_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/port_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/project_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/subnets_info.py pylint:ansible-deprecated-no-collection-name
plugins/module_utils/openstack.py pylint:ansible-deprecated-no-collection-name

View File

@@ -0,0 +1,9 @@
plugins/modules/compute_flavor_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/identity_domain_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/identity_user_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/image_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/networks_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/port_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/project_info.py pylint:ansible-deprecated-no-collection-name
plugins/modules/subnets_info.py pylint:ansible-deprecated-no-collection-name
plugins/module_utils/openstack.py pylint:ansible-deprecated-no-collection-name

View File

@@ -1,4 +0,0 @@
packaging # needed for update-bundled and changelog
sphinx ; python_version >= '3.5' # docs build requires python 3+
sphinx-notfound-page ; python_version >= '3.5' # docs build requires python 3+
straight.plugin ; python_version >= '3.5' # needed for hacking/build-ansible.py which will host changelog generation and requires python 3+

View File

@@ -96,7 +96,7 @@ if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
global file_spec
if file_spec is None:
import _io # pylint: disable=import-outside-toplevel
import _io # noqa
file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))))
if mock is None:

View File

@@ -16,9 +16,10 @@
set -e
TOXDIR=${1:-.}
######### Disbaled in https://review.opendev.org/#/c/743054
# galaxy_importer.main does not return non-zero error code on error
output=$(python -m galaxy_importer.main $TOXDIR/build_artifact/*)
if echo $output | grep ERROR: ; then
exit 1
fi
#output=$(python -m galaxy_importer.main $TOXDIR/build_artifact/*)
#if echo $output | grep ERROR: ; then
# exit 1
#fi

View File

@@ -23,7 +23,11 @@ rm -rf "${ANSIBLE_COLLECTIONS_PATH}"
mkdir -p ${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/openstack/cloud
cp -a ${TOXDIR}/{plugins,meta,scripts,tests,docs} ${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/openstack/cloud
cd ${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/openstack/cloud/
echo "Running ansible-test with version:"
ansible --version
ansible-test sanity -v \
--venv \
--python 3.6 \
--skip-test metaclass-boilerplate \
--skip-test future-import-boilerplate \
plugins/ docs/ meta/ scripts/ tests/

39
tox.ini
View File

@@ -8,7 +8,9 @@ ignore_basepython_conflict = True
skip_install = True
install_command = python -m pip install {opts} {packages}
basepython = python3
passenv = OS_*
passenv =
OS_*
pip: PIP_INSTALL
setenv =
VIRTUAL_ENV={envdir}
LANG=en_US.UTF-8
@@ -17,8 +19,10 @@ setenv =
OS_LOG_CAPTURE={env:OS_LOG_CAPTURE:true}
OS_STDOUT_CAPTURE={env:OS_STDOUT_CAPTURE:true}
OS_STDERR_CAPTURE={env:OS_STDERR_CAPTURE:true}
pip: PIP_INSTALL={env:PIP_INSTALL:true}
deps =
-r{toxinidir}/test-requirements.txt
pip: {toxinidir}
commands = stestr run {posargs}
stestr slowest
@@ -34,20 +38,30 @@ commands =
deps =
pbr
ruamel.yaml
galaxy-importer
git+https://github.com/ansible/ansible
ansible-base
commands =
python {toxinidir}/tools/build.py
ansible --version
ansible-galaxy collection build --force {toxinidir} --output-path {toxinidir}/build_artifact
/bin/bash {toxinidir}/tools/check-import.sh {toxinidir}
[testenv:linters]
passenv = *
deps =
{[testenv]deps}
commands =
{[testenv:build]commands}
{[testenv:pep8]commands}
ansible --version
/bin/bash {toxinidir}/tools/run-ansible-sanity.sh {toxinidir}
[testenv:linters-2.9]
passenv = {[testenv:linters]passenv}
commands = {[testenv:linters]commands}
deps =
-r{toxinidir}/test-requirements-2.9.txt
[testenv:venv]
deps =
-r{toxinidir}/test-requirements.txt
@@ -66,8 +80,25 @@ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,ansible_collections
[testenv:ansible]
# Need to pass some env vars for the Ansible playbooks
passenv = HOME USER ANSIBLE_VAR_*
passenv =
HOME
USER
ANSIBLE_*
deps =
{[testenv]deps}
commands =
/bin/bash {toxinidir}/ci/run-ansible-tests-collection.sh -e {envdir} {posargs}
# PIP job runs with Ansible-2.9
[testenv:ansible-pip]
deps =
-r{toxinidir}/test-requirements-2.9.txt
{toxinidir}
passenv = {[testenv:ansible]passenv}
commands = {[testenv:ansible]commands}
[testenv:ansible-2.9]
deps =
-r{toxinidir}/test-requirements-2.9.txt
passenv = {[testenv:ansible]passenv}
commands = {[testenv:ansible]commands}