mirror of
https://opendev.org/openstack/ansible-collections-openstack.git
synced 2026-03-27 05:53:02 +00:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47382d52ed | ||
|
|
0e2058988e | ||
|
|
ab1a2a19d7 | ||
|
|
17a1d72b1c | ||
|
|
58ec1030a4 | ||
|
|
da01746e53 | ||
|
|
c329f65b41 | ||
|
|
18b03e1971 | ||
|
|
16a81fc221 | ||
|
|
50deae71f4 | ||
|
|
b1e5ca91cf | ||
|
|
185d0a5eca | ||
|
|
2b8aa2cb08 | ||
|
|
3c8fbc6b27 | ||
|
|
d212be018b | ||
|
|
573e219e30 | ||
|
|
5c3750df2c | ||
|
|
94e0e10e49 | ||
|
|
db9a8d5a18 | ||
|
|
7e20a8fc97 | ||
|
|
c7969aa052 | ||
|
|
179a500903 | ||
|
|
ab3e136867 | ||
|
|
8d2391d873 | ||
|
|
e1d62ff73a | ||
|
|
c3261d9813 | ||
|
|
1d8605fbf7 | ||
|
|
0843990dee | ||
|
|
6f8b39bb16 | ||
|
|
c39c8f9d74 | ||
|
|
e4c7bd3df8 | ||
|
|
8a4974025f | ||
|
|
51a9731cef | ||
|
|
051b270d36 | ||
|
|
ca234d7e42 | ||
|
|
5967e1ad0a | ||
|
|
bca980c115 | ||
|
|
a55b817968 | ||
|
|
b7c22515b7 | ||
|
|
70c773fe6d | ||
|
|
a3f809eb99 | ||
|
|
049a2de725 | ||
|
|
69947cd9fd | ||
|
|
c68b33f79f | ||
|
|
62f0da75bb | ||
|
|
6e2bde4060 | ||
|
|
e4a223d160 | ||
|
|
6d4d8d4b0c | ||
|
|
a4e6d1b67c | ||
|
|
3aaf7ff03a | ||
|
|
f6a5433503 | ||
|
|
92c10638a9 |
143
.zuul.yaml
143
.zuul.yaml
@@ -19,6 +19,42 @@
|
||||
devstack_services:
|
||||
designate: true
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-octavia
|
||||
parent: ansible-collections-openstack-functional-devstack
|
||||
description: |
|
||||
Run openstack collections functional tests against a master devstack
|
||||
with Octavia plugin enabled, using releases of openstacksdk and latest
|
||||
ansible release. Run it only on Load Balancer changes.
|
||||
pre-run: ci/playbooks/get_amphora_tarball.yaml
|
||||
required-projects:
|
||||
- openstack/octavia
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.11
|
||||
files:
|
||||
- ^ci/roles/loadbalancer/.*$
|
||||
- ^plugins/modules/lb_health_monitor.py
|
||||
- ^plugins/modules/lb_listener.py
|
||||
- ^plugins/modules/lb_member.py
|
||||
- ^plugins/modules/lb_pool.py
|
||||
- ^plugins/modules/loadbalancer.py
|
||||
vars:
|
||||
tox_envlist: ansible
|
||||
devstack_plugins:
|
||||
designate: https://opendev.org/openstack/designate
|
||||
octavia: https://opendev.org/openstack/octavia
|
||||
devstack_services:
|
||||
designate: true
|
||||
octavia: true
|
||||
o-api: true
|
||||
o-cw: true
|
||||
o-hk: true
|
||||
o-hm: true
|
||||
devstack_localrc:
|
||||
OCTAVIA_AMP_IMAGE_FILE: "/tmp/test-only-amphora-x64-haproxy-ubuntu-bionic.qcow2"
|
||||
OCTAVIA_AMP_IMAGE_SIZE: 3
|
||||
OCTAVIA_AMP_IMAGE_NAME: "test-only-amphora-x64-haproxy-ubuntu-bionic"
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-releases
|
||||
parent: ansible-collections-openstack-functional-devstack
|
||||
@@ -43,14 +79,14 @@
|
||||
tox_envlist: ansible-2.9
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-ansible-2.11
|
||||
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
|
||||
using master of openstacksdk and stable 2.11 branch of ansible
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
vars:
|
||||
tox_envlist: ansible
|
||||
|
||||
@@ -80,16 +116,16 @@
|
||||
|
||||
# Stable branches tests
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-victoria-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-victoria-ansible-2.11
|
||||
parent: ansible-collections-openstack-functional-devstack-ansible-devel
|
||||
description: |
|
||||
Run openstack collections functional tests against a victoria devstack
|
||||
using victoria brach of openstacksdk and stable 2.10 branch of ansible
|
||||
using victoria brach of openstacksdk and stable 2.11 branch of ansible
|
||||
voting: true
|
||||
override-checkout: stable/victoria
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
- name: openstack/openstacksdk
|
||||
override-checkout: stable/victoria
|
||||
vars:
|
||||
@@ -97,16 +133,16 @@
|
||||
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-ussuri-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-ussuri-ansible-2.11
|
||||
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.10 branch of ansible
|
||||
using ussuri brach of openstacksdk and stable 2.11 branch of ansible
|
||||
voting: true
|
||||
override-checkout: stable/ussuri
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
- name: openstack/openstacksdk
|
||||
override-checkout: stable/ussuri
|
||||
- name: openstack/os-client-config
|
||||
@@ -115,16 +151,16 @@
|
||||
tox_envlist: ansible
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-train-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-train-ansible-2.11
|
||||
parent: ansible-collections-openstack-functional-devstack-ansible-devel
|
||||
description: |
|
||||
Run openstack collections functional tests against a train devstack
|
||||
using train brach of openstacksdk and stable 2.10 branch of ansible
|
||||
using train brach of openstacksdk and stable 2.11 branch of ansible
|
||||
voting: false
|
||||
override-checkout: stable/train
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
- name: openstack/openstacksdk
|
||||
override-checkout: stable/train
|
||||
- name: openstack/os-client-config
|
||||
@@ -133,16 +169,16 @@
|
||||
tox_envlist: ansible
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-stein-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-stein-ansible-2.11
|
||||
parent: ansible-collections-openstack-functional-devstack-ansible-devel
|
||||
description: |
|
||||
Run openstack collections functional tests against a stein devstack
|
||||
using stein brach of openstacksdk and stable 2.10 branch of ansible
|
||||
using stein brach of openstacksdk and stable 2.11 branch of ansible
|
||||
voting: true
|
||||
override-checkout: stable/stein
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
- name: openstack/openstacksdk
|
||||
override-checkout: stable/stein
|
||||
- name: openstack/os-client-config
|
||||
@@ -151,16 +187,16 @@
|
||||
tox_envlist: ansible
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-rocky-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-rocky-ansible-2.11
|
||||
parent: ansible-collections-openstack-functional-devstack-ansible-devel
|
||||
description: |
|
||||
Run openstack collections functional tests against a rocky devstack
|
||||
using rocky brach of openstacksdk and stable 2.10 branch of ansible
|
||||
using rocky brach of openstacksdk and stable 2.11 branch of ansible
|
||||
voting: true
|
||||
override-checkout: stable/rocky
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
- name: openstack/openstacksdk
|
||||
override-checkout: stable/rocky
|
||||
- name: openstack/os-client-config
|
||||
@@ -172,16 +208,16 @@
|
||||
tox_envlist: ansible
|
||||
|
||||
- job:
|
||||
name: ansible-collections-openstack-functional-devstack-queens-ansible-2.10
|
||||
name: ansible-collections-openstack-functional-devstack-queens-ansible-2.11
|
||||
parent: ansible-collections-openstack-functional-devstack-ansible-devel
|
||||
description: |
|
||||
Run openstack collections functional tests against a queens devstack
|
||||
using master branch of openstacksdk and stable 2.10 branch of ansible
|
||||
using master branch of openstacksdk and stable 2.11 branch of ansible
|
||||
voting: true
|
||||
override-checkout: stable/queens
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
- name: openstack/openstacksdk
|
||||
# Run queens with highest possible py2 version of SDK
|
||||
override-checkout: stable/train
|
||||
@@ -222,15 +258,15 @@
|
||||
tox_envlist: linters-2.11
|
||||
|
||||
- job:
|
||||
name: openstack-tox-linters-ansible-2.10
|
||||
name: openstack-tox-linters-ansible-2.11
|
||||
parent: openstack-tox-linters
|
||||
nodeset: ubuntu-bionic
|
||||
description: |
|
||||
Run openstack collections linter tests using the 2.10 branch of ansible
|
||||
Run openstack collections linter tests using the 2.11 branch of ansible
|
||||
voting: true
|
||||
required-projects:
|
||||
- name: github.com/ansible/ansible
|
||||
override-checkout: stable-2.10
|
||||
override-checkout: stable-2.11
|
||||
|
||||
- job:
|
||||
name: openstack-tox-linters-ansible-2.9
|
||||
@@ -263,13 +299,13 @@
|
||||
jobs:
|
||||
- tox-pep8
|
||||
- openstack-tox-linters-ansible-devel
|
||||
- openstack-tox-linters-ansible-2.10
|
||||
- openstack-tox-linters-ansible-2.11
|
||||
- openstack-tox-linters-ansible-2.9
|
||||
- ansible-collections-openstack-functional-devstack:
|
||||
dependencies: &deps_unit_lint
|
||||
- tox-pep8
|
||||
- openstack-tox-linters-ansible-2.9
|
||||
- openstack-tox-linters-ansible-2.10
|
||||
- openstack-tox-linters-ansible-2.11
|
||||
irrelevant-files: &ignore_files
|
||||
- changelogs/.*
|
||||
- COPYING
|
||||
@@ -286,7 +322,7 @@
|
||||
- ansible-collections-openstack-functional-devstack-ansible-2.9:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-ansible-2.10:
|
||||
- ansible-collections-openstack-functional-devstack-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-ansible-devel:
|
||||
@@ -295,22 +331,29 @@
|
||||
- ansible-collections-openstack-functional-devstack-ansible-pip:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.10:
|
||||
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.10:
|
||||
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-train-ansible-2.10:
|
||||
- ansible-collections-openstack-functional-devstack-train-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-stein-ansible-2.10:
|
||||
voting: false
|
||||
- ansible-collections-openstack-functional-devstack-stein-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.10:
|
||||
voting: false
|
||||
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
- ansible-collections-openstack-functional-devstack-queens-ansible-2.10:
|
||||
voting: false
|
||||
- ansible-collections-openstack-functional-devstack-queens-ansible-2.11:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
voting: false
|
||||
- ansible-collections-openstack-functional-devstack-octavia:
|
||||
dependencies: *deps_unit_lint
|
||||
irrelevant-files: *ignore_files
|
||||
|
||||
@@ -326,37 +369,39 @@
|
||||
gate:
|
||||
jobs:
|
||||
- tox-pep8
|
||||
- openstack-tox-linters-ansible-2.10
|
||||
- openstack-tox-linters-ansible-2.11
|
||||
- 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-2.11
|
||||
- ansible-collections-openstack-functional-devstack-ansible-pip
|
||||
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.10
|
||||
# - ansible-collections-openstack-functional-devstack-train-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-stein-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-queens-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.11
|
||||
# - ansible-collections-openstack-functional-devstack-train-ansible-2.11
|
||||
# - ansible-collections-openstack-functional-devstack-stein-ansible-2.11
|
||||
# - ansible-collections-openstack-functional-devstack-rocky-ansible-2.11
|
||||
# - ansible-collections-openstack-functional-devstack-queens-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-octavia
|
||||
|
||||
periodic:
|
||||
jobs:
|
||||
- openstack-tox-linters-ansible-devel
|
||||
- openstack-tox-linters-ansible-2.10
|
||||
- openstack-tox-linters-ansible-2.11
|
||||
- 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-2.11
|
||||
- ansible-collections-openstack-functional-devstack-ansible-devel
|
||||
- ansible-collections-openstack-functional-devstack-ansible-pip
|
||||
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-train-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-stein-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-queens-ansible-2.10
|
||||
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-train-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-stein-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-rocky-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-queens-ansible-2.11
|
||||
- ansible-collections-openstack-functional-devstack-queens-ansible-devel
|
||||
- bifrost-collections-src
|
||||
- bifrost-keystone-collections-src
|
||||
- ansible-collections-openstack-functional-devstack-octavia
|
||||
|
||||
@@ -5,6 +5,69 @@ Openstack Cloud Ansilbe modules Release Notes
|
||||
.. contents:: Topics
|
||||
|
||||
|
||||
v1.4.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
New object_container module and bugfixes.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Add Octavia job for testing Load Balancer
|
||||
- Add binding profile to port module
|
||||
- Add execution environment metadata
|
||||
- Fix CI for latest ansible-test with no_log
|
||||
- Fix issues with newest ansible-test 2.11
|
||||
- Prepare for Ansible 2.11 tests
|
||||
- add option to exclude legacy groups
|
||||
- security_group_rule add support ipv6-icmp
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- openstack.cloud.object_container - Manage Swift container
|
||||
|
||||
v1.3.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
New modules and bugfixes.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Fix some typos in readme
|
||||
- Guidelines Fix links and formatting
|
||||
- baremetal_node - Add support for new features
|
||||
- baremetal_node - ironic deprecate sub-options of driver_info
|
||||
- baremetal_node - ironic stop putting meaningless values to properties
|
||||
- image_info - Migrating image_info module from AnsibleModule to OpenStackModule
|
||||
- recordset - Update recordset docu
|
||||
- server - Allow description field to be set with os_server
|
||||
- server_action - Added shelve and unshelve as new server actions
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- port - Fixed check for None in os_port
|
||||
- project - Fix setting custom property on os_project
|
||||
- security_group_rule - Remove protocols choice in security rules
|
||||
- volume_info - Fix volume_info result for SDK < 0.19
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- openstack.cloud.identity_role_info - Retrieve information about Openstack Identity roles.
|
||||
- openstack.cloud.keypair_info - Retrieve information about Openstack key pairs.
|
||||
- openstack.cloud.security_group_info - Retrieve information about Openstack Security Groups.
|
||||
- openstack.cloud.security_group_rule_info - Retrieve information about Openstack Security Group rules.
|
||||
- openstack.cloud.stack_info - Retrieve information about Openstack Heat stacks.
|
||||
|
||||
v1.2.1
|
||||
======
|
||||
|
||||
|
||||
12
README.md
12
README.md
@@ -11,7 +11,7 @@ The collection includes the Openstack modules and plugins supported by Openstack
|
||||
|
||||
### Installing dependencies
|
||||
|
||||
For using Openstack Cloud collection firstly need to install `ansible` and `openstacksdk` Python modules on Ansible controller.
|
||||
For using the Openstack Cloud collection firstly you need to install `ansible` and `openstacksdk` Python modules on your Ansible controller.
|
||||
For example with pip:
|
||||
|
||||
```bash
|
||||
@@ -19,8 +19,8 @@ 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.
|
||||
Please note, that under some circumstances Ansible might invoke a non-standard Python interpreter on the target host.
|
||||
Using Python version 3 is highly recommended for OpenstackSDK and strongly required from OpenstackSDK version 0.39.0.
|
||||
|
||||
---
|
||||
|
||||
@@ -39,7 +39,7 @@ Before using the Openstack Cloud collection, you need to install the collection
|
||||
|
||||
`ansible-galaxy collection install openstack.cloud`
|
||||
|
||||
You can also include it in a `requirements.yml` file and install it via `ansible-galaxy collection install -r requirements.yml` using the format:
|
||||
You can also include it in a `requirements.yml` file and install it through `ansible-galaxy collection install -r requirements.yml` using the format:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
@@ -48,7 +48,7 @@ collections:
|
||||
|
||||
### Playbooks
|
||||
|
||||
To use a module from Openstack Cloud collection, please reference the full namespace, collection name, and modules name that you want to use:
|
||||
To use a module from the Openstack Cloud collection, please reference the full namespace, collection name, and module name that you want to use:
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -66,7 +66,7 @@ To use a module from Openstack Cloud collection, please reference the full names
|
||||
volume_size: 75
|
||||
```
|
||||
|
||||
Or you can add full namepsace and collecton name in the `collections` element:
|
||||
Or you can add the full namespace and collection name in the `collections` element:
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
||||
@@ -1,111 +1,168 @@
|
||||
ancestor: null
|
||||
releases:
|
||||
1.2.1:
|
||||
release_date: '2021-01-03'
|
||||
changes:
|
||||
release_summary: Porting modules to new OpenstackModule class and fixes.
|
||||
minor_changes:
|
||||
- dns_zone, recordset - Enable update for recordset and add tests for dns and recordset module
|
||||
- loadbalancer - Refactor loadbalancer module
|
||||
- openstack - OpenStackModule Support defining a minimum version of the SDK
|
||||
- ironic - Refactor ironic authentication into a new module_utils module
|
||||
- endpoint - Do not fail when endpoint state is absent
|
||||
- subnet - Fix subnets update and idempotency
|
||||
- volume_info - Fix volume_info arguments for SDK 0.19
|
||||
- routers_info - Added deprecated_names for router_info module
|
||||
- security_group_rule - Refactor TCP/UDP port check
|
||||
- openstack - Fix docs-args mismatch in modules
|
||||
- security_group.py - Migrating security_group from AnsibleModule to OpenStackModule
|
||||
- router - Migrating routers from AnsibleModule to OpenStackModule
|
||||
- server_volume - Migrating server_volume from AnsibleModule to OpenStackModule
|
||||
- dns_zone - Migrating dns_zone from AnsibleModule to OpenStackModule
|
||||
- network - Migrating network from AnsibleModule to OpenStackModule
|
||||
- routers_info - Migrating routers_info from AnsibleModule to OpenStackModule
|
||||
- networks_info - Migrating networks_info from AnsibleModule to OpenStackModule
|
||||
- subnets_info - Migrating subnets_info from AnsibleModule to OpenStackModule
|
||||
- server.py - Improve "server" module with OpenstackModule class
|
||||
- volume.py - Migrating volume from AnsibleModule to OpenStackModule
|
||||
- subnet - Migrating subnet module from AnsibleModule to OpenStackModule
|
||||
- openstack - Add galaxy.yml to support install from git
|
||||
1.2.0:
|
||||
release_date: '2020-10-13'
|
||||
changes:
|
||||
release_summary: New volume backup modules.
|
||||
minor_changes:
|
||||
- lb_health_monitor - Make it possible to create a health monitor to a pool
|
||||
modules:
|
||||
- name: volume_snapshot_info module
|
||||
description: Retrieve information about Openstack volume snapshots.
|
||||
namespace: ''
|
||||
- name: volume_backup_info module
|
||||
description: Retrieve information about Openstack volume backups.
|
||||
namespace: ''
|
||||
- name: volume_backup module
|
||||
description: Add/Delete Openstack volumes backup.
|
||||
namespace: ''
|
||||
1.1.0:
|
||||
release_date: '2020-08-17'
|
||||
changes:
|
||||
release_summary: Starting redesign modules and bugfixes.
|
||||
minor_changes:
|
||||
- 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.
|
||||
- Add 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
|
||||
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
|
||||
- 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
|
||||
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
|
||||
release_summary: Initial release of collection.
|
||||
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: ''
|
||||
- description: Add support for Keystone Identity Providers
|
||||
name: federation_idp
|
||||
namespace: ''
|
||||
- description: Add support for fetching the information about federation IDPs
|
||||
name: federation_idp_info
|
||||
namespace: ''
|
||||
- description: Add support for Keystone mappings
|
||||
name: federation_mapping
|
||||
namespace: ''
|
||||
- description: Add support for fetching the information about Keystone mappings
|
||||
name: federation_mapping_info
|
||||
namespace: ''
|
||||
- description: Add support for Keystone federation Protocols
|
||||
name: keystone_federation_protocol
|
||||
namespace: ''
|
||||
- description: Add support for getting information about Keystone federation Protocols
|
||||
name: keystone_federation_protocol_info
|
||||
namespace: ''
|
||||
- description: Retrieve information about one or more OpenStack routers.
|
||||
name: routers_info
|
||||
namespace: ''
|
||||
release_date: '2020-05-19'
|
||||
1.0.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- server_info - Fix broken server_info module and add tests
|
||||
release_summary: Bugfix for server_info
|
||||
release_date: '2020-05-22'
|
||||
1.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fix non existing attribuites in SDK exception
|
||||
- security_group_rule - Don't pass tenant_id for remote group
|
||||
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
|
||||
release_summary: Starting redesign modules and bugfixes.
|
||||
modules:
|
||||
- description: Retrieve information about Openstack volumes.
|
||||
name: volume_info
|
||||
namespace: ''
|
||||
release_date: '2020-08-17'
|
||||
1.2.0:
|
||||
changes:
|
||||
minor_changes:
|
||||
- lb_health_monitor - Make it possible to create a health monitor to a pool
|
||||
release_summary: New volume backup modules.
|
||||
modules:
|
||||
- description: Add/Delete Openstack volumes backup.
|
||||
name: volume_backup module
|
||||
namespace: ''
|
||||
- description: Retrieve information about Openstack volume backups.
|
||||
name: volume_backup_info module
|
||||
namespace: ''
|
||||
- description: Retrieve information about Openstack volume snapshots.
|
||||
name: volume_snapshot_info module
|
||||
namespace: ''
|
||||
release_date: '2020-10-13'
|
||||
1.2.1:
|
||||
changes:
|
||||
minor_changes:
|
||||
- dns_zone - Migrating dns_zone from AnsibleModule to OpenStackModule
|
||||
- dns_zone, recordset - Enable update for recordset and add tests for dns and
|
||||
recordset module
|
||||
- endpoint - Do not fail when endpoint state is absent
|
||||
- ironic - Refactor ironic authentication into a new module_utils module
|
||||
- loadbalancer - Refactor loadbalancer module
|
||||
- network - Migrating network from AnsibleModule to OpenStackModule
|
||||
- networks_info - Migrating networks_info from AnsibleModule to OpenStackModule
|
||||
- openstack - Add galaxy.yml to support install from git
|
||||
- openstack - Fix docs-args mismatch in modules
|
||||
- openstack - OpenStackModule Support defining a minimum version of the SDK
|
||||
- router - Migrating routers from AnsibleModule to OpenStackModule
|
||||
- routers_info - Added deprecated_names for router_info module
|
||||
- routers_info - Migrating routers_info from AnsibleModule to OpenStackModule
|
||||
- security_group.py - Migrating security_group from AnsibleModule to OpenStackModule
|
||||
- security_group_rule - Refactor TCP/UDP port check
|
||||
- server.py - Improve "server" module with OpenstackModule class
|
||||
- server_volume - Migrating server_volume from AnsibleModule to OpenStackModule
|
||||
- subnet - Fix subnets update and idempotency
|
||||
- subnet - Migrating subnet module from AnsibleModule to OpenStackModule
|
||||
- subnets_info - Migrating subnets_info from AnsibleModule to OpenStackModule
|
||||
- volume.py - Migrating volume from AnsibleModule to OpenStackModule
|
||||
- volume_info - Fix volume_info arguments for SDK 0.19
|
||||
release_summary: Porting modules to new OpenstackModule class and fixes.
|
||||
release_date: '2021-01-03'
|
||||
1.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- port - Fixed check for None in os_port
|
||||
- project - Fix setting custom property on os_project
|
||||
- security_group_rule - Remove protocols choice in security rules
|
||||
- volume_info - Fix volume_info result for SDK < 0.19
|
||||
minor_changes:
|
||||
- Fix some typos in readme
|
||||
- Guidelines Fix links and formatting
|
||||
- baremetal_node - Add support for new features
|
||||
- baremetal_node - ironic deprecate sub-options of driver_info
|
||||
- baremetal_node - ironic stop putting meaningless values to properties
|
||||
- image_info - Migrating image_info module from AnsibleModule to OpenStackModule
|
||||
- recordset - Update recordset docu
|
||||
- server - Allow description field to be set with os_server
|
||||
- server_action - Added shelve and unshelve as new server actions
|
||||
release_summary: New modules and bugfixes.
|
||||
modules:
|
||||
- description: Retrieve information about Openstack Identity roles.
|
||||
name: identity_role_info
|
||||
namespace: ''
|
||||
- description: Retrieve information about Openstack key pairs.
|
||||
name: keypair_info
|
||||
namespace: ''
|
||||
- description: Retrieve information about Openstack Security Groups.
|
||||
name: security_group_info
|
||||
namespace: ''
|
||||
- description: Retrieve information about Openstack Security Group rules.
|
||||
name: security_group_rule_info
|
||||
namespace: ''
|
||||
- description: Retrieve information about Openstack Heat stacks.
|
||||
name: stack_info
|
||||
namespace: ''
|
||||
release_date: '2021-02-16'
|
||||
1.4.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Add Octavia job for testing Load Balancer
|
||||
- Add binding profile to port module
|
||||
- Add execution environment metadata
|
||||
- Fix CI for latest ansible-test with no_log
|
||||
- Fix issues with newest ansible-test 2.11
|
||||
- Prepare for Ansible 2.11 tests
|
||||
- add option to exclude legacy groups
|
||||
- security_group_rule add support ipv6-icmp
|
||||
release_summary: New object_container module and bugfixes.
|
||||
modules:
|
||||
- description: Manage Swift container
|
||||
name: object_container
|
||||
namespace: ''
|
||||
release_date: '2021-04-08'
|
||||
|
||||
6
ci/playbooks/get_amphora_tarball.yaml
Normal file
6
ci/playbooks/get_amphora_tarball.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: Download amphora tarball
|
||||
get_url:
|
||||
url: "https://tarballs.openstack.org/octavia/test-images/test-only-amphora-x64-haproxy-ubuntu-bionic.qcow2"
|
||||
dest: /tmp/test-only-amphora-x64-haproxy-ubuntu-bionic.qcow2
|
||||
@@ -15,7 +15,16 @@
|
||||
disk_format: raw
|
||||
register: image
|
||||
|
||||
- debug: var=image
|
||||
- name: Get details of created image
|
||||
openstack.cloud.image_info:
|
||||
cloud: "{{ cloud }}"
|
||||
image: "{{ image_name }}"
|
||||
register: image_info_result
|
||||
|
||||
- name: Verify image info
|
||||
assert:
|
||||
that:
|
||||
- "image_info_result.openstack_image.name == image_name"
|
||||
|
||||
- name: Delete raw image (defaults)
|
||||
openstack.cloud.image:
|
||||
@@ -40,8 +49,6 @@
|
||||
distro: ubuntu
|
||||
register: image
|
||||
|
||||
- debug: var=image
|
||||
|
||||
- name: Delete raw image (complex)
|
||||
openstack.cloud.image:
|
||||
cloud: "{{ cloud }}"
|
||||
@@ -52,3 +59,14 @@
|
||||
file:
|
||||
name: "{{ tmp_file.stdout }}"
|
||||
state: absent
|
||||
|
||||
- name: Try to get details of deleted image
|
||||
openstack.cloud.image_info:
|
||||
cloud: "{{ cloud }}"
|
||||
image: "{{ image_name }}"
|
||||
register: deleted_image_info_result
|
||||
|
||||
- name: Verify image is deleted
|
||||
assert:
|
||||
that:
|
||||
- not deleted_image_info_result.openstack_image
|
||||
@@ -7,6 +7,17 @@
|
||||
register:
|
||||
keypair
|
||||
|
||||
- name: Get list of keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
register: keypairs
|
||||
|
||||
- name: Ensure that list of keypairs contains single element
|
||||
assert:
|
||||
that:
|
||||
- keypairs['openstack_keypairs']|length == 1
|
||||
|
||||
# This assert verifies that Ansible is capable serializing data returned by SDK
|
||||
- name: Ensure private key is returned
|
||||
assert:
|
||||
@@ -19,6 +30,17 @@
|
||||
name: "{{ keypair_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Get list of keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
register: keypairs
|
||||
|
||||
- name: Ensure that list of keypairs is empty
|
||||
assert:
|
||||
that:
|
||||
- keypairs['openstack_keypairs']|length == 0
|
||||
|
||||
- name: Generate test key file
|
||||
user:
|
||||
name: "{{ ansible_env.USER }}"
|
||||
@@ -32,12 +54,34 @@
|
||||
state: present
|
||||
public_key_file: "{{ ansible_env.HOME }}/.ssh/shade_id_rsa.pub"
|
||||
|
||||
- name: Get list of keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
register: keypairs
|
||||
|
||||
- name: Ensure that list of keypairs contains single element
|
||||
assert:
|
||||
that:
|
||||
- keypairs['openstack_keypairs']|length == 1
|
||||
|
||||
- name: Delete keypair (file)
|
||||
openstack.cloud.keypair:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Get list of keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
register: keypairs
|
||||
|
||||
- name: Ensure that list of keypairs is empty
|
||||
assert:
|
||||
that:
|
||||
- keypairs['openstack_keypairs']|length == 0
|
||||
|
||||
- name: Create keypair (key)
|
||||
openstack.cloud.keypair:
|
||||
cloud: "{{ cloud }}"
|
||||
@@ -45,12 +89,34 @@
|
||||
state: present
|
||||
public_key: "{{ lookup('file', '~/.ssh/shade_id_rsa.pub') }}"
|
||||
|
||||
- name: Get list of keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
register: keypairs
|
||||
|
||||
- name: Ensure that list of keypairs contains single element
|
||||
assert:
|
||||
that:
|
||||
- keypairs['openstack_keypairs']|length == 1
|
||||
|
||||
- name: Delete keypair (key)
|
||||
openstack.cloud.keypair:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Get list of keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ keypair_name }}"
|
||||
register: keypairs
|
||||
|
||||
- name: Ensure that list of keypairs is empty
|
||||
assert:
|
||||
that:
|
||||
- keypairs['openstack_keypairs']|length == 0
|
||||
|
||||
- name: Delete test key pub file
|
||||
file:
|
||||
name: "{{ ansible_env.HOME }}/.ssh/shade_id_rsa.pub"
|
||||
|
||||
@@ -5,6 +5,29 @@
|
||||
state: present
|
||||
name: "{{ role_name }}"
|
||||
|
||||
- name: List keystone roles
|
||||
openstack.cloud.identity_role_info:
|
||||
cloud: "{{ cloud }}"
|
||||
register: roles
|
||||
|
||||
- name: Check roles
|
||||
assert:
|
||||
that:
|
||||
- roles.openstack_roles | length > 0
|
||||
- "'{{ role_name }}' in (roles.openstack_roles | map(attribute='name') | list)"
|
||||
|
||||
- name: List keystone roles by name
|
||||
openstack.cloud.identity_role_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ role_name}}"
|
||||
register: roles1
|
||||
|
||||
- name: Check roles
|
||||
assert:
|
||||
that:
|
||||
- roles1.openstack_roles | length == 1
|
||||
- roles1.openstack_roles[0]['name'] == role_name
|
||||
|
||||
- name: Delete keystone role
|
||||
openstack.cloud.identity_role:
|
||||
cloud: "{{ cloud }}"
|
||||
|
||||
3
ci/roles/loadbalancer/defaults/main.yml
Normal file
3
ci/roles/loadbalancer/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
network_name: network_lb
|
||||
subnet_name: subnet_lb
|
||||
lb_name: test_lb
|
||||
50
ci/roles/loadbalancer/tasks/main.yml
Normal file
50
ci/roles/loadbalancer/tasks/main.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
---
|
||||
- name: Create network {{ network_name }} for LB
|
||||
openstack.cloud.network:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ network_name }}"
|
||||
state: present
|
||||
|
||||
- name: Create subnet {{ subnet_name }} on network {{ network_name }} for LB
|
||||
openstack.cloud.subnet:
|
||||
cloud: "{{ cloud }}"
|
||||
network_name: "{{ network_name }}"
|
||||
name: "{{ subnet_name }}"
|
||||
state: present
|
||||
enable_dhcp: true
|
||||
dns_nameservers:
|
||||
- 8.8.8.7
|
||||
- 8.8.8.8
|
||||
cidr: 192.168.0.0/24
|
||||
gateway_ip: 192.168.0.1
|
||||
allocation_pool_start: 192.168.0.2
|
||||
allocation_pool_end: 192.168.0.254
|
||||
|
||||
- name: Create loadbalancer - generic
|
||||
openstack.cloud.loadbalancer:
|
||||
cloud: "{{ cloud }}"
|
||||
state: present
|
||||
name: "{{ lb_name }}"
|
||||
vip_subnet: "{{ subnet_name }}"
|
||||
timeout: 450
|
||||
|
||||
- name: Delete loadbalancer
|
||||
openstack.cloud.loadbalancer:
|
||||
cloud: "{{ cloud }}"
|
||||
state: absent
|
||||
name: "{{ lb_name }}"
|
||||
timeout: 150
|
||||
|
||||
- name: Delete subnet {{ subnet_name }} on network {{ network_name }}
|
||||
openstack.cloud.subnet:
|
||||
cloud: "{{ cloud }}"
|
||||
network_name: "{{ network_name }}"
|
||||
name: "{{ subnet_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Delete network {{ network_name }} of LB
|
||||
openstack.cloud.network:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ network_name }}"
|
||||
state: absent
|
||||
1
ci/roles/object_container/defaults/main.yml
Normal file
1
ci/roles/object_container/defaults/main.yml
Normal file
@@ -0,0 +1 @@
|
||||
container_name: "test-container"
|
||||
60
ci/roles/object_container/tasks/main.yml
Normal file
60
ci/roles/object_container/tasks/main.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
- module_defaults:
|
||||
openstack.cloud.object_container:
|
||||
cloud: "{{ cloud }}"
|
||||
block:
|
||||
- name: Create an empty container
|
||||
openstack.cloud.object_container:
|
||||
container: "{{ container_name }}"
|
||||
register: container
|
||||
|
||||
- name: Verify container was created
|
||||
assert:
|
||||
that:
|
||||
- container is success
|
||||
- container is changed
|
||||
- container.container.name == container_name
|
||||
|
||||
- name: Set metadata for a container
|
||||
openstack.cloud.object_container:
|
||||
container: "{{ container_name }}"
|
||||
metadata: "Cache-Control='no-cache'"
|
||||
register: set_meta
|
||||
|
||||
- name: Verify container metadata was set
|
||||
assert:
|
||||
that:
|
||||
- set_meta is success
|
||||
- set_meta is changed
|
||||
|
||||
- name: Delete some keys from container metadata
|
||||
openstack.cloud.object_container:
|
||||
container: "{{ container_name }}"
|
||||
keys:
|
||||
- Cache-Control
|
||||
register: delete_meta
|
||||
|
||||
- name: Verify some keys from container metadata was deleted
|
||||
assert:
|
||||
that:
|
||||
- delete_meta is success
|
||||
- delete_meta is changed
|
||||
|
||||
- name: Delete container
|
||||
openstack.cloud.object_container:
|
||||
container: "{{ container_name }}"
|
||||
state: absent
|
||||
register: deleted
|
||||
|
||||
- name: Verify container was deleted
|
||||
assert:
|
||||
that:
|
||||
- deleted is success
|
||||
- deleted is changed
|
||||
|
||||
always:
|
||||
- name: Delete container
|
||||
openstack.cloud.object_container:
|
||||
container: "{{ container_name }}"
|
||||
state: absent
|
||||
ignore_errors: yes
|
||||
2
ci/roles/orchestration/defaults/main.yaml
Normal file
2
ci/roles/orchestration/defaults/main.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
stack_name: "test-stack"
|
||||
11
ci/roles/orchestration/files/hello-world.yaml
Normal file
11
ci/roles/orchestration/files/hello-world.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# Minimal HOT template defining a single compute server.
|
||||
#
|
||||
heat_template_version: 2013-05-23
|
||||
|
||||
description: >
|
||||
Minimal HOT template for stack
|
||||
|
||||
parameters:
|
||||
resources:
|
||||
outputs:
|
||||
44
ci/roles/orchestration/tasks/main.yaml
Normal file
44
ci/roles/orchestration/tasks/main.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
- name: Create minimal stack
|
||||
openstack.cloud.stack:
|
||||
cloud: "{{ cloud }}"
|
||||
# template is searched related to playbook location or as absolute path
|
||||
template: "roles/orchestration/files/hello-world.yaml"
|
||||
name: "{{ stack_name }}"
|
||||
|
||||
- name: List stacks
|
||||
openstack.cloud.stack_info:
|
||||
cloud: "{{ cloud }}"
|
||||
register: stacks
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- stacks['stacks']|length > 0
|
||||
|
||||
- name: Get Single stack
|
||||
openstack.cloud.stack_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ stack_name }}"
|
||||
register: test_stack
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- test_stack is defined
|
||||
- test_stack['stacks'][0]['name'] == stack_name
|
||||
|
||||
- name: Delete stack
|
||||
openstack.cloud.stack:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ stack_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Get Single stack
|
||||
openstack.cloud.stack_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ stack_name }}"
|
||||
register: stacks
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- stacks is defined
|
||||
- stacks['stacks']|length == 0
|
||||
@@ -4,3 +4,6 @@ subnet_name: ansible_port_subnet
|
||||
port_name: ansible_port
|
||||
secgroup_name: ansible_port_secgroup
|
||||
no_security_groups: True
|
||||
binding_profile:
|
||||
"pci_slot": "0000:03:11.1"
|
||||
"physical_network": "provider"
|
||||
|
||||
@@ -88,6 +88,30 @@
|
||||
state: absent
|
||||
name: "{{ secgroup_name }}"
|
||||
|
||||
- name: Test port binding config (runs from train release sdk > 0.28)
|
||||
block:
|
||||
- name: Create port (with binding profile)
|
||||
openstack.cloud.port:
|
||||
cloud: "{{ cloud }}"
|
||||
state: present
|
||||
name: "{{ port_name }}"
|
||||
network: "{{ network_name }}"
|
||||
binding_profile: "{{ binding_profile }}"
|
||||
register: port
|
||||
|
||||
- name: Assert binding:profile exists in created port
|
||||
assert:
|
||||
that: "port.port['binding:profile']"
|
||||
|
||||
- debug: var=port
|
||||
|
||||
- name: Delete port (with binding profile)
|
||||
openstack.cloud.port:
|
||||
cloud: "{{ cloud }}"
|
||||
state: absent
|
||||
name: "{{ port_name }}"
|
||||
when: sdk_version is version(0.28, '>')
|
||||
|
||||
- name: Delete subnet
|
||||
openstack.cloud.subnet:
|
||||
cloud: "{{ cloud }}"
|
||||
|
||||
@@ -101,6 +101,71 @@
|
||||
remote_ip_prefix: 0.0.0.0/0
|
||||
direction: egress
|
||||
|
||||
- name: List all available rules of all security groups in a project
|
||||
openstack.cloud.security_group_rule_info:
|
||||
cloud: "{{ cloud }}"
|
||||
when: sdk_version is version("0.32", '>=')
|
||||
register: test_sec_rules
|
||||
|
||||
- name: Check - List all available rules of all security groups in a project
|
||||
assert:
|
||||
that:
|
||||
- test_sec_rules.security_group_rules | length > 0
|
||||
when: sdk_version is version("0.32", '>=')
|
||||
|
||||
- name: List all available rules of a specific security group
|
||||
openstack.cloud.security_group_rule_info:
|
||||
cloud: "{{ cloud }}"
|
||||
security_group: "{{ secgroup_name }}"
|
||||
register: test_sec_rule1
|
||||
|
||||
- name: Check - List all available rules of a specific security group
|
||||
assert:
|
||||
that:
|
||||
- test_sec_rule1.security_group_rules | length > 0
|
||||
|
||||
- name: List all available rules with filters
|
||||
openstack.cloud.security_group_rule_info:
|
||||
cloud: "{{ cloud }}"
|
||||
security_group: "{{ secgroup_name }}"
|
||||
protocol: tcp
|
||||
port_range_min: 80
|
||||
port_range_max: 80
|
||||
remote_ip_prefix: 0.0.0.0/0
|
||||
when: sdk_version is version("0.32", '>=')
|
||||
register: test_sec_rule
|
||||
|
||||
- name: Check - List all available rules with filters
|
||||
assert:
|
||||
that:
|
||||
- test_sec_rule.security_group_rules | length == 1
|
||||
when: sdk_version is version("0.32", '>=')
|
||||
|
||||
- name: List all security groups of a project
|
||||
openstack.cloud.security_group_info:
|
||||
cloud: "{{ cloud }}"
|
||||
register: test_sec_groups
|
||||
|
||||
- name: Check - List all security groups of a project
|
||||
assert:
|
||||
that:
|
||||
- test_sec_groups.security_groups | length > 0
|
||||
|
||||
- name: Filter security group by name
|
||||
openstack.cloud.security_group_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ secgroup_name }}"
|
||||
register: test_sec_group
|
||||
|
||||
- name: Check - List all security groups of a project
|
||||
assert:
|
||||
that:
|
||||
- test_sec_group.security_groups | length == 1
|
||||
- test_sec_group.security_groups[0]['name'] == secgroup_name
|
||||
# This fails on Stein only
|
||||
when: sdk_version is version("0.36.5", '>=')
|
||||
|
||||
|
||||
- name: Delete empty ICMP rule
|
||||
openstack.cloud.security_group_rule:
|
||||
cloud: "{{ cloud }}"
|
||||
|
||||
@@ -418,3 +418,103 @@
|
||||
that:
|
||||
- info19.openstack_servers.0.status in ('ACTIVE', 'REBUILD')
|
||||
- server is changed
|
||||
|
||||
- name: Shelve server
|
||||
openstack.cloud.server_action:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
action: shelve
|
||||
wait: true
|
||||
register: server
|
||||
|
||||
- name: Get info about server
|
||||
openstack.cloud.server_info:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
register: info20
|
||||
|
||||
- name: Ensure status for server is SHELVED or SHELVED_OFFLOADED
|
||||
assert:
|
||||
that:
|
||||
- info20.openstack_servers.0.status in ['SHELVED', 'SHELVED_OFFLOADED']
|
||||
- server is changed
|
||||
|
||||
- name: Shelve offload server
|
||||
openstack.cloud.server_action:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
action: shelve_offload
|
||||
wait: true
|
||||
register: server
|
||||
|
||||
- name: Get info about server
|
||||
openstack.cloud.server_info:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
register: info21
|
||||
|
||||
- name: Ensure status for server is SHELVED_OFFLOADED
|
||||
# no change if server has been offloaded automatically after first shelve command
|
||||
assert:
|
||||
that:
|
||||
- info21.openstack_servers.0.status == 'SHELVED_OFFLOADED'
|
||||
|
||||
- name: Shelve offload server again
|
||||
openstack.cloud.server_action:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
action: shelve_offload
|
||||
wait: true
|
||||
register: server
|
||||
|
||||
- name: Get info about server
|
||||
openstack.cloud.server_info:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
register: info22
|
||||
|
||||
- name: Ensure status for server is SHELVED_OFFLOADED
|
||||
assert:
|
||||
that:
|
||||
- info22.openstack_servers.0.status == 'SHELVED_OFFLOADED'
|
||||
- server is not changed
|
||||
|
||||
- name: Unshelve server
|
||||
openstack.cloud.server_action:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
action: unshelve
|
||||
wait: true
|
||||
register: server
|
||||
|
||||
- name: Get info about server
|
||||
openstack.cloud.server_info:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
register: info23
|
||||
|
||||
- name: Ensure status for server is ACTIVE
|
||||
assert:
|
||||
that:
|
||||
- info23.openstack_servers.0.status == 'ACTIVE'
|
||||
- server is changed
|
||||
|
||||
- name: Unshelve server again
|
||||
openstack.cloud.server_action:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
action: unshelve
|
||||
wait: true
|
||||
register: server
|
||||
|
||||
- name: Get info about server
|
||||
openstack.cloud.server_info:
|
||||
cloud: "{{ cloud }}"
|
||||
server: "{{ server_name }}"
|
||||
register: info24
|
||||
|
||||
- name: Ensure status for server is ACTIVE
|
||||
assert:
|
||||
that:
|
||||
- info24.openstack_servers.0.status == 'ACTIVE'
|
||||
- server is not changed
|
||||
|
||||
@@ -68,4 +68,3 @@
|
||||
display_name: ansible_volume
|
||||
|
||||
- include_tasks: volume_info.yml
|
||||
|
||||
|
||||
@@ -106,6 +106,27 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# In case of Octavia enabled:
|
||||
_octavia_image_path="/tmp/test-only-amphora-x64-haproxy-ubuntu-bionic.qcow2"
|
||||
if systemctl list-units --full -all | grep -Fq "devstack@o-api.service" && \
|
||||
test -f "$_octavia_image_path"
|
||||
then
|
||||
# Upload apmhora image for Octavia to test load balancers
|
||||
OCTAVIA_AMP_IMAGE_FILE=${OCTAVIA_AMP_IMAGE_FILE:-"$_octavia_image_path"}
|
||||
OCTAVIA_AMP_IMAGE_NAME=${OCTAVIA_AMP_IMAGE_NAME:-"test-only-amphora-x64-haproxy-ubuntu-bionic"}
|
||||
OCTAVIA_AMP_IMAGE_SIZE=${OCTAVIA_AMP_IMAGE_SIZE:-3}
|
||||
openstack --os-cloud=${CLOUD} image create \
|
||||
--container-format bare \
|
||||
--disk-format qcow2 \
|
||||
--private \
|
||||
--file $OCTAVIA_AMP_IMAGE_FILE \
|
||||
--project service $OCTAVIA_AMP_IMAGE_NAME
|
||||
openstack --os-cloud=${CLOUD} image set --tag amphora $OCTAVIA_AMP_IMAGE_NAME
|
||||
# End of Octavia preparement
|
||||
else
|
||||
tag_opt="$tag_opt --skip-tags loadbalancer"
|
||||
fi
|
||||
|
||||
# Discover openstackSDK version
|
||||
SDK_VER=$(python -c "import openstack; print(openstack.version.__version__)")
|
||||
pushd ci/
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
roles:
|
||||
- { role: auth, tags: auth }
|
||||
- { role: client_config, tags: client_config }
|
||||
- role: object_container
|
||||
tags: object_container
|
||||
when: sdk_version is version(0.18, '>=')
|
||||
- { role: group, tags: group }
|
||||
- role: dns
|
||||
tags: dns
|
||||
@@ -39,3 +42,8 @@
|
||||
- { role: user_group, tags: user_group }
|
||||
- { role: user_role, tags: user_role }
|
||||
- { role: volume, tags: volume }
|
||||
- role: orchestration
|
||||
tags: orchestrate
|
||||
when: sdk_version is version("0.53.0", '>=')
|
||||
- role: loadbalancer
|
||||
tags: loadbalancer
|
||||
|
||||
@@ -58,10 +58,10 @@ Libraries
|
||||
users as a primary audience, they are for intra-server communication.
|
||||
* All modules should be registered in ``meta/action_groups.yml`` for enabling the
|
||||
variables to be set in `group level
|
||||
<https://docs.ansible.com/ansible/latest/user_guide/playbooks_module_defaults.html>`.
|
||||
<https://docs.ansible.com/ansible/latest/user_guide/playbooks_module_defaults.html>`_.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
* Integration testing is currently done in `OpenStack's CI system
|
||||
<https://opendev.org/openstack/ansible-collections-openstack/src/branch/master/zuul.yaml>`
|
||||
<https://opendev.org/openstack/ansible-collections-openstack/src/branch/master/.zuul.yaml>`_
|
||||
|
||||
@@ -18,7 +18,7 @@ build_ignore:
|
||||
- ci
|
||||
- galaxy.yml.in
|
||||
- setup.cfg
|
||||
- test-requirements.txt
|
||||
- test-requirements*
|
||||
- tests
|
||||
- tools
|
||||
- tox.ini
|
||||
@@ -29,8 +29,8 @@ build_ignore:
|
||||
- importer_result.json
|
||||
- .tox
|
||||
- .env
|
||||
- .vscode
|
||||
- ansible_collections_openstack.egg-info
|
||||
- contrib
|
||||
- changelogs/.plugin-cache.yaml
|
||||
- changelogs/fragments
|
||||
version: 1.2.1
|
||||
- changelogs
|
||||
version: 1.4.0
|
||||
|
||||
@@ -53,6 +53,7 @@ action_groups:
|
||||
- image
|
||||
- image_info
|
||||
- keypair
|
||||
- keypair_info
|
||||
- keystone_federation_protocol
|
||||
- keystone_federation_protocol_info
|
||||
- lb_listener
|
||||
@@ -65,6 +66,7 @@ action_groups:
|
||||
- network
|
||||
- networks_info
|
||||
- object
|
||||
- object_container
|
||||
- port
|
||||
- port_info
|
||||
- project
|
||||
@@ -77,7 +79,9 @@ action_groups:
|
||||
- router
|
||||
- routers_info
|
||||
- security_group
|
||||
- security_group_info
|
||||
- security_group_rule
|
||||
- security_group_rule_info
|
||||
- server
|
||||
- server_action
|
||||
- server_group
|
||||
@@ -147,6 +151,7 @@ action_groups:
|
||||
- image
|
||||
- image_info
|
||||
- keypair
|
||||
- keypair_info
|
||||
- keystone_federation_protocol
|
||||
- keystone_federation_protocol_info
|
||||
- lb_listener
|
||||
@@ -159,6 +164,7 @@ action_groups:
|
||||
- network
|
||||
- networks_info
|
||||
- object
|
||||
- object_container
|
||||
- port
|
||||
- port_info
|
||||
- project
|
||||
@@ -171,7 +177,9 @@ action_groups:
|
||||
- router
|
||||
- routers_info
|
||||
- security_group
|
||||
- security_group_info
|
||||
- security_group_rule
|
||||
- security_group_rule_info
|
||||
- server
|
||||
- server_action
|
||||
- server_group
|
||||
|
||||
@@ -98,6 +98,10 @@ options:
|
||||
description: Add hosts to group based on Jinja2 conditionals.
|
||||
type: dictionary
|
||||
default: {}
|
||||
legacy_groups:
|
||||
description: Automatically create groups from host variables.
|
||||
type: bool
|
||||
default: true
|
||||
|
||||
extends_documentation_fragment:
|
||||
- inventory_cache
|
||||
@@ -361,8 +365,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
openstack=server)
|
||||
self.inventory.add_host(current_host)
|
||||
|
||||
for group in self._get_groups_from_server(server, namegroup=namegroup):
|
||||
groups[group].append(current_host)
|
||||
if self.get_option('legacy_groups'):
|
||||
for group in self._get_groups_from_server(server, namegroup=namegroup):
|
||||
groups[group].append(current_host)
|
||||
|
||||
def verify_file(self, path):
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ class OpenStackModule:
|
||||
"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')
|
||||
version='2.0.0', collection_name='openstack.cloud')
|
||||
|
||||
def openstack_cloud_from_module(self):
|
||||
"""Sets up connection to cloud using provided options. Checks if all
|
||||
|
||||
@@ -43,29 +43,71 @@ options:
|
||||
endpoint URL for the Ironic API. Use with "auth" and "auth_type"
|
||||
settings set to None.
|
||||
type: str
|
||||
resource_class:
|
||||
description:
|
||||
- The specific resource type to which this node belongs.
|
||||
type: str
|
||||
bios_interface:
|
||||
description:
|
||||
- The bios interface for this node, e.g. "no-bios".
|
||||
type: str
|
||||
boot_interface:
|
||||
description:
|
||||
- The boot interface for this node, e.g. "pxe".
|
||||
type: str
|
||||
console_interface:
|
||||
description:
|
||||
- The console interface for this node, e.g. "no-console".
|
||||
type: str
|
||||
deploy_interface:
|
||||
description:
|
||||
- The deploy interface for this node, e.g. "iscsi".
|
||||
type: str
|
||||
inspect_interface:
|
||||
description:
|
||||
- The interface used for node inspection, e.g. "no-inspect".
|
||||
type: str
|
||||
management_interface:
|
||||
description:
|
||||
- The interface for out-of-band management of this node, e.g.
|
||||
"ipmitool".
|
||||
type: str
|
||||
network_interface:
|
||||
description:
|
||||
- The network interface provider to use when describing
|
||||
connections for this node.
|
||||
type: str
|
||||
power_interface:
|
||||
description:
|
||||
- The interface used to manage power actions on this node, e.g.
|
||||
"ipmitool".
|
||||
type: str
|
||||
raid_interface:
|
||||
description:
|
||||
- Interface used for configuring raid on this node.
|
||||
type: str
|
||||
rescue_interface:
|
||||
description:
|
||||
- Interface used for node rescue, e.g. "no-rescue".
|
||||
type: str
|
||||
storage_interface:
|
||||
description:
|
||||
- Interface used for attaching and detaching volumes on this node, e.g.
|
||||
"cinder".
|
||||
type: str
|
||||
vendor_interface:
|
||||
description:
|
||||
- Interface for all vendor-specific actions on this node, e.g.
|
||||
"no-vendor".
|
||||
type: str
|
||||
driver_info:
|
||||
description:
|
||||
- Information for this server's driver. Will vary based on which
|
||||
driver is in use. Any sub-field which is populated will be validated
|
||||
during creation.
|
||||
during creation. For compatibility reasons sub-fields `power`,
|
||||
`deploy`, `management` and `console` are flattened.
|
||||
required: true
|
||||
type: dict
|
||||
suboptions:
|
||||
power:
|
||||
description:
|
||||
- Information necessary to turn this server on / off.
|
||||
This often includes such things as IPMI username, password, and IP address.
|
||||
required: true
|
||||
deploy:
|
||||
description:
|
||||
- Information necessary to deploy this server directly, without using Nova. THIS IS NOT RECOMMENDED.
|
||||
console:
|
||||
description:
|
||||
- Information necessary to connect to this server's serial console. Not all drivers support this.
|
||||
management:
|
||||
description:
|
||||
- Information necessary to interact with this server's management interface. May be shared by power_info in some cases.
|
||||
required: true
|
||||
nics:
|
||||
description:
|
||||
- 'A list of network interface cards, eg, " - mac: aa:bb:cc:aa:bb:cc"'
|
||||
@@ -149,10 +191,9 @@ EXAMPLES = '''
|
||||
- mac: "aa:bb:cc:aa:bb:cc"
|
||||
- mac: "dd:ee:ff:dd:ee:ff"
|
||||
driver_info:
|
||||
power:
|
||||
ipmi_address: "1.2.3.4"
|
||||
ipmi_username: "admin"
|
||||
ipmi_password: "adminpass"
|
||||
ipmi_address: "1.2.3.4"
|
||||
ipmi_username: "admin"
|
||||
ipmi_password: "adminpass"
|
||||
chassis_uuid: "00000000-0000-0000-0000-000000000001"
|
||||
|
||||
'''
|
||||
@@ -174,31 +215,35 @@ from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
|
||||
)
|
||||
|
||||
|
||||
_PROPERTIES = {
|
||||
'cpu_arch': 'cpu_arch',
|
||||
'cpus': 'cpus',
|
||||
'ram': 'memory_mb',
|
||||
'disk_size': 'local_gb',
|
||||
'capabilities': 'capabilities',
|
||||
'root_device': 'root_device',
|
||||
}
|
||||
|
||||
|
||||
def _parse_properties(module):
|
||||
"""Convert ansible properties into native ironic values.
|
||||
|
||||
Also filter out any properties that are not set.
|
||||
"""
|
||||
p = module.params['properties']
|
||||
props = dict(
|
||||
cpu_arch=p.get('cpu_arch') if p.get('cpu_arch') else 'x86_64',
|
||||
cpus=p.get('cpus') if p.get('cpus') else 1,
|
||||
memory_mb=p.get('ram') if p.get('ram') else 1,
|
||||
local_gb=p.get('disk_size') if p.get('disk_size') else 1,
|
||||
capabilities=p.get('capabilities') if p.get('capabilities') else '',
|
||||
root_device=p.get('root_device') if p.get('root_device') else '',
|
||||
)
|
||||
return props
|
||||
return {to_key: p[from_key] for (from_key, to_key) in _PROPERTIES.items()
|
||||
if p.get(from_key) is not None}
|
||||
|
||||
|
||||
def _parse_driver_info(sdk, module):
|
||||
p = module.params['driver_info']
|
||||
info = p.get('power')
|
||||
if not info:
|
||||
raise sdk.exceptions.OpenStackCloudException(
|
||||
"driver_info['power'] is required")
|
||||
if p.get('console'):
|
||||
info.update(p.get('console'))
|
||||
if p.get('management'):
|
||||
info.update(p.get('management'))
|
||||
if p.get('deploy'):
|
||||
info.update(p.get('deploy'))
|
||||
info = module.params['driver_info'].copy()
|
||||
for deprecated in ('power', 'console', 'management', 'deploy'):
|
||||
if deprecated in info:
|
||||
info.update(info.pop(deprecated))
|
||||
module.deprecate("Suboption %s of the driver_info parameter of "
|
||||
"'openstack.cloud.baremetal_node' is deprecated"
|
||||
% deprecated, version='2.0.0',
|
||||
collection_name='openstack.cloud')
|
||||
return info
|
||||
|
||||
|
||||
@@ -233,6 +278,19 @@ def main():
|
||||
uuid=dict(required=False),
|
||||
name=dict(required=False),
|
||||
driver=dict(required=False),
|
||||
resource_class=dict(required=False),
|
||||
bios_interface=dict(required=False),
|
||||
boot_interface=dict(required=False),
|
||||
console_interface=dict(required=False),
|
||||
deploy_interface=dict(required=False),
|
||||
inspect_interface=dict(required=False),
|
||||
management_interface=dict(required=False),
|
||||
network_interface=dict(required=False),
|
||||
power_interface=dict(required=False),
|
||||
raid_interface=dict(required=False),
|
||||
rescue_interface=dict(required=False),
|
||||
storage_interface=dict(required=False),
|
||||
vendor_interface=dict(required=False),
|
||||
driver_info=dict(type='dict', required=True),
|
||||
nics=dict(type='list', required=True, elements="dict"),
|
||||
properties=dict(type='dict', default={}),
|
||||
@@ -269,6 +327,22 @@ def main():
|
||||
driver_info=driver_info,
|
||||
name=module.params['name'],
|
||||
)
|
||||
optional_field_names = ('resource_class',
|
||||
'bios_interface',
|
||||
'boot_interface',
|
||||
'console_interface',
|
||||
'deploy_interface',
|
||||
'inspect_interface',
|
||||
'management_interface',
|
||||
'network_interface',
|
||||
'power_interface',
|
||||
'raid_interface',
|
||||
'rescue_interface',
|
||||
'storage_interface',
|
||||
'vendor_interface')
|
||||
for i in optional_field_names:
|
||||
if module.params[i]:
|
||||
kwargs[i] = module.params[i]
|
||||
|
||||
if module.params['chassis_uuid']:
|
||||
kwargs['chassis_uuid'] = module.params['chassis_uuid']
|
||||
|
||||
@@ -230,7 +230,7 @@ def main():
|
||||
discovery_url=dict(default=None),
|
||||
docker_volume_size=dict(type='int'),
|
||||
flavor_id=dict(default=None),
|
||||
keypair=dict(default=None),
|
||||
keypair=dict(default=None, no_log=False),
|
||||
labels=dict(default=None, type='raw'),
|
||||
master_count=dict(type='int', default=1),
|
||||
master_flavor_id=dict(default=None),
|
||||
|
||||
@@ -184,7 +184,8 @@ def main():
|
||||
is_old_facts = module._name == 'openstack.cloud.compute_flavor_facts'
|
||||
if is_old_facts:
|
||||
module.deprecate("The 'openstack.cloud.compute_flavor_facts' module has been renamed to 'openstack.cloud.compute_flavor_info', "
|
||||
"and the renamed one no longer returns ansible_facts", version='2.13')
|
||||
"and the renamed one no longer returns ansible_facts", version='2.0.0',
|
||||
collection_name='openstack.cloud')
|
||||
|
||||
name = module.params['name']
|
||||
vcpus = module.params['vcpus']
|
||||
|
||||
1
plugins/modules/container.py
Symbolic link
1
plugins/modules/container.py
Symbolic link
@@ -0,0 +1 @@
|
||||
object_container.py
|
||||
@@ -102,7 +102,8 @@ def main():
|
||||
is_old_facts = module._name == 'openstack.cloud.identity_domain_facts'
|
||||
if is_old_facts:
|
||||
module.deprecate("The 'openstack.cloud.identity_domain_facts' module has been renamed to 'openstack.cloud.identity_domain_info', "
|
||||
"and the renamed one no longer returns ansible_facts", version='2.13')
|
||||
"and the renamed one no longer returns ansible_facts", version='2.0.0',
|
||||
collection_name='openstack.cloud')
|
||||
|
||||
sdk, opcloud = openstack_cloud_from_module(module)
|
||||
try:
|
||||
|
||||
103
plugins/modules/identity_role_info.py
Normal file
103
plugins/modules/identity_role_info.py
Normal file
@@ -0,0 +1,103 @@
|
||||
#!/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: identity_role_info
|
||||
short_description: Retrive information about roles
|
||||
author: OpenStack Ansible SIG
|
||||
description:
|
||||
- Get information about identity roles in Openstack
|
||||
options:
|
||||
domain_id:
|
||||
description:
|
||||
- List roles in specified domain only
|
||||
type: str
|
||||
required: false
|
||||
name:
|
||||
description:
|
||||
- List role speficied by name
|
||||
type: str
|
||||
required: false
|
||||
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
|
||||
extends_documentation_fragment:
|
||||
- openstack.cloud.openstack
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
openstack_roles:
|
||||
description: List of identity roles
|
||||
returned: always
|
||||
type: list
|
||||
elements: dict
|
||||
sample:
|
||||
- domain_id: None
|
||||
id: 19bf514fdda84f808ccee8463bd85c1a
|
||||
location:
|
||||
cloud: mycloud
|
||||
project:
|
||||
domain_id: None
|
||||
domain_name: None
|
||||
id: None
|
||||
name: None
|
||||
region_name: None
|
||||
zone: None
|
||||
name: member
|
||||
properties:
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Retrieve info about all roles
|
||||
- openstack.cloud.identity_role_info:
|
||||
cloud: mycloud
|
||||
|
||||
# Retrieve info about all roles in specific domain
|
||||
- openstack.cloud.identity_role_info:
|
||||
cloud: mycloud
|
||||
domain_id: some_domain_id
|
||||
|
||||
# Retrieve info about role 'admin'
|
||||
- openstack.cloud.identity_role_info:
|
||||
cloud: mycloud
|
||||
name: admin
|
||||
|
||||
'''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
|
||||
|
||||
|
||||
class IdentityRoleInfoModule(OpenStackModule):
|
||||
|
||||
argument_spec = dict(
|
||||
domain_id=dict(type='str', required=False),
|
||||
name=dict(type='str', required=False),
|
||||
)
|
||||
module_kwargs = dict(
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
def run(self):
|
||||
roles = self.conn.list_roles(domain_id=self.params['domain_id'])
|
||||
# Dictionaries are supported from Train release
|
||||
roles = [item if isinstance(item, dict) else item.to_dict() for item in roles]
|
||||
# Filtering by name is supported from Wallaby release
|
||||
if self.params['name']:
|
||||
roles = [item for item in roles if self.params['name'] in (item['id'], item['name'])]
|
||||
self.results.update({'openstack_roles': roles})
|
||||
|
||||
|
||||
def main():
|
||||
module = IdentityRoleInfoModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -126,7 +126,8 @@ def main():
|
||||
is_old_facts = module._name == 'openstack.cloud.identity_user_facts'
|
||||
if is_old_facts:
|
||||
module.deprecate("The 'openstack.cloud.identity_user_facts' module has been renamed to 'openstack.cloud.identity_user_info', "
|
||||
"and the renamed one no longer returns ansible_facts", version='2.13')
|
||||
"and the renamed one no longer returns ansible_facts", version='2.0.0',
|
||||
collection_name='openstack.cloud')
|
||||
|
||||
sdk, opcloud = openstack_cloud_from_module(module)
|
||||
try:
|
||||
|
||||
@@ -142,44 +142,31 @@ openstack_image:
|
||||
type: int
|
||||
'''
|
||||
|
||||
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
|
||||
|
||||
|
||||
class ImageInfoModule(OpenStackModule):
|
||||
|
||||
deprecated_names = ('openstack.cloud.os_image_facts', 'openstack.cloud.os_image_info')
|
||||
|
||||
argument_spec = dict(
|
||||
image=dict(type='str', required=False),
|
||||
properties=dict(type='dict', required=False),
|
||||
)
|
||||
|
||||
def run(self):
|
||||
|
||||
if self.params['image']:
|
||||
image = self.conn.get_image(self.params['image'])
|
||||
self.exit(changed=False, openstack_image=image)
|
||||
else:
|
||||
images = self.conn.search_images(filters=self.params['properties'])
|
||||
self.exit(changed=False, openstack_image=images)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
image=dict(required=False),
|
||||
properties=dict(default=None, type='dict'),
|
||||
)
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec, **module_kwargs)
|
||||
is_old_facts = module._name == 'openstack.cloud.image_facts'
|
||||
if is_old_facts:
|
||||
module.deprecate("The 'openstack.cloud.image_facts' module has been renamed to 'openstack.cloud.image_info', "
|
||||
"and the renamed one no longer returns ansible_facts", version='2.13')
|
||||
|
||||
sdk, cloud = openstack_cloud_from_module(module)
|
||||
try:
|
||||
if module.params['image']:
|
||||
image = cloud.get_image(module.params['image'])
|
||||
if is_old_facts:
|
||||
module.exit_json(changed=False, ansible_facts=dict(
|
||||
openstack_image=image))
|
||||
else:
|
||||
module.exit_json(changed=False, openstack_image=image)
|
||||
else:
|
||||
images = cloud.search_images(filters=module.params['properties'])
|
||||
if is_old_facts:
|
||||
module.exit_json(changed=False, ansible_facts=dict(
|
||||
openstack_image=images))
|
||||
else:
|
||||
module.exit_json(changed=False, openstack_image=images)
|
||||
|
||||
except sdk.exceptions.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
module = ImageInfoModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
153
plugins/modules/keypair_info.py
Normal file
153
plugins/modules/keypair_info.py
Normal file
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2021 T-Systems International GmbH
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: keypair_info
|
||||
short_description: Get information about keypairs from OpenStack
|
||||
author: OpenStack Ansible SIG
|
||||
description:
|
||||
- Get information about keypairs that are associated with the account
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name or ID of the keypair
|
||||
type: str
|
||||
user_id:
|
||||
description:
|
||||
- It allows admin users to operate key-pairs of specified user ID.
|
||||
type: str
|
||||
limit:
|
||||
description:
|
||||
- Requests a page size of items.
|
||||
- Returns a number of items up to a limit value.
|
||||
type: int
|
||||
marker:
|
||||
description:
|
||||
- The last-seen item.
|
||||
type: str
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
|
||||
extends_documentation_fragment:
|
||||
- openstack.cloud.openstack
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Get information about keypairs
|
||||
openstack.cloud.keypair_info:
|
||||
register: result
|
||||
|
||||
- name: Get information about keypairs using optional parameters
|
||||
openstack.cloud.keypair_info:
|
||||
name: "test"
|
||||
user_id: "fed75b36fd7a4078a769178d2b1bd844"
|
||||
limit: 10
|
||||
marker: "jdksl"
|
||||
register: result
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
openstack_keypairs:
|
||||
description:
|
||||
- Lists keypairs that are associated with the account.
|
||||
type: complex
|
||||
returned: always
|
||||
contains:
|
||||
created_at:
|
||||
description:
|
||||
- The date and time when the resource was created.
|
||||
type: str
|
||||
sample: "2021-01-19T14:52:07.261634"
|
||||
id:
|
||||
description:
|
||||
- The id identifying the keypair
|
||||
type: str
|
||||
sample: "keypair-5d935425-31d5-48a7-a0f1-e76e9813f2c3"
|
||||
is_deleted:
|
||||
description:
|
||||
- A boolean indicates whether this keypair is deleted or not.
|
||||
type: bool
|
||||
fingerprint:
|
||||
description:
|
||||
- The fingerprint for the keypair.
|
||||
type: str
|
||||
sample: "7e:eb:ab:24:ba:d1:e1:88:ae:9a:fb:66:53:df:d3:bd"
|
||||
name:
|
||||
description:
|
||||
- A keypair name which will be used to reference it later.
|
||||
type: str
|
||||
sample: "keypair-5d935425-31d5-48a7-a0f1-e76e9813f2c3"
|
||||
private_key:
|
||||
description:
|
||||
- The private key for the keypair.
|
||||
type: str
|
||||
sample: "MIICXAIBAAKBgQCqGKukO ... hZj6+H0qtjTkVxwTCpvKe4eCZ0FPq"
|
||||
public_key:
|
||||
description:
|
||||
- The keypair public key.
|
||||
type: str
|
||||
sample: "ssh-rsa AAAAB3NzaC1yc ... 8rPsBUHNLQp Generated-by-Nova"
|
||||
type:
|
||||
description:
|
||||
- The type of the keypair.
|
||||
- Allowed values are ssh or x509.
|
||||
type: str
|
||||
sample: "ssh"
|
||||
user_id:
|
||||
description:
|
||||
- It allows admin users to operate key-pairs of specified user ID.
|
||||
type: str
|
||||
sample: "59b10f2a2138428ea9358e10c7e44444"
|
||||
'''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
|
||||
OpenStackModule)
|
||||
|
||||
|
||||
class KeyPairInfoModule(OpenStackModule):
|
||||
argument_spec = dict(
|
||||
name=dict(type='str', required=False),
|
||||
user_id=dict(type='str', required=False),
|
||||
limit=dict(type='int', required=False),
|
||||
marker=dict(type='str', required=False)
|
||||
)
|
||||
|
||||
def run(self):
|
||||
name = self.params['name']
|
||||
user_id = self.params['user_id']
|
||||
limit = self.params['limit']
|
||||
marker = self.params['marker']
|
||||
|
||||
filters = {}
|
||||
data = []
|
||||
|
||||
if user_id:
|
||||
filters['user_id'] = user_id
|
||||
if limit:
|
||||
filters['limit'] = limit
|
||||
if marker:
|
||||
filters['marker'] = marker
|
||||
|
||||
result = self.conn.search_keypairs(name_or_id=name,
|
||||
filters=filters)
|
||||
raws = [raw if isinstance(raw, dict) else raw.to_dict()
|
||||
for raw in result]
|
||||
|
||||
for raw in raws:
|
||||
raw.pop('location')
|
||||
data.append(raw)
|
||||
|
||||
self.exit(changed=False, openstack_keypairs=data)
|
||||
|
||||
|
||||
def main():
|
||||
module = KeyPairInfoModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
207
plugins/modules/object_container.py
Normal file
207
plugins/modules/object_container.py
Normal file
@@ -0,0 +1,207 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2021 by Open Telekom Cloud, operated by T-Systems International GmbH
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: object_container
|
||||
short_description: Manage Swift container.
|
||||
author: OpenStack Ansible SIG
|
||||
description:
|
||||
- Manage Swift container.
|
||||
options:
|
||||
container:
|
||||
description: Name of a container in Swift.
|
||||
type: str
|
||||
required: true
|
||||
metadata:
|
||||
description:
|
||||
- Key/value pairs to be set as metadata on the container.
|
||||
- If a container doesn't exist, it will be created.
|
||||
- Both custom and system metadata can be set.
|
||||
- Custom metadata are keys and values defined by the user.
|
||||
- The system metadata keys are content_type, content_encoding, content_disposition, delete_after,\
|
||||
delete_at, is_content_type_detected
|
||||
type: dict
|
||||
required: false
|
||||
keys:
|
||||
description: Keys from 'metadata' to be deleted.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
delete_with_all_objects:
|
||||
description:
|
||||
- Whether the container should be deleted with all objects or not.
|
||||
- Without this parameter set to "true", an attempt to delete a container that contains objects will fail.
|
||||
type: bool
|
||||
default: False
|
||||
required: false
|
||||
state:
|
||||
description: Whether resource should be present or absent.
|
||||
default: 'present'
|
||||
choices: ['present', 'absent']
|
||||
type: str
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
|
||||
extends_documentation_fragment:
|
||||
- openstack.cloud.openstack
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
container:
|
||||
description: Specifies the container.
|
||||
returned: On success when C(state=present)
|
||||
type: dict
|
||||
sample:
|
||||
{
|
||||
"bytes": 5449,
|
||||
"bytes_used": 5449,
|
||||
"content_type": null,
|
||||
"count": 1,
|
||||
"id": "otc",
|
||||
"if_none_match": null,
|
||||
"is_content_type_detected": null,
|
||||
"is_newest": null,
|
||||
"meta_temp_url_key": null,
|
||||
"meta_temp_url_key_2": null,
|
||||
"name": "otc",
|
||||
"object_count": 1,
|
||||
"read_ACL": null,
|
||||
"sync_key": null,
|
||||
"sync_to": null,
|
||||
"timestamp": null,
|
||||
"versions_location": null,
|
||||
"write_ACL": null
|
||||
}
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create empty container
|
||||
- openstack.cloud.object_container:
|
||||
container: "new-container"
|
||||
state: present
|
||||
|
||||
# Set metadata for container
|
||||
- openstack.cloud.object_container:
|
||||
container: "new-container"
|
||||
metadata: "Cache-Control='no-cache'"
|
||||
|
||||
# Delete some keys from metadata of a container
|
||||
- openstack.cloud.object_container:
|
||||
container: "new-container"
|
||||
keys:
|
||||
- content_type
|
||||
|
||||
# Delete container
|
||||
- openstack.cloud.object_container:
|
||||
container: "new-container"
|
||||
state: absent
|
||||
|
||||
# Delete container and its objects
|
||||
- openstack.cloud.object_container:
|
||||
container: "new-container"
|
||||
delete_with_all_objects: true
|
||||
state: absent
|
||||
'''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
|
||||
|
||||
|
||||
class ContainerModule(OpenStackModule):
|
||||
|
||||
argument_spec = dict(
|
||||
container=dict(type='str', required=True),
|
||||
metadata=dict(type='dict', required=False),
|
||||
keys=dict(type='list', required=False, elements='str', no_log=False),
|
||||
state=dict(type='str', required=False, default='present', choices=['present', 'absent']),
|
||||
delete_with_all_objects=dict(type='bool', default=False, required=False)
|
||||
)
|
||||
|
||||
def create(self, container):
|
||||
|
||||
data = {}
|
||||
if self._container_exist(container):
|
||||
self.exit_json(changed=False)
|
||||
|
||||
container_data = self.conn.object_store.create_container(name=container).to_dict()
|
||||
container_data.pop('location')
|
||||
data['container'] = container_data
|
||||
self.exit_json(changed=True, **data)
|
||||
|
||||
def delete(self, container):
|
||||
|
||||
delete_with_all_objects = self.params['delete_with_all_objects']
|
||||
|
||||
changed = False
|
||||
if self._container_exist(container):
|
||||
objects = []
|
||||
for raw in self.conn.object_store.objects(container):
|
||||
dt = raw.to_dict()
|
||||
dt.pop('location')
|
||||
objects.append(dt)
|
||||
if len(objects) > 0:
|
||||
if delete_with_all_objects:
|
||||
for obj in objects:
|
||||
self.conn.object_store.delete_object(container=container, obj=obj['id'])
|
||||
else:
|
||||
self.fail_json(msg="Container has objects")
|
||||
self.conn.object_store.delete_container(container=container)
|
||||
changed = True
|
||||
|
||||
self.exit(changed=changed)
|
||||
|
||||
def set_metadata(self, container, metadata):
|
||||
|
||||
data = {}
|
||||
|
||||
if not self._container_exist(container):
|
||||
new_container = self.conn.object_store.create_container(name=container).to_dict()
|
||||
|
||||
new_container = self.conn.object_store.set_container_metadata(container, **metadata).to_dict()
|
||||
new_container.pop('location')
|
||||
data['container'] = new_container
|
||||
self.exit(changed=True, **data)
|
||||
|
||||
def delete_metadata(self, container, keys):
|
||||
|
||||
if not self._container_exist(container):
|
||||
self.fail_json(msg="Container doesn't exist")
|
||||
|
||||
self.conn.object_store.delete_container_metadata(container=container, keys=keys)
|
||||
self.exit(changed=True)
|
||||
|
||||
def _container_exist(self, container):
|
||||
try:
|
||||
self.conn.object_store.get_container_metadata(container)
|
||||
return True
|
||||
except self.sdk.exceptions.ResourceNotFound:
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
|
||||
container = self.params['container']
|
||||
state = self.params['state']
|
||||
metadata = self.params['metadata']
|
||||
keys = self.params['keys']
|
||||
|
||||
if state == 'absent':
|
||||
self.delete(container)
|
||||
if metadata:
|
||||
self.set_metadata(container, metadata)
|
||||
if keys:
|
||||
self.delete_metadata(container, keys)
|
||||
|
||||
self.create(container)
|
||||
|
||||
|
||||
def main():
|
||||
module = ContainerModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -119,6 +119,10 @@ options:
|
||||
description:
|
||||
- Whether to enable or disable the port security on the network.
|
||||
type: bool
|
||||
binding_profile:
|
||||
description:
|
||||
- Binding profile dict that the port should be created with.
|
||||
type: dict
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
@@ -199,6 +203,20 @@ EXAMPLES = '''
|
||||
name: port1
|
||||
network: foo
|
||||
vnic_type: direct
|
||||
|
||||
# Create a port with binding profile
|
||||
- openstack.cloud.port:
|
||||
state: present
|
||||
auth:
|
||||
auth_url: https://identity.example.com
|
||||
username: admin
|
||||
password: admin
|
||||
project_name: admin
|
||||
name: port1
|
||||
network: foo
|
||||
binding_profile:
|
||||
"pci_slot": "0000:03:11.1"
|
||||
"physical_network": "provider"
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
@@ -246,6 +264,10 @@ port_security_enabled:
|
||||
description: Port security state on the network.
|
||||
returned: success
|
||||
type: bool
|
||||
binding:profile:
|
||||
description: Port binded profile
|
||||
returned: success
|
||||
type: dict
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
@@ -274,7 +296,8 @@ def _needs_update(module, port, cloud):
|
||||
'device_owner',
|
||||
'device_id',
|
||||
'binding:vnic_type',
|
||||
'port_security_enabled']
|
||||
'port_security_enabled',
|
||||
'binding:profile']
|
||||
compare_list_dict = ['allowed_address_pairs',
|
||||
'extra_dhcp_opts']
|
||||
compare_list = ['security_groups']
|
||||
@@ -290,7 +313,7 @@ def _needs_update(module, port, cloud):
|
||||
return True
|
||||
|
||||
for key in compare_list_dict:
|
||||
if not module.params[key]:
|
||||
if module.params[key]:
|
||||
if not port[key]:
|
||||
return True
|
||||
|
||||
@@ -357,7 +380,8 @@ def _compose_port_args(module, cloud):
|
||||
'device_owner',
|
||||
'device_id',
|
||||
'binding:vnic_type',
|
||||
'port_security_enabled']
|
||||
'port_security_enabled',
|
||||
'binding:profile']
|
||||
for optional_param in optional_parameters:
|
||||
if module.params[optional_param] is not None:
|
||||
port_kwargs[optional_param] = module.params[optional_param]
|
||||
@@ -393,7 +417,8 @@ def main():
|
||||
vnic_type=dict(default=None,
|
||||
choices=['normal', 'direct', 'direct-physical',
|
||||
'macvtap', 'baremetal', 'virtio-forwarder']),
|
||||
port_security_enabled=dict(default=None, type='bool')
|
||||
port_security_enabled=dict(default=None, type='bool'),
|
||||
binding_profile=dict(default=None, type='dict')
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs(
|
||||
@@ -424,6 +449,9 @@ def main():
|
||||
# Neutron API accept 'binding:vnic_type' as an argument
|
||||
# for the port type.
|
||||
module.params['binding:vnic_type'] = module.params.pop('vnic_type')
|
||||
# Neutron API accept 'binding:profile' as an argument
|
||||
# for the port binding profile type.
|
||||
module.params['binding:profile'] = module.params.pop('binding_profile')
|
||||
|
||||
port = None
|
||||
network_id = None
|
||||
|
||||
@@ -195,7 +195,8 @@ def main():
|
||||
is_old_facts = module._name == 'openstack.cloud.port_facts'
|
||||
if is_old_facts:
|
||||
module.deprecate("The 'openstack.cloud.port_facts' module has been renamed to 'openstack.cloud.port_info', "
|
||||
"and the renamed one no longer returns ansible_facts", version='2.13')
|
||||
"and the renamed one no longer returns ansible_facts", version='2.0.0',
|
||||
collection_name='openstack.cloud')
|
||||
|
||||
port = module.params.get('port')
|
||||
filters = module.params.get('filters')
|
||||
|
||||
@@ -115,7 +115,7 @@ def _needs_update(module, project):
|
||||
if properties:
|
||||
project_properties = project.get('properties')
|
||||
for k, v in properties.items():
|
||||
if v is not None and v != project_properties[k]:
|
||||
if v is not None and (k not in project_properties or v != project_properties[k]):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@@ -115,7 +115,8 @@ def main():
|
||||
is_old_facts = module._name == 'openstack.cloud.project_facts'
|
||||
if is_old_facts:
|
||||
module.deprecate("The 'openstack.cloud.project_facts' module has been renamed to 'openstack.cloud.project_info', "
|
||||
"and the renamed one no longer returns ansible_facts", version='2.13')
|
||||
"and the renamed one no longer returns ansible_facts", version='2.0.0',
|
||||
collection_name='openstack.cloud')
|
||||
|
||||
sdk, opcloud = openstack_cloud_from_module(module)
|
||||
try:
|
||||
|
||||
@@ -381,7 +381,7 @@ def main():
|
||||
injected_files=dict(required=False, type='int', default=None),
|
||||
injected_path_size=dict(required=False, type='int', default=None),
|
||||
instances=dict(required=False, type='int', default=None),
|
||||
key_pairs=dict(required=False, type='int', default=None),
|
||||
key_pairs=dict(required=False, type='int', default=None, no_log=False),
|
||||
loadbalancer=dict(required=False, type='int', default=None),
|
||||
network=dict(required=False, type='int', default=None),
|
||||
per_volume_gigabytes=dict(required=False, type='int', default=None),
|
||||
|
||||
@@ -74,6 +74,8 @@ EXAMPLES = '''
|
||||
state: present
|
||||
zone: example.net.
|
||||
name: www.example.net.
|
||||
recordset_type: "a"
|
||||
records: ['10.1.1.1']
|
||||
ttl: 7200
|
||||
|
||||
# Delete recordset named "www.example.net."
|
||||
|
||||
193
plugins/modules/security_group_info.py
Normal file
193
plugins/modules/security_group_info.py
Normal file
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2020 by Open Telekom Cloud, operated by T-Systems International GmbH
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: security_group_info
|
||||
short_description: Lists security groups
|
||||
extends_documentation_fragment: openstack.cloud.openstack
|
||||
author: OpenStack Ansible SIG
|
||||
description:
|
||||
- List security groups
|
||||
options:
|
||||
description:
|
||||
description:
|
||||
- Description of the security group
|
||||
type: str
|
||||
name:
|
||||
description:
|
||||
- Name or id of the security group.
|
||||
type: str
|
||||
project_id:
|
||||
description:
|
||||
- Specifies the project id as filter criteria
|
||||
type: str
|
||||
revision_number:
|
||||
description:
|
||||
- Filter the list result by the revision number of the
|
||||
- resource.
|
||||
type: int
|
||||
tags:
|
||||
description:
|
||||
- A list of tags to filter the list result by.
|
||||
- Resources that match all tags in this list will be returned.
|
||||
type: list
|
||||
elements: str
|
||||
any_tags:
|
||||
description:
|
||||
- A list of tags to filter the list result by.
|
||||
- Resources that match any tag in this list will be returned.
|
||||
type: list
|
||||
elements: str
|
||||
not_tags:
|
||||
description:
|
||||
- A list of tags to filter the list result by.
|
||||
- Resources that match all tags in this list will be excluded.
|
||||
type: list
|
||||
elements: str
|
||||
not_any_tags:
|
||||
description:
|
||||
- A list of tags to filter the list result by.
|
||||
- Resources that match any tag in this list will be excluded.
|
||||
type: list
|
||||
elements: str
|
||||
|
||||
requirements: ["openstacksdk"]
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
security_groups:
|
||||
description: List of dictionaries describing security groups.
|
||||
type: complex
|
||||
returned: On Success.
|
||||
contains:
|
||||
created_at:
|
||||
description: Creation time of the security group
|
||||
type: str
|
||||
sample: "yyyy-mm-dd hh:mm:ss"
|
||||
description:
|
||||
description: Description of the security group
|
||||
type: str
|
||||
sample: "My security group"
|
||||
id:
|
||||
description: ID of the security group
|
||||
type: str
|
||||
sample: "d90e55ba-23bd-4d97-b722-8cb6fb485d69"
|
||||
name:
|
||||
description: Name of the security group.
|
||||
type: str
|
||||
sample: "my-sg"
|
||||
project_id:
|
||||
description: Project ID where the security group is located in.
|
||||
type: str
|
||||
sample: "25d24fc8-d019-4a34-9fff-0a09fde6a567"
|
||||
security_group_rules:
|
||||
description: Specifies the security group rule list
|
||||
type: list
|
||||
sample: [
|
||||
{
|
||||
"id": "d90e55ba-23bd-4d97-b722-8cb6fb485d69",
|
||||
"direction": "ingress",
|
||||
"protocol": null,
|
||||
"ethertype": "IPv4",
|
||||
"description": null,
|
||||
"remote_group_id": "0431c9c5-1660-42e0-8a00-134bec7f03e2",
|
||||
"remote_ip_prefix": null,
|
||||
"tenant_id": "bbfe8c41dd034a07bebd592bf03b4b0c",
|
||||
"port_range_max": null,
|
||||
"port_range_min": null,
|
||||
"security_group_id": "0431c9c5-1660-42e0-8a00-134bec7f03e2"
|
||||
},
|
||||
{
|
||||
"id": "aecff4d4-9ce9-489c-86a3-803aedec65f7",
|
||||
"direction": "egress",
|
||||
"protocol": null,
|
||||
"ethertype": "IPv4",
|
||||
"description": null,
|
||||
"remote_group_id": null,
|
||||
"remote_ip_prefix": null,
|
||||
"tenant_id": "bbfe8c41dd034a07bebd592bf03b4b0c",
|
||||
"port_range_max": null,
|
||||
"port_range_min": null,
|
||||
"security_group_id": "0431c9c5-1660-42e0-8a00-134bec7f03e2"
|
||||
}
|
||||
]
|
||||
updated_at:
|
||||
description: Update time of the security group
|
||||
type: str
|
||||
sample: "yyyy-mm-dd hh:mm:ss"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Get specific security group
|
||||
- openstack.cloud.security_group_info:
|
||||
cloud: "{{ cloud }}"
|
||||
name: "{{ my_sg }}"
|
||||
register: sg
|
||||
# Get all security groups
|
||||
- openstack.cloud.security_group_info:
|
||||
cloud: "{{ cloud }}"
|
||||
register: sg
|
||||
'''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
|
||||
OpenStackModule)
|
||||
|
||||
|
||||
class SecurityGroupInfoModule(OpenStackModule):
|
||||
argument_spec = dict(
|
||||
description=dict(required=False, type='str'),
|
||||
name=dict(required=False, type='str'),
|
||||
project_id=dict(required=False, type='str'),
|
||||
revision_number=dict(required=False, type='int'),
|
||||
tags=dict(required=False, type='list', elements='str'),
|
||||
any_tags=dict(required=False, type='list', elements='str'),
|
||||
not_tags=dict(required=False, type='list', elements='str'),
|
||||
not_any_tags=dict(required=False, type='list', elements='str')
|
||||
)
|
||||
|
||||
def run(self):
|
||||
description = self.params['description']
|
||||
name = self.params['name']
|
||||
project_id = self.params['project_id']
|
||||
revision_number = self.params['revision_number']
|
||||
tags = self.params['tags']
|
||||
any_tags = self.params['any_tags']
|
||||
not_tags = self.params['not_tags']
|
||||
not_any_tags = self.params['not_any_tags']
|
||||
|
||||
attrs = {}
|
||||
|
||||
if description:
|
||||
attrs['description'] = description
|
||||
if project_id:
|
||||
attrs['project_id'] = project_id
|
||||
if revision_number:
|
||||
attrs['revision_number'] = revision_number
|
||||
if tags:
|
||||
attrs['tags'] = ','.join(tags)
|
||||
if any_tags:
|
||||
attrs['any_tags'] = ','.join(any_tags)
|
||||
if not_tags:
|
||||
attrs['not_tags'] = ','.join(not_tags)
|
||||
if not_any_tags:
|
||||
attrs['not_any_tags'] = ','.join(not_any_tags)
|
||||
|
||||
attrs = self.check_versioned(**attrs)
|
||||
result = self.conn.network.security_groups(**attrs)
|
||||
result = [item if isinstance(item, dict) else item.to_dict() for item in result]
|
||||
if name:
|
||||
result = [item for item in result if name in (item['id'], item['name'])]
|
||||
self.results.update({'security_groups': result})
|
||||
|
||||
|
||||
def main():
|
||||
module = SecurityGroupInfoModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -19,8 +19,7 @@ options:
|
||||
type: str
|
||||
protocol:
|
||||
description:
|
||||
- IP protocols ANY TCP UDP ICMP 112 (VRRP) 132 (SCTP)
|
||||
choices: ['any', 'tcp', 'udp', 'icmp', '112', '132', None]
|
||||
- IP protocols ANY TCP UDP ICMP and others, also number in range 0-255
|
||||
type: str
|
||||
port_range_min:
|
||||
description:
|
||||
@@ -203,7 +202,7 @@ def _ports_match(protocol, module_min, module_max, rule_min, rule_max):
|
||||
"""
|
||||
|
||||
# Check if the user is supplying -1 for ICMP.
|
||||
if protocol == 'icmp':
|
||||
if protocol in ['icmp', 'ipv6-icmp']:
|
||||
if module_min and int(module_min) == -1:
|
||||
module_min = None
|
||||
if module_max and int(module_max) == -1:
|
||||
@@ -246,14 +245,11 @@ class SecurityGroupRuleModule(OpenStackModule):
|
||||
|
||||
argument_spec = dict(
|
||||
security_group=dict(required=True),
|
||||
# NOTE(Shrews): None is an acceptable protocol value for
|
||||
# Neutron, but Nova will balk at this.
|
||||
protocol=dict(default=None,
|
||||
choices=[None, 'any', 'tcp', 'udp', 'icmp', '112', '132']),
|
||||
protocol=dict(type='str'),
|
||||
port_range_min=dict(required=False, type='int'),
|
||||
port_range_max=dict(required=False, type='int'),
|
||||
remote_ip_prefix=dict(required=False, default=None),
|
||||
remote_group=dict(required=False, default=None),
|
||||
remote_ip_prefix=dict(required=False),
|
||||
remote_group=dict(required=False),
|
||||
ethertype=dict(default='IPv4',
|
||||
choices=['IPv4', 'IPv6']),
|
||||
direction=dict(default='ingress',
|
||||
|
||||
250
plugins/modules/security_group_rule_info.py
Normal file
250
plugins/modules/security_group_rule_info.py
Normal file
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2020 by Tino Schreiber (Open Telekom Cloud), operated by T-Systems International GmbH
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: security_group_rule_info
|
||||
short_description: Querying security group rules
|
||||
author: OpenStack Ansible SIG
|
||||
description:
|
||||
- Querying security group rules
|
||||
options:
|
||||
description:
|
||||
description:
|
||||
- Filter the list result by the human-readable description of
|
||||
the resource.
|
||||
type: str
|
||||
direction:
|
||||
description:
|
||||
- Filter the security group rule list result by the direction in
|
||||
which the security group rule is applied.
|
||||
choices: ['egress', 'ingress']
|
||||
type: str
|
||||
ethertype:
|
||||
description:
|
||||
- Filter the security group rule list result by the ethertype of
|
||||
network traffic. The value must be IPv4 or IPv6.
|
||||
choices: ['IPv4', 'IPv6']
|
||||
type: str
|
||||
port_range_min:
|
||||
description:
|
||||
- Starting port
|
||||
type: int
|
||||
port_range_max:
|
||||
description:
|
||||
- Ending port
|
||||
type: int
|
||||
project:
|
||||
description:
|
||||
- Unique name or ID of the project.
|
||||
required: false
|
||||
type: str
|
||||
protocol:
|
||||
description:
|
||||
- Filter the security group rule list result by the IP protocol.
|
||||
type: str
|
||||
choices: ['any', 'tcp', 'udp', 'icmp', '112', '132']
|
||||
remote_group:
|
||||
description:
|
||||
- Filter the security group rule list result by the name or ID of the
|
||||
remote group that associates with this security group rule.
|
||||
type: str
|
||||
remote_ip_prefix:
|
||||
description:
|
||||
- Source IP address(es) in CIDR notation (exclusive with remote_group)
|
||||
type: str
|
||||
revision_number:
|
||||
description:
|
||||
- Filter the list result by the revision number of the resource.
|
||||
type: int
|
||||
rule:
|
||||
description:
|
||||
- Filter the list result by the ID of the security group rule.
|
||||
type: str
|
||||
security_group:
|
||||
description:
|
||||
- Name or ID of the security group
|
||||
type: str
|
||||
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
|
||||
extends_documentation_fragment:
|
||||
- openstack.cloud.openstack
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Get all security group rules
|
||||
- openstack.cloud.security_group_rule_info:
|
||||
cloud: "{{ cloud }}"
|
||||
register: sg
|
||||
|
||||
# Filter security group rules for port 80 and name
|
||||
- openstack.cloud.security_group_rule_info:
|
||||
cloud: "{{ cloud }}"
|
||||
security_group: "{{ rule_name }}"
|
||||
protocol: tcp
|
||||
port_range_min: 80
|
||||
port_range_max: 80
|
||||
remote_ip_prefix: 0.0.0.0/0
|
||||
|
||||
# Filter for ICMP rules
|
||||
- openstack.cloud.security_group_rule_info:
|
||||
cloud: "{{ cloud }}"
|
||||
protocol: icmp
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
security_group_rules:
|
||||
description: List of dictionaries describing security group rules.
|
||||
type: complex
|
||||
returned: On Success.
|
||||
contains:
|
||||
id:
|
||||
description: Unique rule UUID.
|
||||
type: str
|
||||
description:
|
||||
description: Human-readable description of the resource.
|
||||
type: str
|
||||
sample: 'My description.'
|
||||
direction:
|
||||
description: The direction in which the security group rule is applied.
|
||||
type: str
|
||||
sample: 'egress'
|
||||
ethertype:
|
||||
description: One of IPv4 or IPv6.
|
||||
type: str
|
||||
sample: 'IPv4'
|
||||
port_range_min:
|
||||
description: The minimum port number in the range that is matched by
|
||||
the security group rule.
|
||||
type: int
|
||||
sample: 8000
|
||||
port_range_max:
|
||||
description: The maximum port number in the range that is matched by
|
||||
the security group rule.
|
||||
type: int
|
||||
sample: 8000
|
||||
project:
|
||||
description:
|
||||
- Unique ID of the project.
|
||||
type: str
|
||||
sample: '16d53a84a13b49529d2e2c3646691123'
|
||||
protocol:
|
||||
description: The protocol that is matched by the security group rule.
|
||||
type: str
|
||||
sample: 'tcp'
|
||||
remote_ip_prefix:
|
||||
description: The remote IP prefix to be associated with this security group rule.
|
||||
type: str
|
||||
sample: '0.0.0.0/0'
|
||||
security_group_id:
|
||||
description: The security group ID to associate with this security group rule.
|
||||
type: str
|
||||
sample: '729b9660-a20a-41fe-bae6-ed8fa7f69123'
|
||||
'''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
|
||||
OpenStackModule)
|
||||
|
||||
|
||||
class SecurityGroupRuleInfoModule(OpenStackModule):
|
||||
argument_spec = dict(
|
||||
description=dict(required=False, type='str'),
|
||||
direction=dict(required=False,
|
||||
type='str',
|
||||
choices=['egress', 'ingress']),
|
||||
ethertype=dict(required=False,
|
||||
type='str',
|
||||
choices=['IPv4', 'IPv6']),
|
||||
port_range_min=dict(required=False, type='int', min_ver="0.32.0"),
|
||||
port_range_max=dict(required=False, type='int', min_ver="0.32.0"),
|
||||
project=dict(required=False, type='str'),
|
||||
protocol=dict(required=False,
|
||||
type='str',
|
||||
choices=['any', 'tcp', 'udp', 'icmp', '112', '132']),
|
||||
remote_group=dict(required=False, type='str'),
|
||||
remote_ip_prefix=dict(required=False, type='str', min_ver="0.32.0"),
|
||||
revision_number=dict(required=False, type='int'),
|
||||
rule=dict(required=False, type='str'),
|
||||
security_group=dict(required=False, type='str')
|
||||
)
|
||||
|
||||
module_kwargs = dict(
|
||||
mutually_exclusive=[
|
||||
['remote_ip_prefix', 'remote_group'],
|
||||
]
|
||||
)
|
||||
|
||||
def run(self):
|
||||
description = self.params['description']
|
||||
direction = self.params['direction']
|
||||
ethertype = self.params['ethertype']
|
||||
project = self.params['project']
|
||||
protocol = self.params['protocol']
|
||||
remote_group = self.params['remote_group']
|
||||
revision_number = self.params['revision_number']
|
||||
rule = self.params['rule']
|
||||
security_group = self.params['security_group']
|
||||
|
||||
changed = False
|
||||
filters = self.check_versioned(
|
||||
port_range_min=self.params['port_range_min'],
|
||||
port_range_max=self.params['port_range_max'],
|
||||
remote_ip_prefix=self.params['remote_ip_prefix']
|
||||
)
|
||||
data = []
|
||||
|
||||
if rule:
|
||||
sec_rule = self.conn.network.get_security_group_rule(rule)
|
||||
if sec_rule is None:
|
||||
self.exit(changed=changed, security_group_rules=[])
|
||||
self.exit(changed=changed,
|
||||
security_group_rules=sec_rule.to_dict())
|
||||
# query parameter id is currently not supported
|
||||
# PR is open for that.
|
||||
# filters['id] = sec_rule.id
|
||||
if description:
|
||||
filters['description'] = description
|
||||
if direction:
|
||||
filters['direction'] = direction
|
||||
if ethertype:
|
||||
filters['ethertype'] = ethertype
|
||||
if project:
|
||||
proj = self.conn.get_project(project)
|
||||
if proj is None:
|
||||
self.fail_json(msg='Project %s could not be found' % project)
|
||||
filters['project_id'] = proj.id
|
||||
if protocol:
|
||||
filters['protocol'] = protocol
|
||||
if remote_group:
|
||||
filters['remote_group_id'] = remote_group
|
||||
if revision_number:
|
||||
filters['revision_number'] = revision_number
|
||||
if security_group:
|
||||
sec_grp = self.conn.network.find_security_group(
|
||||
name_or_id=security_group,
|
||||
ignore_missing=True)
|
||||
if sec_grp is None:
|
||||
self.fail_json(msg='Security group %s could not be found' % sec_grp)
|
||||
filters['security_group_id'] = sec_grp.id
|
||||
|
||||
for item in self.conn.network.security_group_rules(**filters):
|
||||
item = item.to_dict()
|
||||
data.append(item)
|
||||
|
||||
self.exit_json(changed=changed,
|
||||
security_group_rules=data)
|
||||
|
||||
|
||||
def main():
|
||||
module = SecurityGroupRuleInfoModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -189,6 +189,10 @@ options:
|
||||
description:
|
||||
- Availability zone in which to create the server.
|
||||
type: str
|
||||
description:
|
||||
description:
|
||||
- Description of the server.
|
||||
type: str
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
@@ -505,6 +509,7 @@ class ServerModule(OpenStackModule):
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
delete_fip=dict(default=False, type='bool'),
|
||||
reuse_ips=dict(default=True, type='bool'),
|
||||
description=dict(default=None, type='str'),
|
||||
)
|
||||
module_kwargs = dict(
|
||||
mutually_exclusive=[
|
||||
@@ -608,7 +613,8 @@ class ServerModule(OpenStackModule):
|
||||
)
|
||||
for optional_param in (
|
||||
'key_name', 'availability_zone', 'network',
|
||||
'scheduler_hints', 'volume_size', 'volumes'):
|
||||
'scheduler_hints', 'volume_size', 'volumes',
|
||||
'description'):
|
||||
if self.params[optional_param]:
|
||||
bootkwargs[optional_param] = self.params[optional_param]
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ options:
|
||||
- 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]
|
||||
rebuild, shelve, shelve_offload, unshelve]
|
||||
type: str
|
||||
required: true
|
||||
image:
|
||||
@@ -70,18 +70,43 @@ EXAMPLES = '''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
|
||||
|
||||
# If I(action) is set to C(shelve) then according to OpenStack's Compute API, the shelved
|
||||
# server is in one of two possible states:
|
||||
#
|
||||
# SHELVED: The server is in shelved state. Depends on the shelve offload time,
|
||||
# the server will be automatically shelved off loaded.
|
||||
# SHELVED_OFFLOADED: The shelved server is offloaded (removed from the compute host) and
|
||||
# it needs unshelved action to be used again.
|
||||
#
|
||||
# But wait_for_server can only wait for a single server state. If a shelved server is offloaded
|
||||
# immediately, then a exceptions.ResourceTimeout will be raised if I(action) is set to C(shelve).
|
||||
# This is likely to happen because shelved_offload_time in Nova's config is set to 0 by default.
|
||||
# This also applies if you boot the server from volumes.
|
||||
#
|
||||
# Calling C(shelve_offload) instead of C(shelve) will also fail most likely because the default
|
||||
# policy does not allow C(shelve_offload) for non-admin users while C(shelve) is allowed for
|
||||
# admin users and server owners.
|
||||
#
|
||||
# As we cannot retrieve shelved_offload_time from Nova's config, we fall back to waiting for
|
||||
# one state and if that fails then we fetch the server's state and match it against the other
|
||||
# valid states from _action_map.
|
||||
#
|
||||
# Ref.: https://docs.openstack.org/api-guide/compute/server_concepts.html
|
||||
|
||||
_action_map = {'stop': 'SHUTOFF',
|
||||
'start': 'ACTIVE',
|
||||
'pause': 'PAUSED',
|
||||
'unpause': 'ACTIVE',
|
||||
'lock': 'ACTIVE', # API doesn't show lock/unlock status
|
||||
'unlock': 'ACTIVE',
|
||||
'suspend': 'SUSPENDED',
|
||||
'resume': 'ACTIVE',
|
||||
'rebuild': 'ACTIVE'}
|
||||
_action_map = {'stop': ['SHUTOFF'],
|
||||
'start': ['ACTIVE'],
|
||||
'pause': ['PAUSED'],
|
||||
'unpause': ['ACTIVE'],
|
||||
'lock': ['ACTIVE'], # API doesn't show lock/unlock status
|
||||
'unlock': ['ACTIVE'],
|
||||
'suspend': ['SUSPENDED'],
|
||||
'resume': ['ACTIVE'],
|
||||
'rebuild': ['ACTIVE'],
|
||||
'shelve': ['SHELVED_OFFLOADED', 'SHELVED'],
|
||||
'shelve_offload': ['SHELVED_OFFLOADED'],
|
||||
'unshelve': ['ACTIVE']}
|
||||
|
||||
_admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock']
|
||||
_admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock', 'shelve_offload']
|
||||
|
||||
|
||||
class ServerActionModule(OpenStackModule):
|
||||
@@ -92,9 +117,9 @@ class ServerActionModule(OpenStackModule):
|
||||
action=dict(required=True, type='str',
|
||||
choices=['stop', 'start', 'pause', 'unpause',
|
||||
'lock', 'unlock', 'suspend', 'resume',
|
||||
'rebuild']),
|
||||
'rebuild', 'shelve', 'shelve_offload', 'unshelve']),
|
||||
image=dict(required=False, type='str'),
|
||||
admin_password=dict(required=False, type='str'),
|
||||
admin_password=dict(required=False, type='str', no_log=True),
|
||||
)
|
||||
module_kwargs = dict(
|
||||
required_if=[('action', 'rebuild', ['image'])],
|
||||
@@ -128,6 +153,9 @@ class ServerActionModule(OpenStackModule):
|
||||
def _execute_server_action(self, os_server):
|
||||
if self.params['action'] == 'rebuild':
|
||||
return self._rebuild_server(os_server)
|
||||
if self.params['action'] == 'shelve_offload':
|
||||
# shelve_offload is not supported in OpenstackSDK
|
||||
return self._action(os_server, json={'shelveOffload': None})
|
||||
action_name = self.params['action'] + "_server"
|
||||
try:
|
||||
func_name = getattr(self.conn.compute, action_name)
|
||||
@@ -154,23 +182,38 @@ class ServerActionModule(OpenStackModule):
|
||||
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']}})
|
||||
self._action(os_server, json={'rebuild': {'imageRef': image['id']}})
|
||||
|
||||
def _action(self, os_server, json):
|
||||
response = self.conn.compute.post(
|
||||
'/servers/{server_id}/action'.format(server_id=os_server['id']),
|
||||
json=json)
|
||||
self.sdk.exceptions.raise_from_response(response)
|
||||
return response
|
||||
|
||||
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'])
|
||||
states = _action_map[self.params['action']]
|
||||
|
||||
try:
|
||||
self.conn.compute.wait_for_server(
|
||||
server,
|
||||
status=states[0],
|
||||
wait=self.params['timeout'])
|
||||
except self.sdk.exceptions.ResourceTimeout:
|
||||
# raise if there is only one valid state
|
||||
if len(states) < 2:
|
||||
raise
|
||||
# fetch current server status and compare to other valid states
|
||||
server = self.conn.compute.get_server(os_server['id'])
|
||||
if server.status not in states:
|
||||
raise
|
||||
|
||||
def __system_state_change(self, os_server):
|
||||
"""Check if system state would change."""
|
||||
return os_server.status != _action_map[self.params['action']]
|
||||
return os_server.status not in _action_map[self.params['action']]
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
109
plugins/modules/stack_info.py
Normal file
109
plugins/modules/stack_info.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/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: stack_info
|
||||
short_description: Retrive information about Heat stacks
|
||||
author: OpenStack Ansible SIG
|
||||
description:
|
||||
- Get information about Heat stack in openstack
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name of the stack as a string.
|
||||
type: str
|
||||
required: false
|
||||
status:
|
||||
description:
|
||||
- Value of the status of the stack so that you can filter on "available" for example
|
||||
type: str
|
||||
required: false
|
||||
project_id:
|
||||
description:
|
||||
- Project ID to be used as filter
|
||||
type: str
|
||||
required: false
|
||||
owner_id:
|
||||
description:
|
||||
- Owner (parent) of the stack to be used as a filter
|
||||
type: str
|
||||
required: false
|
||||
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "openstacksdk"
|
||||
|
||||
extends_documentation_fragment:
|
||||
- openstack.cloud.openstack
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
stacks:
|
||||
description: List of dictionaries describing stacks.
|
||||
type: list
|
||||
elements: dict
|
||||
returned: always.
|
||||
contains:
|
||||
id:
|
||||
description: Unique UUID.
|
||||
type: str
|
||||
sample: "39007a7e-ee4f-4d13-8283-b4da2e037c69"
|
||||
status:
|
||||
description: Stack status.
|
||||
type: str
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Get backups.
|
||||
- openstack.cloud.stack_info:
|
||||
register: stack
|
||||
|
||||
- openstack.cloud.stack_info:
|
||||
name: my_stack
|
||||
register: stack
|
||||
'''
|
||||
|
||||
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
|
||||
|
||||
|
||||
class StackInfoModule(OpenStackModule):
|
||||
module_min_sdk_version = '0.53.0'
|
||||
|
||||
argument_spec = dict(
|
||||
name=dict(required=False, type='str'),
|
||||
status=dict(required=False, type='str'),
|
||||
project_id=dict(required=False, type='str'),
|
||||
owner_id=dict(required=False, type='str')
|
||||
)
|
||||
|
||||
def run(self):
|
||||
data = []
|
||||
attrs = {}
|
||||
|
||||
for param in ['name', 'status', 'project_id', 'owner_id']:
|
||||
if self.params[param]:
|
||||
attrs[param] = self.params[param]
|
||||
|
||||
for raw in self.conn.orchestration.stacks(**attrs):
|
||||
dt = raw.to_dict()
|
||||
dt.pop('location')
|
||||
data.append(dt)
|
||||
|
||||
self.exit_json(
|
||||
changed=False,
|
||||
stacks=data
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = StackInfoModule()
|
||||
module()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -133,7 +133,7 @@ class VolumeInfoModule(OpenStackModule):
|
||||
status=self.params['status'],
|
||||
)
|
||||
result = self.conn.block_storage.volumes(**kwargs)
|
||||
result = list(result)
|
||||
result = [vol if isinstance(vol, dict) else vol.to_dict() for vol in result]
|
||||
self.results.update({'volumes': result})
|
||||
|
||||
|
||||
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
openstacksdk>=0.13
|
||||
@@ -1,11 +0,0 @@
|
||||
openstacksdk
|
||||
ansible-base
|
||||
pycodestyle
|
||||
flake8
|
||||
pylint
|
||||
voluptuous
|
||||
yamllint
|
||||
rstcheck
|
||||
ruamel.yaml
|
||||
#galaxy-importer # see https://review.opendev.org/#/c/743054
|
||||
tox
|
||||
@@ -1 +1 @@
|
||||
test-requirements-2.10.txt
|
||||
test-requirements-2.11.txt
|
||||
@@ -1,7 +0,0 @@
|
||||
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/port_info.py pylint:ansible-deprecated-no-collection-name
|
||||
plugins/modules/project_info.py pylint:ansible-deprecated-no-collection-name
|
||||
plugins/module_utils/openstack.py pylint:ansible-deprecated-no-collection-name
|
||||
@@ -1,7 +0,0 @@
|
||||
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/port_info.py pylint:ansible-deprecated-no-collection-name
|
||||
plugins/modules/project_info.py pylint:ansible-deprecated-no-collection-name
|
||||
plugins/module_utils/openstack.py pylint:ansible-deprecated-no-collection-name
|
||||
|
||||
0
tests/sanity/ignore-2.12.txt
Normal file
0
tests/sanity/ignore-2.12.txt
Normal file
Reference in New Issue
Block a user