Add 'all_projects' to server_action module

This allows to execute actions on servers outside of the current auth
scoped project if the user has permission to do so.

Change-Id: Ifb3f40973a76ad8c57bcbcbcb8e73c917681096b
This commit is contained in:
Gaudenz Steinlin 2022-02-24 17:47:49 +01:00 committed by Jakob Meng
parent a03dd05465
commit bf2c20f590
4 changed files with 124 additions and 14 deletions

@ -1,5 +1,8 @@
server_network: private server_network: private
server_name: ansible_server server_name: ansible_server
server_alt_network: private_alt
server_alt_subnet: subnet_alt
server_alt_name: ansible_server_alt
flavor: m1.tiny flavor: m1.tiny
floating_ip_pool_name: public floating_ip_pool_name: public
boot_volume_size: 5 boot_volume_size: 5

@ -518,3 +518,95 @@
that: that:
- info24.openstack_servers.0.status == 'ACTIVE' - info24.openstack_servers.0.status == 'ACTIVE'
- server is not changed - server is not changed
- name: Create network for alternate server
openstack.cloud.network:
cloud: "{{ cloud_alt }}"
name: "{{ server_alt_network }}"
state: present
- name: Create subnet for alternate server
openstack.cloud.subnet:
cloud: "{{ cloud_alt }}"
network_name: "{{ server_alt_network }}"
name: "{{ server_alt_subnet }}"
state: present
cidr: 192.168.0.0/24
- name: Create server in alternate project
openstack.cloud.server:
cloud: "{{ cloud_alt }}"
state: present
name: "{{ server_alt_name }}"
image: "{{ image }}"
flavor: "{{ flavor }}"
network: "{{ server_alt_network }}"
auto_floating_ip: false
wait: true
register: server_alt
- name: Get info about server in alternate project
openstack.cloud.server_info:
cloud: "{{ cloud_alt }}"
server: "{{ server_alt_name }}"
register: info25
- name: Ensure status for server in alternate project is ACTIVE
assert:
that:
- info25.openstack_servers.0.status == 'ACTIVE'
- name: Try to stop server in alternate project
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_alt_name }}"
action: stop
wait: true
ignore_errors: true
register: server_alt
- name: Ensure server was not stopped
assert:
that:
- server_alt is failed
- server_alt.msg == "Could not find server {{ server_alt_name }}"
- name: Stop server in alternate project with all_projects=true
openstack.cloud.server_action:
cloud: "{{ cloud }}"
server: "{{ server_alt_name }}"
action: stop
wait: true
all_projects: True
register: server_alt
- name: Get info about server in alternate project
openstack.cloud.server_info:
cloud: "{{ cloud_alt }}"
server: "{{ server_alt_name }}"
register: info26
- name: Ensure status for server is SHUTOFF
assert:
that:
- info26.openstack_servers.0.status == 'SHUTOFF'
- server_alt is changed
- name: Delete server in alternate project
openstack.cloud.server:
cloud: "{{ cloud_alt }}"
state: absent
name: "{{ server_alt_name }}"
wait: true
- name: Delete subnet for alternate server
openstack.cloud.subnet:
cloud: "{{ cloud_alt }}"
name: "{{ server_alt_subnet }}"
state: absent
- name: Delete network for alternate server
openstack.cloud.network:
cloud: "{{ cloud_alt }}"
name: "{{ server_alt_network }}"
state: absent

@ -6,20 +6,22 @@
# #
# tox -e ansible [TAG ...] # tox -e ansible [TAG ...]
# or # or
# tox -e ansible -- -c cloudX [TAG ...] # tox -e ansible -- -c cloudX -u cloudY [TAG ...]
# or to use the development version of Ansible: # or to use the development version of Ansible:
# tox -e ansible -- -d -c cloudX [TAG ...] # tox -e ansible -- -d -c cloudX -u cloudY [TAG ...]
# #
# USAGE: # USAGE:
# run-ansible-tests.sh -e ENVDIR [-d] [-c CLOUD] [TAG ...] # run-ansible-tests.sh -e ENVDIR [-d] [-c CLOUD] [-u CLOUD_ALT] [TAG ...]
# #
# PARAMETERS: # PARAMETERS:
# -d Use Ansible source repo development branch. # -d Use Ansible source repo development branch.
# -e ENVDIR Directory of the tox environment to use for testing. # -e ENVDIR Directory of the tox environment to use for testing.
# -c CLOUD Name of the cloud to use for testing. # -c CLOUD Name of the cloud to use for testing.
# Defaults to "devstack-admin". # Defaults to "devstack-admin".
# [TAG ...] Optional list of space-separated tags to control which # -u CLOUD_ALT Name of another cloud to use for testing.
# modules are tested. # Defaults to "devstack-alt".
# [TAG ...] Optional list of space-separated tags to control which
# modules are tested.
# #
# EXAMPLES: # EXAMPLES:
# # Run all Ansible tests # # Run all Ansible tests
@ -31,14 +33,16 @@
set -ex set -ex
CLOUD="devstack-admin" CLOUD="devstack-admin"
CLOUD_ALT="devstack-alt"
ENVDIR= ENVDIR=
USE_DEV=0 USE_DEV=0
while getopts "c:de:" opt while getopts "c:de:u:" opt
do do
case $opt in case $opt in
d) USE_DEV=1 ;; d) USE_DEV=1 ;;
c) CLOUD=${OPTARG} ;; c) CLOUD=${OPTARG} ;;
u) CLOUD_ALT=${OPTARG} ;;
e) ENVDIR=${OPTARG} ;; e) ENVDIR=${OPTARG} ;;
?) echo "Invalid option: -${OPTARG}" ?) echo "Invalid option: -${OPTARG}"
exit 1;; exit 1;;
@ -134,6 +138,6 @@ pushd ci/
set -o pipefail set -o pipefail
ANSIBLE_COLLECTIONS_PATHS=$TEST_COLLECTIONS_PATHS ansible-playbook \ ANSIBLE_COLLECTIONS_PATHS=$TEST_COLLECTIONS_PATHS ansible-playbook \
-vvv ./run-collection.yml \ -vvv ./run-collection.yml \
-e "sdk_version=${SDK_VER} cloud=${CLOUD} image=${IMAGE} ${ANSIBLE_VARS}" \ -e "sdk_version=${SDK_VER} cloud=${CLOUD} cloud_alt=${CLOUD_ALT} image=${IMAGE} ${ANSIBLE_VARS}" \
${tag_opt} 2>&1 | sudo tee /opt/stack/logs/test_output.log ${tag_opt} 2>&1 | sudo tee /opt/stack/logs/test_output.log
popd popd

@ -46,6 +46,12 @@ options:
description: description:
- Admin password for server to rebuild - Admin password for server to rebuild
type: str type: str
all_projects:
description:
- Whether to search for server in all projects or just the current
auth scoped project.
type: bool
default: 'no'
requirements: requirements:
- "python >= 3.6" - "python >= 3.6"
@ -120,6 +126,7 @@ class ServerActionModule(OpenStackModule):
'rebuild', 'shelve', 'shelve_offload', 'unshelve']), 'rebuild', 'shelve', 'shelve_offload', 'unshelve']),
image=dict(required=False, type='str'), image=dict(required=False, type='str'),
admin_password=dict(required=False, type='str', no_log=True), admin_password=dict(required=False, type='str', no_log=True),
all_projects=dict(required=False, type='bool', default=False),
) )
module_kwargs = dict( module_kwargs = dict(
required_if=[('action', 'rebuild', ['image'])], required_if=[('action', 'rebuild', ['image'])],
@ -137,7 +144,10 @@ class ServerActionModule(OpenStackModule):
def _preliminary_checks(self): def _preliminary_checks(self):
# Using Munch object for getting information about a server # Using Munch object for getting information about a server
os_server = self.conn.get_server(self.params['server']) os_server = self.conn.get_server(
self.params['server'],
all_projects=self.params['all_projects'],
)
if not os_server: if not os_server:
self.fail_json(msg='Could not find server %s' % self.params['server']) self.fail_json(msg='Could not find server %s' % self.params['server'])
# check mode # check mode
@ -193,8 +203,9 @@ class ServerActionModule(OpenStackModule):
def _wait(self, os_server): def _wait(self, os_server):
"""Wait for the server to reach the desired state for the given action.""" """Wait for the server to reach the desired state for the given action."""
# Using Server object for wait_for_server function # The wait_for_server function needs a Server object instead of the
server = self.conn.compute.find_server(self.params['server']) # Munch object returned by self.conn.get_server
server = self.conn.compute.get_server(os_server['id'])
states = _action_map[self.params['action']] states = _action_map[self.params['action']]
try: try: