11 Commits
1.5.3 ... 1.6.0

Author SHA1 Message Date
Sagi Shnaidman
f3b12fed68 Release 1.6.0 version
Change-Id: Ia93e0c9ad892cafabfa43de1578800c099cb5804
2022-01-13 14:46:19 +02:00
Zuul
39a627d4a0 Merge "Add Neutron RBAC modules" 2022-01-12 11:13:53 +00:00
hamza alqtaishat
4eb7c43539 Add compute services list module
The module retrieve the nova compute services info
filters by
 * host
 * binary ( nova-compute, nova-conductor, ... )

Closes-Bug: 2009775
Change-Id: I0f9cac27a7a91727ba1d005e04431e8f83c46fa8
2022-01-11 17:14:54 +00:00
Ashraf Hasson
8c6d1041fa Add Neutron RBAC modules
Change-Id: Ibaff06561055c5cd024abb789dae075dd7871f08
2022-01-11 11:59:58 -05:00
Zuul
26530ac97b Merge "Leave queens job only in experimental" 2021-12-18 23:25:14 +00:00
Zuul
b3e07a1864 Merge "quota: Adds metadata_items parameter" 2021-12-18 23:18:44 +00:00
Sagi Shnaidman
94933250e8 Leave queens job only in experimental
Change-Id: Ibc77dfe72e972948c0b4b018c8f4b18dc7dec790
2021-12-18 22:23:24 +02:00
Pierre Riteau
1582956dcd Remove failing job from gate
Change-Id: I7920e99efd152c2f5a9839bdcbe96a14d6587688
2021-12-17 23:40:05 +01:00
Sagi Shnaidman
b1952e0c4b Replace victoria job by xena one
Move victoria job to experimental, add xena job to check/gate.
Change-Id: Ia0376bf253b9f0ce2f13222982e7e9b8582a93d6
2021-12-16 22:08:44 +02:00
Sagi Shnaidman
9cd6d2f69a Move queens job to experimental
Change-Id: I2df552e6fa98e642b9ccce891d730bb96dedb9a8
2021-12-16 21:56:30 +02:00
Will Szumski
86a57498e8 quota: Adds metadata_items parameter
This is used to set the maximum number of metadata items per instance.

Change-Id: Ib5b86126ec25e9e84436d7ee7f79e43e22637272
2021-12-16 18:59:40 +00:00
12 changed files with 831 additions and 8 deletions

View File

@@ -128,6 +128,23 @@
tox_envlist: ansible-2.12
# Stable branches tests
- job:
name: ansible-collections-openstack-functional-devstack-xena-ansible-2.12
parent: ansible-collections-openstack-functional-devstack-ansible-devel
description: |
Run openstack collections functional tests against a xena devstack
using xena brach of openstacksdk and stable 2.12 branch of ansible
voting: true
override-checkout: stable/xena
required-projects:
- name: github.com/ansible/ansible
override-checkout: stable-2.12
- name: openstack/openstacksdk
override-checkout: stable/xena
vars:
tox_envlist: ansible
- job:
name: ansible-collections-openstack-functional-devstack-wallaby-ansible-2.12
parent: ansible-collections-openstack-functional-devstack-ansible-devel
@@ -345,15 +362,12 @@
dependencies: *deps_unit_lint
- ansible-collections-openstack-functional-devstack-ansible-devel:
dependencies: *deps_unit_lint
- ansible-collections-openstack-functional-devstack-wallaby-ansible-2.12:
- ansible-collections-openstack-functional-devstack-xena-ansible-2.12:
dependencies: *deps_unit_lint
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.12:
- ansible-collections-openstack-functional-devstack-wallaby-ansible-2.12:
dependencies: *deps_unit_lint
- ansible-collections-openstack-functional-devstack-train-ansible-2.11:
dependencies: *deps_unit_lint
- ansible-collections-openstack-functional-devstack-queens-ansible-2.11:
dependencies: *deps_unit_lint
voting: false
- ansible-collections-openstack-functional-devstack-octavia:
dependencies: *deps_unit_lint
@@ -383,9 +397,8 @@
- ansible-collections-openstack-functional-devstack-ansible-2.9
- ansible-collections-openstack-functional-devstack-ansible-2.12
- ansible-collections-openstack-functional-devstack-wallaby-ansible-2.12
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.12
- ansible-collections-openstack-functional-devstack-xena-ansible-2.12
- ansible-collections-openstack-functional-devstack-train-ansible-2.11
- ansible-collections-openstack-functional-devstack-queens-ansible-2.11
- ansible-collections-openstack-functional-devstack-octavia
- tripleo-ci-centos-8-standalone-osa
@@ -399,6 +412,7 @@
- ansible-collections-openstack-functional-devstack-ansible-2.9
- ansible-collections-openstack-functional-devstack-ansible-2.12
- ansible-collections-openstack-functional-devstack-ansible-devel
- ansible-collections-openstack-functional-devstack-xena-ansible-2.12
- ansible-collections-openstack-functional-devstack-wallaby-ansible-2.12
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.12
- ansible-collections-openstack-functional-devstack-train-ansible-2.11
@@ -410,7 +424,9 @@
experimental:
jobs:
- ansible-collections-openstack-functional-devstack-ansible-2.11
- ansible-collections-openstack-functional-devstack-victoria-ansible-2.12
- ansible-collections-openstack-functional-devstack-ussuri-ansible-2.11
- ansible-collections-openstack-functional-devstack-queens-ansible-2.11
tag:
jobs:

View File

@@ -5,6 +5,26 @@ Openstack Cloud Ansilbe modules Release Notes
.. contents:: Topics
v1.6.0
======
Release Summary
---------------
New modules for RBAC and Nova services
Minor Changes
-------------
- quota - Adds metadata_items parameter
New Modules
-----------
- openstack.cloud.compute_service_info - Retrieve information about one or more OpenStack compute services
- openstack.cloud.neutron_rbac_policies_info - Fetch Neutron policies.
- openstack.cloud.neutron_rbac_policy - Create or delete a Neutron policy to apply a RBAC rule against an object.
v1.5.3
======

View File

@@ -266,3 +266,20 @@ releases:
- server_volume - check specified server is found
release_summary: Bugfixes
release_date: '2021-11-11'
1.6.0:
changes:
minor_changes:
- quota - Adds metadata_items parameter
release_summary: New modules for RBAC and Nova services
modules:
- description: Retrieve information about one or more OpenStack compute services
name: compute_service_info
namespace: ''
- description: Fetch Neutron policies.
name: neutron_rbac_policies_info
namespace: ''
- description: Create or delete a Neutron policy to apply a RBAC rule against
an object.
name: neutron_rbac_policy
namespace: ''
release_date: '2022-01-13'

View File

@@ -0,0 +1,85 @@
---
# General run of tests
# - Prepare projects/network objects
# - Create rbac object
# - Get rbac object info
# - Verify RBAC object match
# - Delete rbac object
# - Get rbac object info
# - Verify RBAC object deleted
- name: Create source project
openstack.cloud.project:
cloud: "{{ cloud }}"
state: present
name: source_project
description: Source project for network RBAC test
domain_id: default
enabled: True
register: source_project
- name: Create network - generic
openstack.cloud.network:
cloud: "{{ cloud }}"
name: "{{ network_name }}"
state: present
project: "{{ source_project.project.id }}"
shared: false
external: "{{ network_external }}"
register: network
- name: Create target project
openstack.cloud.project:
cloud: "{{ cloud }}"
state: present
name: ansible_project
description: Target project for network RBAC test
domain_id: default
enabled: True
register: target_project
- name: Create a new network RBAC policy
openstack.cloud.neutron_rbac_policy:
cloud: "{{ cloud }}"
object_id: "{{ network.network.id }}"
object_type: 'network'
action: 'access_as_shared'
target_project_id: "{{ target_project.project.id }}"
project_id: "{{ source_project.project.id }}"
register: rbac_policy
- name: Get all rbac policies for {{ source_project.project.name }} - after creation
openstack.cloud.neutron_rbac_policies_info:
cloud: "{{ cloud }}"
project_id: "{{ source_project.project.id }}"
register: rbac_policies
- name: Capture all existing policy IDs
set_fact:
rbac_policy_ids: "{{ rbac_policies.policies | map(attribute='id') | list }}"
- name: Verify policy exists - after creation
assert:
that:
- rbac_policy.policy.id in rbac_policy_ids
- name: Delete RBAC policy
openstack.cloud.neutron_rbac_policy:
cloud: "{{ cloud }}"
policy_id: "{{ rbac_policy.policy.id }}"
state: absent
- name: Get all rbac policies for {{ source_project.project.name }} - after deletion
openstack.cloud.neutron_rbac_policies_info:
cloud: "{{ cloud }}"
project_id: "{{ source_project.project.id }}"
register: rbac_policies_remaining
- name: Capture all remaining policy IDs
set_fact:
remaining_rbac_policy_ids: "{{ rbac_policies_remaining.policies | map(attribute='id') | list }}"
- name: Verify policy does not exist - after deletion
assert:
that:
- not rbac_policy.policy.id in remaining_rbac_policy_ids

View File

@@ -0,0 +1,15 @@
---
- name: Get nova compute services info
openstack.cloud.compute_service_info:
cloud: "{{ cloud }}"
binary: "nova-compute"
register: result
failed_when: "result.openstack_compute_services | length <= 0"
- name: Get nova conductor services info
openstack.cloud.compute_service_info:
cloud: "{{ cloud }}"
binary: "nova-conductor"
register: result
failed_when: "result.openstack_compute_services | length <= 0"

View File

@@ -30,7 +30,14 @@
when: sdk_version is version(0.44, '>=')
- { role: keystone_role, tags: keystone_role }
- { role: network, tags: network }
- role: neutron_rbac
tags:
- rbac
- neutron_rbac
- { role: nova_flavor, tags: nova_flavor }
- role: nova_services
tags: nova_services
when: sdk_version is version(0.44, '>=')
- { role: object, tags: object }
- { role: port, tags: port }
- { role: project, tags: project }

View File

@@ -33,4 +33,4 @@ build_ignore:
- ansible_collections_openstack.egg-info
- contrib
- changelogs
version: 1.5.3
version: 1.6.0

View File

@@ -19,6 +19,8 @@ action_groups:
- compute_flavor
- compute_flavor_info
- compute_flavor_info
- compute_service_info
- compute_service_info
- config
- config
- dns_zone

View File

@@ -0,0 +1,111 @@
#!/usr/bin/python
# Copyright (c) 2016 Hewlett-Packard Enterprise Corporation
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = '''
---
module: compute_service_info
short_description: Retrieve information about one or more OpenStack compute services
author: OpenStack Ansible SIG
description:
- Retrieve information about nova compute services
options:
binary:
description:
- Filter by service binary type
type: str
host:
description:
- Filter by service host
type: str
requirements:
- "python >= 3.6"
- "openstacksdk"
extends_documentation_fragment:
- openstack.cloud.openstack
'''
EXAMPLES = '''
# Gather information about compute services
- openstack.cloud.compute_service_info:
cloud: awesomecloud
binary: "nova-compute"
host: "localhost"
register: result
- openstack.cloud.compute_service_info:
cloud: awesomecloud
register: result
- debug:
msg: "{{ result.openstack_compute_services }}"
'''
RETURN = '''
openstack_compute_services:
description: has all the OpenStack information about compute services
returned: always, but can be null
type: complex
contains:
id:
description: Unique UUID.
returned: success
type: str
binary:
description: The binary name of the service.
returned: success
type: str
host:
description: The name of the host.
returned: success
type: str
zone:
description: The availability zone name.
returned: success
type: str
status:
description: The status of the service. One of enabled or disabled.
returned: success
type: str
state:
description: The state of the service. One of up or down.
returned: success
type: str
update:
description: The date and time when the resource was updated
returned: success
type: str
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class ComputeServiceInfoModule(OpenStackModule):
argument_spec = dict(
binary=dict(required=False, default=None),
host=dict(required=False, default=None),
)
module_kwargs = dict(
supports_check_mode=True
)
def run(self):
binary = self.params['binary']
host = self.params['host']
filters = {}
if binary:
filters['binary'] = binary
if host:
filters['host'] = host
services = self.conn.compute.services(**filters)
services = list(services)
self.exit_json(changed=False, openstack_compute_services=services)
def main():
module = ComputeServiceInfoModule()
module()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,237 @@
#!/usr/bin/python
# coding: utf-8 -*-
# Copyright: Ansible Project
# (c) 2021, Ashraf Hasson <ahasson@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: neutron_rbac_policies_info
short_description: Fetch Neutron policies.
author: OpenStack Ansible SIG
description:
- Get RBAC policies against a network, security group or a QoS Policy for one or more projects.
- If a C(policy_id) was not provided, this module will attempt to fetch all available policies.
- Accepts same arguments as OpenStackSDK network proxy C(find_rbac_policy) and C(rbac_policies) functions which are ultimately passed over to C(RBACPolicy)
- All parameters passed in to this module act as a filter for when no C(policy_id) was provided, otherwise they're ignored.
- Returns None if no matching policy was found as opposed to failing.
options:
policy_id:
description:
- The RBAC policy ID
- If provided, all other filters are ignored
type: str
object_id:
description:
- The object ID (the subject of the policy) to which the RBAC rules applies
- This would be the ID of a network, security group or a qos policy
- Mutually exclusive with the C(object_type)
type: str
object_type:
description:
- Can be one of the following object types C(network), C(security_group) or C(qos_policy)
- Mutually exclusive with the C(object_id)
choices: ['network', 'security_group', 'qos_policy']
type: str
target_project_id:
description:
- Filters the RBAC rules based on the target project id
- Logically AND'ed with other filters
- Mutually exclusive with C(project_id)
type: str
project_id:
description:
- Filters the RBAC rules based on the project id to which the object belongs to
- Logically AND'ed with other filters
- Mutually exclusive with C(target_project_id)
type: str
project:
description:
- Filters the RBAC rules based on the project name
- Logically AND'ed with other filters
type: str
action:
description:
- Can be either of the following options C(access_as_shared) | C(access_as_external)
- Logically AND'ed with other filters
choices: ['access_as_shared', 'access_as_external']
type: str
extends_documentation_fragment:
- openstack.cloud.openstack
'''
EXAMPLES = r'''
# Gather all rbac policies for a project
- name: Get all rbac policies for {{ project }}
openstack.cloud.neutron_rbac_policies_info:
project_id: "{{ project.id }}"
'''
RETURN = r'''
# return value can either be plural or signular depending on what was passed in as parameters
policies:
description:
- List of rbac policies, this could also be returned as a singular element, i.e., 'policy'
type: complex
returned: always
contains:
object_id:
description:
- The UUID of the object to which the RBAC rules apply
type: str
sample: "7422172b-2961-475c-ac68-bd0f2a9960ad"
target_project_id:
description:
- The UUID of the target project
type: str
sample: "c201a689c016435c8037977166f77368"
project_id:
description:
- The UUID of the project to which access is granted
type: str
sample: "84b8774d595b41e89f3dfaa1fd76932c"
object_type:
description:
- The object type to which the RBACs apply
type: str
sample: "network"
action:
description:
- The access model specified by the RBAC rules
type: str
sample: "access_as_shared"
id:
description:
- The ID of the RBAC rule/policy
type: str
sample: "4154ce0c-71a7-4d87-a905-09762098ddb9"
name:
description:
- The name of the RBAC rule; usually null
type: str
sample: null
location:
description:
- A dictionary of the project details to which access is granted
type: dict
sample: >-
{
"cloud": "devstack",
"region_name": "",
"zone": null,
"project": {
"id": "84b8774d595b41e89f3dfaa1fd76932c",
"name": null,
"domain_id": null,
"domain_name": null
}
}
'''
import re
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class NeutronRbacPoliciesInfo(OpenStackModule):
argument_spec = dict(
policy_id=dict(),
object_id=dict(), # ID of the object that this RBAC policy affects.
object_type=dict(choices=['security_group', 'qos_policy', 'network']), # Type of the object that this RBAC policy affects.
target_project_id=dict(), # The ID of the project this RBAC will be enforced.
project_id=dict(), # The owner project ID.
project=dict(),
action=dict(choices=['access_as_external', 'access_as_shared']), # Action for the RBAC policy.
)
module_kwargs = dict(
supports_check_mode=True,
)
def _filter_policies_by(self, policies, key, value):
filtered = []
regexp = re.compile(r"location\.project\.([A-Za-z]+)")
if regexp.match(key):
attribute = key.split('.')[-1]
for p in policies:
if p['location']['project'][attribute] == value:
filtered.append(p)
else:
for p in policies:
if getattr(p, key) == value:
filtered.append(p)
return filtered
def _get_rbac_policies(self):
object_type = self.params.get('object_type')
project_id = self.params.get('project_id')
action = self.params.get('action')
search_attributes = {}
if object_type is not None:
search_attributes['object_type'] = object_type
if project_id is not None:
search_attributes['project_id'] = project_id
if action is not None:
search_attributes['action'] = action
try:
policies = []
generator = self.conn.network.rbac_policies(**search_attributes)
for p in generator:
policies.append(p)
except self.sdk.exceptions.OpenStackCloudException as ex:
self.fail_json(msg='Failed to get RBAC policies: {0}'.format(str(ex)))
return policies
def run(self):
policy_id = self.params.get('policy_id')
object_id = self.params.get('object_id')
object_type = self.params.get('object_type')
project_id = self.params.get('project_id')
project = self.params.get('project')
target_project_id = self.params.get('target_project_id')
if self.ansible.check_mode:
self.exit_json(changed=False)
if policy_id is not None:
try:
policy = self.conn.network.get_rbac_policy(policy_id)
self.exit_json(changed=False, policy=policy)
except self.sdk.exceptions.ResourceNotFound:
self.exit_json(changed=False, policy=None)
except self.sdk.exceptions.OpenStackCloudException as ex:
self.fail_json(msg='Failed to get RBAC policy: {0}'.format(str(ex)))
else:
if object_id is not None and object_type is not None:
self.fail_json(msg='object_id and object_type are mutually exclusive, please specify one of the two.')
if project_id is not None and target_project_id is not None:
self.fail_json(msg='project_id and target_project_id are mutually exclusive, please specify one of the two.')
filtered_policies = self._get_rbac_policies()
if project is not None:
filtered_policies = self._filter_policies_by(filtered_policies, 'location.project.name', project)
if object_id is not None:
filtered_policies = self._filter_policies_by(filtered_policies, 'object_id', object_id)
if target_project_id is not None:
filtered_policies = self._filter_policies_by(filtered_policies, 'target_project_id', target_project_id)
self.exit_json(policies=filtered_policies, changed=False)
def main():
module = NeutronRbacPoliciesInfo()
module()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,308 @@
#!/usr/bin/python
# Copyright: Ansible Project
# (c) 2021, Ashraf Hasson <ahasson@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = r'''
---
module: neutron_rbac_policy
short_description: Create or delete a Neutron policy to apply a RBAC rule against an object.
author: OpenStack Ansible SIG
description:
- Create a policy to apply a RBAC rule against a network, security group or a QoS Policy or update/delete an existing policy.
- If a C(policy_id) was provided but not found, this module will attempt to create a new policy rather than error out when updating an existing rule.
- Accepts same arguments as OpenStackSDK network proxy C(find_rbac_policy) and C(rbac_policies) functions which are ultimately passed over to C(RBACPolicy)
options:
policy_id:
description:
- The RBAC policy ID
- Required when deleting or updating an existing RBAC policy rule, ignored otherwise
type: str
object_id:
description:
- The object ID (the subject of the policy) to which the RBAC rule applies
- Cannot be changed when updating an existing policy
- Required when creating a RBAC policy rule, ignored when deleting a policy
type: str
object_type:
description:
- Can be one of the following object types C(network), C(security_group) or C(qos_policy)
- Cannot be changed when updating an existing policy
- Required when creating a RBAC policy rule, ignored when deleting a policy
choices: ['network', 'security_group', 'qos_policy']
type: str
target_project_id:
description:
- The project to which access to be allowed or revoked/disallowed
- Can be specified/changed when updating an existing policy
- Required when creating or updating a RBAC policy rule, ignored when deleting a policy
type: str
project_id:
description:
- The project to which the object_id belongs
- Cannot be changed when updating an existing policy
- Required when creating a RBAC policy rule, ignored when deleting a policy
type: str
action:
description:
- Can be either of the following options C(access_as_shared) | C(access_as_external)
- Cannot be changed when updating an existing policy
- Required when creating a RBAC policy rule, ignored when deleting a policy
choices: ['access_as_shared', 'access_as_external']
type: str
state:
description:
- Whether the RBAC rule should be C(present) or C(absent).
choices: ['present', 'absent']
default: present
type: str
extends_documentation_fragment:
- openstack.cloud.openstack
'''
EXAMPLES = r'''
# Ensure network RBAC policy exists
- name: Create a new network RBAC policy
neutron_rbac_policy:
object_id: '7422172b-2961-475c-ac68-bd0f2a9960ad'
object_type: 'network'
target_project_id: 'a12f9ce1de0645e0a0b01c2e679f69ec'
project_id: '84b8774d595b41e89f3dfaa1fd76932d'
# Update network RBAC policy
- name: Update an existing network RBAC policy
neutron_rbac_policy:
policy_id: 'f625242a-6a73-47ac-8d1f-91440b2c617f'
target_project_id: '163c89e065a94e069064e551e15daf0e'
# Delete an existing RBAC policy
- name: Delete RBAC policy
openstack.cloud.openstack.neutron_rbac_policy:
policy_id: 'f625242a-6a73-47ac-8d1f-91440b2c617f'
state: absent
'''
RETURN = r'''
policy:
description:
- A hash representing the policy
type: complex
returned: always
contains:
object_id:
description:
- The UUID of the object to which the RBAC rules apply
type: str
sample: "7422172b-2961-475c-ac68-bd0f2a9960ad"
target_project_id:
description:
- The UUID of the target project
type: str
sample: "c201a689c016435c8037977166f77368"
project_id:
description:
- The UUID of the project to which access is granted
type: str
sample: "84b8774d595b41e89f3dfaa1fd76932c"
object_type:
description:
- The object type to which the RBACs apply
type: str
sample: "network"
action:
description:
- The access model specified by the RBAC rules
type: str
sample: "access_as_shared"
id:
description:
- The ID of the RBAC rule/policy
type: str
sample: "4154ce0c-71a7-4d87-a905-09762098ddb9"
name:
description:
- The name of the RBAC rule; usually null
type: str
sample: null
location:
description:
- A dictionary of the project details to which access is granted
type: dict
sample: >-
{
"cloud": "devstack",
"region_name": "",
"zone": null,
"project": {
"id": "84b8774d595b41e89f3dfaa1fd76932c",
"name": null,
"domain_id": null,
"domain_name": null
}
}
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class NeutronRbacPolicy(OpenStackModule):
argument_spec = dict(
policy_id=dict(),
object_id=dict(), # ID of the object that this RBAC policy affects.
object_type=dict(choices=['security_group', 'qos_policy', 'network']), # Type of the object that this RBAC policy affects.
target_project_id=dict(), # The ID of the project this RBAC will be enforced.
project_id=dict(), # The owner project ID.
action=dict(choices=['access_as_external', 'access_as_shared']), # Action for the RBAC policy.
state=dict(default='present', choices=['absent', 'present'])
)
module_kwargs = dict(
supports_check_mode=True,
)
def _delete_rbac_policy(self, policy):
"""
Delete an existing RBAC policy
returns: the "Changed" state
"""
if policy is None:
self.fail_json(msg='Must specify policy_id for delete')
try:
self.conn.network.delete_rbac_policy(policy.id)
except self.sdk.exceptions.OpenStackCloudException as ex:
self.fail_json(msg='Failed to delete RBAC policy: {0}'.format(str(ex)))
return True
def _create_rbac_policy(self):
"""
Creates a new RBAC policy
returns: the "Changed" state of the RBAC policy
"""
object_id = self.params.get('object_id')
object_type = self.params.get('object_type')
target_project_id = self.params.get('target_project_id')
project_id = self.params.get('project_id')
action = self.params.get('action')
attributes = {
'object_id': object_id,
'object_type': object_type,
'target_project_id': target_project_id,
'project_id': project_id,
'action': action
}
if not all(attributes.values()):
self.fail_json(msg='Missing one or more required parameter for creating a RBAC policy')
try:
search_attributes = dict(attributes)
del search_attributes['object_id']
del search_attributes['target_project_id']
policies = self.conn.network.rbac_policies(**search_attributes)
for p in policies:
if p.object_id == object_id and p.target_project_id == target_project_id:
return (False, p)
# if no matching policy exists, attempt to create one
policy = self.conn.network.create_rbac_policy(**attributes)
except self.sdk.exceptions.OpenStackCloudException as ex:
self.fail_json(msg='Failed to create RBAC policy: {0}'.format(str(ex)))
return (True, policy)
def _update_rbac_policy(self, policy):
"""
Updates an existing RBAC policy
returns: the "Changed" state of the RBAC policy
"""
object_id = self.params.get('object_id')
object_type = self.params.get('object_type')
target_project_id = self.params.get('target_project_id')
project_id = self.params.get('project_id')
action = self.params.get('action')
allowed_attributes = {
'rbac_policy': policy.id,
'target_project_id': target_project_id
}
disallowed_attributes = {
'object_id': object_id,
'object_type': object_type,
'project_id': project_id,
'action': action
}
if not all(allowed_attributes.values()):
self.fail_json(msg='Missing one or more required parameter for updating a RBAC policy')
if any(disallowed_attributes.values()):
self.fail_json(msg='Cannot change disallowed parameters while updating a RBAC policy: ["object_id", "object_type", "project_id", "action"]')
try:
policy = self.conn.network.update_rbac_policy(**allowed_attributes)
except self.sdk.exceptions.OpenStackCloudException as ex:
self.fail_json(msg='Failed to update the RBAC policy: {0}'.format(str(ex)))
return (True, policy)
def _policy_state_change(self, policy):
state = self.params['state']
if state == 'present':
if not policy:
return True
if state == 'absent' and policy:
return True
return False
def run(self):
policy_id = self.params.get('policy_id')
state = self.params.get('state')
if policy_id is not None:
try:
policy = self.conn.network.get_rbac_policy(policy_id)
except self.sdk.exceptions.ResourceNotFound:
policy = None
except self.sdk.exceptions.OpenStackCloudException as ex:
self.fail_json(msg='Failed to get RBAC policy: {0}'.format(str(ex)))
else:
policy = None
if self.ansible.check_mode:
self.exit_json(changed=self._policy_state_change(policy), policy=policy)
if state == 'absent':
if policy is None and policy_id:
self.exit_json(changed=False)
if policy_id is None:
self.fail_json(msg='Must specify policy_id when state is absent')
if policy is not None:
changed = self._delete_rbac_policy(policy)
self.exit_json(changed=changed)
# state == 'present'
else:
if policy is None:
(changed, new_policy) = self._create_rbac_policy()
else:
(changed, new_policy) = self._update_rbac_policy(policy)
self.exit_json(changed=changed, policy=new_policy)
def main():
module = NeutronRbacPolicy()
module()
if __name__ == '__main__':
main()

View File

@@ -69,6 +69,9 @@ options:
loadbalancer:
description: Number of load balancers to allow.
type: int
metadata_items:
description: Number of metadata items allowed per instance.
type: int
network:
description: Number of networks to allow.
type: int
@@ -183,6 +186,7 @@ EXAMPLES = '''
instances: "{{ item.instances }}"
key_pairs: "{{ item.key_pairs }}"
loadbalancer: "{{ item.loadbalancer }}"
metadata_items: "{{ item.metadata_items }}"
per_volume_gigabytes: "{{ item.per_volume_gigabytes }}"
pool: "{{ item.pool }}"
port: "{{ item.port }}"
@@ -277,6 +281,7 @@ class QuotaModule(OpenStackModule):
instances=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),
metadata_items=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),
pool=dict(required=False, type='int', default=None),