mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 21:00:22 -07:00
Relocating extras into lib/ansible/modules/ after merge
This commit is contained in:
parent
c65ba07d2c
commit
011ea55a8f
596 changed files with 0 additions and 266 deletions
249
lib/ansible/modules/cloud/openstack/os_flavor_facts.py
Normal file
249
lib/ansible/modules/cloud/openstack/os_flavor_facts.py
Normal file
|
@ -0,0 +1,249 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2015 IBM
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import re
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_flavor_facts
|
||||
short_description: Retrieve facts about one or more flavors
|
||||
author: "David Shrewsbury (@Shrews)"
|
||||
version_added: "2.1"
|
||||
description:
|
||||
- Retrieve facts about available OpenStack instance flavors. By default,
|
||||
facts about ALL flavors are retrieved. Filters can be applied to get
|
||||
facts for only matching flavors. For example, you can filter on the
|
||||
amount of RAM available to the flavor, or the number of virtual CPUs
|
||||
available to the flavor, or both. When specifying multiple filters,
|
||||
*ALL* filters must match on a flavor before that flavor is returned as
|
||||
a fact.
|
||||
notes:
|
||||
- This module creates a new top-level C(openstack_flavors) fact, which
|
||||
contains a list of unsorted flavors.
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- A flavor name. Cannot be used with I(ram) or I(vcpus) or I(ephemeral).
|
||||
required: false
|
||||
default: None
|
||||
ram:
|
||||
description:
|
||||
- "A string used for filtering flavors based on the amount of RAM
|
||||
(in MB) desired. This string accepts the following special values:
|
||||
'MIN' (return flavors with the minimum amount of RAM), and 'MAX'
|
||||
(return flavors with the maximum amount of RAM)."
|
||||
|
||||
- "A specific amount of RAM may also be specified. Any flavors with this
|
||||
exact amount of RAM will be returned."
|
||||
|
||||
- "A range of acceptable RAM may be given using a special syntax. Simply
|
||||
prefix the amount of RAM with one of these acceptable range values:
|
||||
'<', '>', '<=', '>='. These values represent less than, greater than,
|
||||
less than or equal to, and greater than or equal to, respectively."
|
||||
required: false
|
||||
default: false
|
||||
vcpus:
|
||||
description:
|
||||
- A string used for filtering flavors based on the number of virtual
|
||||
CPUs desired. Format is the same as the I(ram) parameter.
|
||||
required: false
|
||||
default: false
|
||||
limit:
|
||||
description:
|
||||
- Limits the number of flavors returned. All matching flavors are
|
||||
returned by default.
|
||||
required: false
|
||||
default: None
|
||||
ephemeral:
|
||||
description:
|
||||
- A string used for filtering flavors based on the amount of ephemeral
|
||||
storage. Format is the same as the I(ram) parameter
|
||||
required: false
|
||||
default: false
|
||||
version_added: "2.3"
|
||||
extends_documentation_fragment: openstack
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Gather facts about all available flavors
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
|
||||
# Gather facts for the flavor named "xlarge-flavor"
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
name: "xlarge-flavor"
|
||||
|
||||
# Get all flavors that have exactly 512 MB of RAM.
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
ram: "512"
|
||||
|
||||
# Get all flavors that have 1024 MB or more of RAM.
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
ram: ">=1024"
|
||||
|
||||
# Get a single flavor that has the minimum amount of RAM. Using the 'limit'
|
||||
# option will guarantee only a single flavor is returned.
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
ram: "MIN"
|
||||
limit: 1
|
||||
|
||||
# Get all flavors with 1024 MB of RAM or more, AND exactly 2 virtual CPUs.
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
ram: ">=1024"
|
||||
vcpus: "2"
|
||||
|
||||
# Get all flavors with 1024 MB of RAM or more, exactly 2 virtual CPUs, and
|
||||
# less than 30gb of ephemeral storage.
|
||||
- os_flavor_facts:
|
||||
cloud: mycloud
|
||||
ram: ">=1024"
|
||||
vcpus: "2"
|
||||
ephemeral: "<30"
|
||||
'''
|
||||
|
||||
|
||||
RETURN = '''
|
||||
openstack_flavors:
|
||||
description: Dictionary describing the flavors.
|
||||
returned: On success.
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Flavor ID.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "515256b8-7027-4d73-aa54-4e30a4a4a339"
|
||||
name:
|
||||
description: Flavor name.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "tiny"
|
||||
disk:
|
||||
description: Size of local disk, in GB.
|
||||
returned: success
|
||||
type: int
|
||||
sample: 10
|
||||
ephemeral:
|
||||
description: Ephemeral space size, in GB.
|
||||
returned: success
|
||||
type: int
|
||||
sample: 10
|
||||
ram:
|
||||
description: Amount of memory, in MB.
|
||||
returned: success
|
||||
type: int
|
||||
sample: 1024
|
||||
swap:
|
||||
description: Swap space size, in MB.
|
||||
returned: success
|
||||
type: int
|
||||
sample: 100
|
||||
vcpus:
|
||||
description: Number of virtual CPUs.
|
||||
returned: success
|
||||
type: int
|
||||
sample: 2
|
||||
is_public:
|
||||
description: Make flavor accessible to the public.
|
||||
returned: success
|
||||
type: bool
|
||||
sample: true
|
||||
'''
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=False, default=None),
|
||||
ram=dict(required=False, default=None),
|
||||
vcpus=dict(required=False, default=None),
|
||||
limit=dict(required=False, default=None, type='int'),
|
||||
ephemeral=dict(required=False, default=None),
|
||||
)
|
||||
module_kwargs = openstack_module_kwargs(
|
||||
mutually_exclusive=[
|
||||
['name', 'ram'],
|
||||
['name', 'vcpus'],
|
||||
['name', 'ephemeral']
|
||||
]
|
||||
)
|
||||
module = AnsibleModule(argument_spec, **module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
name = module.params['name']
|
||||
vcpus = module.params['vcpus']
|
||||
ram = module.params['ram']
|
||||
ephemeral = module.params['ephemeral']
|
||||
limit = module.params['limit']
|
||||
|
||||
try:
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
if name:
|
||||
flavors = cloud.search_flavors(filters={'name': name})
|
||||
|
||||
else:
|
||||
flavors = cloud.list_flavors()
|
||||
filters = {}
|
||||
if vcpus:
|
||||
filters['vcpus'] = vcpus
|
||||
if ram:
|
||||
filters['ram'] = ram
|
||||
if ephemeral:
|
||||
filters['ephemeral'] = ephemeral
|
||||
if filters:
|
||||
# Range search added in 1.5.0
|
||||
if StrictVersion(shade.__version__) < StrictVersion('1.5.0'):
|
||||
module.fail_json(msg="Shade >= 1.5.0 needed for this functionality")
|
||||
flavors = cloud.range_search(flavors, filters)
|
||||
|
||||
if limit is not None:
|
||||
flavors = flavors[:limit]
|
||||
|
||||
module.exit_json(changed=False,
|
||||
ansible_facts=dict(openstack_flavors=flavors))
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
171
lib/ansible/modules/cloud/openstack/os_group.py
Normal file
171
lib/ansible/modules/cloud/openstack/os_group.py
Normal file
|
@ -0,0 +1,171 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 IBM
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_group
|
||||
short_description: Manage OpenStack Identity Groups
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.1"
|
||||
author: "Monty Taylor (@emonty), David Shrewsbury (@Shrews)"
|
||||
description:
|
||||
- Manage OpenStack Identity Groups. Groups can be created, deleted or
|
||||
updated. Only the I(description) value can be updated.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Group name
|
||||
required: true
|
||||
description:
|
||||
description:
|
||||
- Group description
|
||||
required: false
|
||||
default: None
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a group named "demo"
|
||||
- os_group:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: demo
|
||||
description: "Demo Group"
|
||||
|
||||
# Update the description on existing "demo" group
|
||||
- os_group:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: demo
|
||||
description: "Something else"
|
||||
|
||||
# Delete group named "demo"
|
||||
- os_group:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
name: demo
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
group:
|
||||
description: Dictionary describing the group.
|
||||
returned: On success when I(state) is 'present'.
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Unique group ID
|
||||
type: string
|
||||
sample: "ee6156ff04c645f481a6738311aea0b0"
|
||||
name:
|
||||
description: Group name
|
||||
type: string
|
||||
sample: "demo"
|
||||
description:
|
||||
description: Group description
|
||||
type: string
|
||||
sample: "Demo Group"
|
||||
domain_id:
|
||||
description: Domain for the group
|
||||
type: string
|
||||
sample: "default"
|
||||
'''
|
||||
|
||||
|
||||
def _system_state_change(state, description, group):
|
||||
if state == 'present' and not group:
|
||||
return True
|
||||
if state == 'present' and description is not None and group.description != description:
|
||||
return True
|
||||
if state == 'absent' and group:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
description=dict(required=False, default=None),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
name = module.params.pop('name')
|
||||
description = module.params.pop('description')
|
||||
state = module.params.pop('state')
|
||||
|
||||
try:
|
||||
cloud = shade.operator_cloud(**module.params)
|
||||
group = cloud.get_group(name)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state, description, group))
|
||||
|
||||
if state == 'present':
|
||||
if group is None:
|
||||
group = cloud.create_group(
|
||||
name=name, description=description)
|
||||
changed = True
|
||||
else:
|
||||
if description is not None and group.description != description:
|
||||
group = cloud.update_group(
|
||||
group.id, description=description)
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
module.exit_json(changed=changed, group=group)
|
||||
|
||||
elif state == 'absent':
|
||||
if group is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_group(group.id)
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
173
lib/ansible/modules/cloud/openstack/os_ironic_inspect.py
Normal file
173
lib/ansible/modules/cloud/openstack/os_ironic_inspect.py
Normal file
|
@ -0,0 +1,173 @@
|
|||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
|
||||
# (c) 2015-2016, Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_ironic_inspect
|
||||
short_description: Explicitly triggers baremetal node introspection in ironic.
|
||||
extends_documentation_fragment: openstack
|
||||
author: "Julia Kreger (@juliakreger)"
|
||||
version_added: "2.1"
|
||||
description:
|
||||
- Requests Ironic to set a node into inspect state in order to collect metadata regarding the node.
|
||||
This command may be out of band or in-band depending on the ironic driver configuration.
|
||||
This is only possible on nodes in 'manageable' and 'available' state.
|
||||
options:
|
||||
mac:
|
||||
description:
|
||||
- unique mac address that is used to attempt to identify the host.
|
||||
required: false
|
||||
default: None
|
||||
uuid:
|
||||
description:
|
||||
- globally unique identifier (UUID) to identify the host.
|
||||
required: false
|
||||
default: None
|
||||
name:
|
||||
description:
|
||||
- unique name identifier to identify the host in Ironic.
|
||||
required: false
|
||||
default: None
|
||||
ironic_url:
|
||||
description:
|
||||
- If noauth mode is utilized, this is required to be set to the endpoint URL for the Ironic API.
|
||||
Use with "auth" and "auth_type" settings set to None.
|
||||
required: false
|
||||
default: None
|
||||
timeout:
|
||||
description:
|
||||
- A timeout in seconds to tell the role to wait for the node to complete introspection if wait is set to True.
|
||||
required: false
|
||||
default: 1200
|
||||
|
||||
requirements: ["shade"]
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
ansible_facts:
|
||||
description: Dictionary of new facts representing discovered properties of the node..
|
||||
returned: changed
|
||||
type: dictionary
|
||||
contains:
|
||||
memory_mb:
|
||||
description: Amount of node memory as updated in the node properties
|
||||
type: string
|
||||
sample: "1024"
|
||||
cpu_arch:
|
||||
description: Detected CPU architecture type
|
||||
type: string
|
||||
sample: "x86_64"
|
||||
local_gb:
|
||||
description: Total size of local disk storage as updaed in node properties.
|
||||
type: string
|
||||
sample: "10"
|
||||
cpus:
|
||||
description: Count of cpu cores defined in the updated node properties.
|
||||
type: string
|
||||
sample: "1"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Invoke node inspection
|
||||
- os_ironic_inspect:
|
||||
name: "testnode1"
|
||||
'''
|
||||
|
||||
|
||||
def _choose_id_value(module):
|
||||
if module.params['uuid']:
|
||||
return module.params['uuid']
|
||||
if module.params['name']:
|
||||
return module.params['name']
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
auth_type=dict(required=False),
|
||||
uuid=dict(required=False),
|
||||
name=dict(required=False),
|
||||
mac=dict(required=False),
|
||||
ironic_url=dict(required=False),
|
||||
timeout=dict(default=1200, type='int', required=False),
|
||||
)
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec, **module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
if StrictVersion(shade.__version__) < StrictVersion('1.0.0'):
|
||||
module.fail_json(msg="To utilize this module, the installed version of"
|
||||
"the shade library MUST be >=1.0.0")
|
||||
|
||||
if (module.params['auth_type'] in [None, 'None'] and
|
||||
module.params['ironic_url'] is None):
|
||||
module.fail_json(msg="Authentication appears to be disabled, "
|
||||
"Please define an ironic_url parameter")
|
||||
|
||||
if (module.params['ironic_url'] and
|
||||
module.params['auth_type'] in [None, 'None']):
|
||||
module.params['auth'] = dict(
|
||||
endpoint=module.params['ironic_url']
|
||||
)
|
||||
|
||||
try:
|
||||
cloud = shade.operator_cloud(**module.params)
|
||||
|
||||
if module.params['name'] or module.params['uuid']:
|
||||
server = cloud.get_machine(_choose_id_value(module))
|
||||
elif module.params['mac']:
|
||||
server = cloud.get_machine_by_mac(module.params['mac'])
|
||||
else:
|
||||
module.fail_json(msg="The worlds did not align, "
|
||||
"the host was not found as "
|
||||
"no name, uuid, or mac was "
|
||||
"defined.")
|
||||
if server:
|
||||
cloud.inspect_machine(server['uuid'], module.params['wait'])
|
||||
# TODO(TheJulia): diff properties, ?and ports? and determine
|
||||
# if a change occured. In theory, the node is always changed
|
||||
# if introspection is able to update the record.
|
||||
module.exit_json(changed=True,
|
||||
ansible_facts=server['properties'])
|
||||
|
||||
else:
|
||||
module.fail_json(msg="node not found.")
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
195
lib/ansible/modules/cloud/openstack/os_keystone_domain.py
Normal file
195
lib/ansible/modules/cloud/openstack/os_keystone_domain.py
Normal file
|
@ -0,0 +1,195 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_keystone_domain
|
||||
short_description: Manage OpenStack Identity Domains
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.1"
|
||||
description:
|
||||
- Create, update, or delete OpenStack Identity domains. If a domain
|
||||
with the supplied name already exists, it will be updated with the
|
||||
new description and enabled attributes.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name that has to be given to the instance
|
||||
required: true
|
||||
description:
|
||||
description:
|
||||
- Description of the domain
|
||||
required: false
|
||||
default: None
|
||||
enabled:
|
||||
description:
|
||||
- Is the domain enabled
|
||||
required: false
|
||||
default: True
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a domain
|
||||
- os_keystone_domain:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: demo
|
||||
description: Demo Domain
|
||||
|
||||
# Delete a domain
|
||||
- os_keystone_domain:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
name: demo
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
domain:
|
||||
description: Dictionary describing the domain.
|
||||
returned: On success when I(state) is 'present'
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Domain ID.
|
||||
type: string
|
||||
sample: "474acfe5-be34-494c-b339-50f06aa143e4"
|
||||
name:
|
||||
description: Domain name.
|
||||
type: string
|
||||
sample: "demo"
|
||||
description:
|
||||
description: Domain description.
|
||||
type: string
|
||||
sample: "Demo Domain"
|
||||
enabled:
|
||||
description: Domain description.
|
||||
type: boolean
|
||||
sample: True
|
||||
|
||||
id:
|
||||
description: The domain ID.
|
||||
returned: On success when I(state) is 'present'
|
||||
type: string
|
||||
sample: "474acfe5-be34-494c-b339-50f06aa143e4"
|
||||
'''
|
||||
|
||||
def _needs_update(module, domain):
|
||||
if domain.description != module.params['description']:
|
||||
return True
|
||||
if domain.enabled != module.params['enabled']:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _system_state_change(module, domain):
|
||||
state = module.params['state']
|
||||
if state == 'absent' and domain:
|
||||
return True
|
||||
|
||||
if state == 'present':
|
||||
if domain is None:
|
||||
return True
|
||||
return _needs_update(module, domain)
|
||||
|
||||
return False
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
description=dict(default=None),
|
||||
enabled=dict(default=True, type='bool'),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
name = module.params['name']
|
||||
description = module.params['description']
|
||||
enabled = module.params['enabled']
|
||||
state = module.params['state']
|
||||
|
||||
try:
|
||||
cloud = shade.operator_cloud(**module.params)
|
||||
|
||||
domains = cloud.search_domains(filters=dict(name=name))
|
||||
|
||||
if len(domains) > 1:
|
||||
module.fail_json(msg='Domain name %s is not unique' % name)
|
||||
elif len(domains) == 1:
|
||||
domain = domains[0]
|
||||
else:
|
||||
domain = None
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(module, domain))
|
||||
|
||||
if state == 'present':
|
||||
if domain is None:
|
||||
domain = cloud.create_domain(
|
||||
name=name, description=description, enabled=enabled)
|
||||
changed = True
|
||||
else:
|
||||
if _needs_update(module, domain):
|
||||
domain = cloud.update_domain(
|
||||
domain.id, name=name, description=description,
|
||||
enabled=enabled)
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
module.exit_json(changed=changed, domain=domain, id=domain.id)
|
||||
|
||||
elif state == 'absent':
|
||||
if domain is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_domain(domain.id)
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
144
lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py
Normal file
144
lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py
Normal file
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise Corporation
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_keystone_domain_facts
|
||||
short_description: Retrieve facts about one or more OpenStack domains
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.1"
|
||||
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
|
||||
description:
|
||||
- Retrieve facts about a one or more OpenStack domains
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name or ID of the domain
|
||||
required: true
|
||||
filters:
|
||||
description:
|
||||
- A dictionary of meta data to use for further filtering. Elements of
|
||||
this dictionary may be additional dictionaries.
|
||||
required: false
|
||||
default: None
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Gather facts about previously created domain
|
||||
- os_keystone_domain_facts:
|
||||
cloud: awesomecloud
|
||||
- debug:
|
||||
var: openstack_domains
|
||||
|
||||
# Gather facts about a previously created domain by name
|
||||
- os_keystone_domain_facts:
|
||||
cloud: awesomecloud
|
||||
name: demodomain
|
||||
- debug:
|
||||
var: openstack_domains
|
||||
|
||||
# Gather facts about a previously created domain with filter
|
||||
- os_keystone_domain_facts
|
||||
cloud: awesomecloud
|
||||
name: demodomain
|
||||
filters:
|
||||
enabled: False
|
||||
- debug:
|
||||
var: openstack_domains
|
||||
'''
|
||||
|
||||
|
||||
RETURN = '''
|
||||
openstack_domains:
|
||||
description: has all the OpenStack facts about domains
|
||||
returned: always, but can be null
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Unique UUID.
|
||||
returned: success
|
||||
type: string
|
||||
name:
|
||||
description: Name given to the domain.
|
||||
returned: success
|
||||
type: string
|
||||
description:
|
||||
description: Description of the domain.
|
||||
returned: success
|
||||
type: string
|
||||
enabled:
|
||||
description: Flag to indicate if the domain is enabled.
|
||||
returned: success
|
||||
type: bool
|
||||
'''
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=False, default=None),
|
||||
filters=dict(required=False, type='dict', default=None),
|
||||
)
|
||||
module_kwargs = openstack_module_kwargs(
|
||||
mutually_exclusive=[
|
||||
['name', 'filters'],
|
||||
]
|
||||
)
|
||||
module = AnsibleModule(argument_spec, **module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
try:
|
||||
name = module.params['name']
|
||||
filters = module.params['filters']
|
||||
|
||||
opcloud = shade.operator_cloud(**module.params)
|
||||
|
||||
if name:
|
||||
# Let's suppose user is passing domain ID
|
||||
try:
|
||||
domains = cloud.get_domain(name)
|
||||
except:
|
||||
domains = opcloud.search_domains(filters={'name': name})
|
||||
|
||||
else:
|
||||
domains = opcloud.search_domains(filters)
|
||||
|
||||
module.exit_json(changed=False, ansible_facts=dict(
|
||||
openstack_domains=domains))
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
140
lib/ansible/modules/cloud/openstack/os_keystone_role.py
Normal file
140
lib/ansible/modules/cloud/openstack/os_keystone_role.py
Normal file
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 IBM
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_keystone_role
|
||||
short_description: Manage OpenStack Identity Roles
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.1"
|
||||
author: "Monty Taylor (@emonty), David Shrewsbury (@Shrews)"
|
||||
description:
|
||||
- Manage OpenStack Identity Roles.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Role Name
|
||||
required: true
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a role named "demo"
|
||||
- os_keystone_role:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: demo
|
||||
|
||||
# Delete the role named "demo"
|
||||
- os_keystone_role:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
name: demo
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
role:
|
||||
description: Dictionary describing the role.
|
||||
returned: On success when I(state) is 'present'.
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Unique role ID.
|
||||
type: string
|
||||
sample: "677bfab34c844a01b88a217aa12ec4c2"
|
||||
name:
|
||||
description: Role name.
|
||||
type: string
|
||||
sample: "demo"
|
||||
'''
|
||||
|
||||
|
||||
def _system_state_change(state, role):
|
||||
if state == 'present' and not role:
|
||||
return True
|
||||
if state == 'absent' and role:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
name = module.params.pop('name')
|
||||
state = module.params.pop('state')
|
||||
|
||||
try:
|
||||
cloud = shade.operator_cloud(**module.params)
|
||||
|
||||
role = cloud.get_role(name)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state, role))
|
||||
|
||||
if state == 'present':
|
||||
if role is None:
|
||||
role = cloud.create_role(name)
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
module.exit_json(changed=changed, role=role)
|
||||
elif state == 'absent':
|
||||
if role is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_role(name)
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
214
lib/ansible/modules/cloud/openstack/os_keystone_service.py
Normal file
214
lib/ansible/modules/cloud/openstack/os_keystone_service.py
Normal file
|
@ -0,0 +1,214 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2016 Sam Yaple
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_keystone_service
|
||||
short_description: Manage OpenStack Identity services
|
||||
extends_documentation_fragment: openstack
|
||||
author: "Sam Yaple (@SamYaple)"
|
||||
version_added: "2.2"
|
||||
description:
|
||||
- Create, update, or delete OpenStack Identity service. If a service
|
||||
with the supplied name already exists, it will be updated with the
|
||||
new description and enabled attributes.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name of the service
|
||||
required: true
|
||||
description:
|
||||
description:
|
||||
- Description of the service
|
||||
required: false
|
||||
default: None
|
||||
enabled:
|
||||
description:
|
||||
- Is the service enabled
|
||||
required: false
|
||||
default: True
|
||||
service_type:
|
||||
description:
|
||||
- The type of service
|
||||
required: true
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a service for glance
|
||||
- os_keystone_service:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: glance
|
||||
service_type: image
|
||||
description: OpenStack Image Service
|
||||
# Delete a service
|
||||
- os_keystone_service:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
name: glance
|
||||
service_type: image
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
service:
|
||||
description: Dictionary describing the service.
|
||||
returned: On success when I(state) is 'present'
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Service ID.
|
||||
type: string
|
||||
sample: "3292f020780b4d5baf27ff7e1d224c44"
|
||||
name:
|
||||
description: Service name.
|
||||
type: string
|
||||
sample: "glance"
|
||||
service_type:
|
||||
description: Service type.
|
||||
type: string
|
||||
sample: "image"
|
||||
description:
|
||||
description: Service description.
|
||||
type: string
|
||||
sample: "OpenStack Image Service"
|
||||
enabled:
|
||||
description: Service status.
|
||||
type: boolean
|
||||
sample: True
|
||||
id:
|
||||
description: The service ID.
|
||||
returned: On success when I(state) is 'present'
|
||||
type: string
|
||||
sample: "3292f020780b4d5baf27ff7e1d224c44"
|
||||
'''
|
||||
|
||||
|
||||
def _needs_update(module, service):
|
||||
if service.enabled != module.params['enabled']:
|
||||
return True
|
||||
if service.description is not None and \
|
||||
service.description != module.params['description']:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _system_state_change(module, service):
|
||||
state = module.params['state']
|
||||
if state == 'absent' and service:
|
||||
return True
|
||||
|
||||
if state == 'present':
|
||||
if service is None:
|
||||
return True
|
||||
return _needs_update(module, service)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
description=dict(default=None),
|
||||
enabled=dict(default=True, type='bool'),
|
||||
name=dict(required=True),
|
||||
service_type=dict(required=True),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
if StrictVersion(shade.__version__) < StrictVersion('1.6.0'):
|
||||
module.fail_json(msg="To utilize this module, the installed version of"
|
||||
"the shade library MUST be >=1.6.0")
|
||||
|
||||
description = module.params['description']
|
||||
enabled = module.params['enabled']
|
||||
name = module.params['name']
|
||||
state = module.params['state']
|
||||
service_type = module.params['service_type']
|
||||
|
||||
try:
|
||||
cloud = shade.operator_cloud(**module.params)
|
||||
|
||||
services = cloud.search_services(name_or_id=name,
|
||||
filters=dict(type=service_type))
|
||||
|
||||
if len(services) > 1:
|
||||
module.fail_json(msg='Service name %s and type %s are not unique' %
|
||||
(name, service_type))
|
||||
elif len(services) == 1:
|
||||
service = services[0]
|
||||
else:
|
||||
service = None
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(module, service))
|
||||
|
||||
if state == 'present':
|
||||
if service is None:
|
||||
service = cloud.create_service(name=name,
|
||||
description=description, type=service_type, enabled=True)
|
||||
changed = True
|
||||
else:
|
||||
if _needs_update(module, service):
|
||||
service = cloud.update_service(
|
||||
service.id, name=name, type=service_type, enabled=enabled,
|
||||
description=description)
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
module.exit_json(changed=changed, service=service, id=service.id)
|
||||
|
||||
elif state == 'absent':
|
||||
if service is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_service(service.id)
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
if __name__ == '__main__':
|
||||
main()
|
229
lib/ansible/modules/cloud/openstack/os_port_facts.py
Normal file
229
lib/ansible/modules/cloud/openstack/os_port_facts.py
Normal file
|
@ -0,0 +1,229 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2016 IBM
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
module: os_port_facts
|
||||
short_description: Retrieve facts about ports within OpenStack.
|
||||
version_added: "2.1"
|
||||
author: "David Shrewsbury (@Shrews)"
|
||||
description:
|
||||
- Retrieve facts about ports from OpenStack.
|
||||
notes:
|
||||
- Facts are placed in the C(openstack_ports) variable.
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
options:
|
||||
port:
|
||||
description:
|
||||
- Unique name or ID of a port.
|
||||
required: false
|
||||
default: null
|
||||
filters:
|
||||
description:
|
||||
- A dictionary of meta data to use for further filtering. Elements
|
||||
of this dictionary will be matched against the returned port
|
||||
dictionaries. Matching is currently limited to strings within
|
||||
the port dictionary, or strings within nested dictionaries.
|
||||
required: false
|
||||
default: null
|
||||
extends_documentation_fragment: openstack
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Gather facts about all ports
|
||||
- os_port_facts:
|
||||
cloud: mycloud
|
||||
|
||||
# Gather facts about a single port
|
||||
- os_port_facts:
|
||||
cloud: mycloud
|
||||
port: 6140317d-e676-31e1-8a4a-b1913814a471
|
||||
|
||||
# Gather facts about all ports that have device_id set to a specific value
|
||||
# and with a status of ACTIVE.
|
||||
- os_port_facts:
|
||||
cloud: mycloud
|
||||
filters:
|
||||
device_id: 1038a010-3a37-4a9d-82ea-652f1da36597
|
||||
status: ACTIVE
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
openstack_ports:
|
||||
description: List of port dictionaries. A subset of the dictionary keys
|
||||
listed below may be returned, depending on your cloud provider.
|
||||
returned: always, but can be null
|
||||
type: complex
|
||||
contains:
|
||||
admin_state_up:
|
||||
description: The administrative state of the router, which is
|
||||
up (true) or down (false).
|
||||
returned: success
|
||||
type: boolean
|
||||
sample: true
|
||||
allowed_address_pairs:
|
||||
description: A set of zero or more allowed address pairs. An
|
||||
address pair consists of an IP address and MAC address.
|
||||
returned: success
|
||||
type: list
|
||||
sample: []
|
||||
"binding:host_id":
|
||||
description: The UUID of the host where the port is allocated.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "b4bd682d-234a-4091-aa5b-4b025a6a7759"
|
||||
"binding:profile":
|
||||
description: A dictionary the enables the application running on
|
||||
the host to pass and receive VIF port-specific
|
||||
information to the plug-in.
|
||||
returned: success
|
||||
type: dict
|
||||
sample: {}
|
||||
"binding:vif_details":
|
||||
description: A dictionary that enables the application to pass
|
||||
information about functions that the Networking API
|
||||
provides.
|
||||
returned: success
|
||||
type: dict
|
||||
sample: {"port_filter": true}
|
||||
"binding:vif_type":
|
||||
description: The VIF type for the port.
|
||||
returned: success
|
||||
type: dict
|
||||
sample: "ovs"
|
||||
"binding:vnic_type":
|
||||
description: The virtual network interface card (vNIC) type that is
|
||||
bound to the neutron port.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "normal"
|
||||
device_id:
|
||||
description: The UUID of the device that uses this port.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "b4bd682d-234a-4091-aa5b-4b025a6a7759"
|
||||
device_owner:
|
||||
description: The UUID of the entity that uses this port.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "network:router_interface"
|
||||
dns_assignment:
|
||||
description: DNS assignment information.
|
||||
returned: success
|
||||
type: list
|
||||
dns_name:
|
||||
description: DNS name
|
||||
returned: success
|
||||
type: string
|
||||
sample: ""
|
||||
extra_dhcp_opts:
|
||||
description: A set of zero or more extra DHCP option pairs.
|
||||
An option pair consists of an option value and name.
|
||||
returned: success
|
||||
type: list
|
||||
sample: []
|
||||
fixed_ips:
|
||||
description: The IP addresses for the port. Includes the IP address
|
||||
and UUID of the subnet.
|
||||
returned: success
|
||||
type: list
|
||||
id:
|
||||
description: The UUID of the port.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "3ec25c97-7052-4ab8-a8ba-92faf84148de"
|
||||
ip_address:
|
||||
description: The IP address.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "127.0.0.1"
|
||||
mac_address:
|
||||
description: The MAC address.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "00:00:5E:00:53:42"
|
||||
name:
|
||||
description: The port name.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "port_name"
|
||||
network_id:
|
||||
description: The UUID of the attached network.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "dd1ede4f-3952-4131-aab6-3b8902268c7d"
|
||||
port_security_enabled:
|
||||
description: The port security status. The status is enabled (true) or disabled (false).
|
||||
returned: success
|
||||
type: boolean
|
||||
sample: false
|
||||
security_groups:
|
||||
description: The UUIDs of any attached security groups.
|
||||
returned: success
|
||||
type: list
|
||||
status:
|
||||
description: The port status.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "ACTIVE"
|
||||
tenant_id:
|
||||
description: The UUID of the tenant who owns the network.
|
||||
returned: success
|
||||
type: string
|
||||
sample: "51fce036d7984ba6af4f6c849f65ef00"
|
||||
'''
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
port=dict(required=False),
|
||||
filters=dict(type='dict', required=False),
|
||||
)
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec, **module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
port = module.params.pop('port')
|
||||
filters = module.params.pop('filters')
|
||||
|
||||
try:
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
ports = cloud.search_ports(port, filters)
|
||||
module.exit_json(changed=False, ansible_facts=dict(
|
||||
openstack_ports=ports))
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
232
lib/ansible/modules/cloud/openstack/os_project.py
Normal file
232
lib/ansible/modules/cloud/openstack/os_project.py
Normal file
|
@ -0,0 +1,232 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2015 IBM Corporation
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_project
|
||||
short_description: Manage OpenStack Projects
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.0"
|
||||
author: "Alberto Gireud (@agireud)"
|
||||
description:
|
||||
- Manage OpenStack Projects. Projects can be created,
|
||||
updated or deleted using this module. A project will be updated
|
||||
if I(name) matches an existing project and I(state) is present.
|
||||
The value for I(name) cannot be updated without deleting and
|
||||
re-creating the project.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name for the project
|
||||
required: true
|
||||
description:
|
||||
description:
|
||||
- Description for the project
|
||||
required: false
|
||||
default: None
|
||||
domain_id:
|
||||
description:
|
||||
- Domain id to create the project in if the cloud supports domains.
|
||||
The domain_id parameter requires shade >= 1.8.0
|
||||
required: false
|
||||
default: None
|
||||
aliases: ['domain']
|
||||
enabled:
|
||||
description:
|
||||
- Is the project enabled
|
||||
required: false
|
||||
default: True
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a project
|
||||
- os_project:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: demoproject
|
||||
description: demodescription
|
||||
domain_id: demoid
|
||||
enabled: True
|
||||
|
||||
# Delete a project
|
||||
- os_project:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
name: demoproject
|
||||
'''
|
||||
|
||||
|
||||
RETURN = '''
|
||||
project:
|
||||
description: Dictionary describing the project.
|
||||
returned: On success when I(state) is 'present'
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Project ID
|
||||
type: string
|
||||
sample: "f59382db809c43139982ca4189404650"
|
||||
name:
|
||||
description: Project name
|
||||
type: string
|
||||
sample: "demoproject"
|
||||
description:
|
||||
description: Project description
|
||||
type: string
|
||||
sample: "demodescription"
|
||||
enabled:
|
||||
description: Boolean to indicate if project is enabled
|
||||
type: bool
|
||||
sample: True
|
||||
'''
|
||||
|
||||
def _needs_update(module, project):
|
||||
keys = ('description', 'enabled')
|
||||
for key in keys:
|
||||
if module.params[key] is not None and module.params[key] != project.get(key):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _system_state_change(module, project):
|
||||
state = module.params['state']
|
||||
if state == 'present':
|
||||
if project is None:
|
||||
changed = True
|
||||
else:
|
||||
if _needs_update(module, project):
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
|
||||
elif state == 'absent':
|
||||
if project is None:
|
||||
changed=False
|
||||
else:
|
||||
changed=True
|
||||
|
||||
return changed;
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
description=dict(required=False, default=None),
|
||||
domain_id=dict(required=False, default=None, aliases=['domain']),
|
||||
enabled=dict(default=True, type='bool'),
|
||||
state=dict(default='present', choices=['absent', 'present'])
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(
|
||||
argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs
|
||||
)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
name = module.params['name']
|
||||
description = module.params['description']
|
||||
domain = module.params.pop('domain_id')
|
||||
enabled = module.params['enabled']
|
||||
state = module.params['state']
|
||||
|
||||
if domain and StrictVersion(shade.__version__) < StrictVersion('1.8.0'):
|
||||
module.fail_json(msg="The domain argument requires shade >=1.8.0")
|
||||
|
||||
try:
|
||||
if domain:
|
||||
opcloud = shade.operator_cloud(**module.params)
|
||||
try:
|
||||
# We assume admin is passing domain id
|
||||
dom = opcloud.get_domain(domain)['id']
|
||||
domain = dom
|
||||
except:
|
||||
# If we fail, maybe admin is passing a domain name.
|
||||
# Note that domains have unique names, just like id.
|
||||
try:
|
||||
dom = opcloud.search_domains(filters={'name': domain})[0]['id']
|
||||
domain = dom
|
||||
except:
|
||||
# Ok, let's hope the user is non-admin and passing a sane id
|
||||
pass
|
||||
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
|
||||
if domain:
|
||||
project = cloud.get_project(name, domain_id=domain)
|
||||
else:
|
||||
project = cloud.get_project(name)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(module, project))
|
||||
|
||||
if state == 'present':
|
||||
if project is None:
|
||||
project = cloud.create_project(
|
||||
name=name, description=description,
|
||||
domain_id=domain,
|
||||
enabled=enabled)
|
||||
changed = True
|
||||
else:
|
||||
if _needs_update(module, project):
|
||||
project = cloud.update_project(
|
||||
project['id'], description=description,
|
||||
enabled=enabled)
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
module.exit_json(changed=changed, project=project)
|
||||
|
||||
elif state == 'absent':
|
||||
if project is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_project(project['id'])
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=e.message, extra_data=e.extra_data)
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
171
lib/ansible/modules/cloud/openstack/os_project_facts.py
Normal file
171
lib/ansible/modules/cloud/openstack/os_project_facts.py
Normal file
|
@ -0,0 +1,171 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise Corporation
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_project_facts
|
||||
short_description: Retrieve facts about one or more OpenStack projects
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.1"
|
||||
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
|
||||
description:
|
||||
- Retrieve facts about a one or more OpenStack projects
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name or ID of the project
|
||||
required: true
|
||||
domain:
|
||||
description:
|
||||
- Name or ID of the domain containing the project if the cloud supports domains
|
||||
required: false
|
||||
default: None
|
||||
filters:
|
||||
description:
|
||||
- A dictionary of meta data to use for further filtering. Elements of
|
||||
this dictionary may be additional dictionaries.
|
||||
required: false
|
||||
default: None
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Gather facts about previously created projects
|
||||
- os_project_facts:
|
||||
cloud: awesomecloud
|
||||
- debug:
|
||||
var: openstack_projects
|
||||
|
||||
# Gather facts about a previously created project by name
|
||||
- os_project_facts:
|
||||
cloud: awesomecloud
|
||||
name: demoproject
|
||||
- debug:
|
||||
var: openstack_projects
|
||||
|
||||
# Gather facts about a previously created project in a specific domain
|
||||
- os_project_facts
|
||||
cloud: awesomecloud
|
||||
name: demoproject
|
||||
domain: admindomain
|
||||
- debug:
|
||||
var: openstack_projects
|
||||
|
||||
# Gather facts about a previously created project in a specific domain
|
||||
with filter
|
||||
- os_project_facts
|
||||
cloud: awesomecloud
|
||||
name: demoproject
|
||||
domain: admindomain
|
||||
filters:
|
||||
enabled: False
|
||||
- debug:
|
||||
var: openstack_projects
|
||||
'''
|
||||
|
||||
|
||||
RETURN = '''
|
||||
openstack_projects:
|
||||
description: has all the OpenStack facts about projects
|
||||
returned: always, but can be null
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Unique UUID.
|
||||
returned: success
|
||||
type: string
|
||||
name:
|
||||
description: Name given to the project.
|
||||
returned: success
|
||||
type: string
|
||||
description:
|
||||
description: Description of the project
|
||||
returned: success
|
||||
type: string
|
||||
enabled:
|
||||
description: Flag to indicate if the project is enabled
|
||||
returned: success
|
||||
type: bool
|
||||
domain_id:
|
||||
description: Domain ID containing the project (keystone v3 clouds only)
|
||||
returned: success
|
||||
type: bool
|
||||
'''
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=False, default=None),
|
||||
domain=dict(required=False, default=None),
|
||||
filters=dict(required=False, type='dict', default=None),
|
||||
)
|
||||
|
||||
module = AnsibleModule(argument_spec)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
try:
|
||||
name = module.params['name']
|
||||
domain = module.params['domain']
|
||||
filters = module.params['filters']
|
||||
|
||||
opcloud = shade.operator_cloud(**module.params)
|
||||
|
||||
if domain:
|
||||
try:
|
||||
# We assume admin is passing domain id
|
||||
dom = opcloud.get_domain(domain)['id']
|
||||
domain = dom
|
||||
except:
|
||||
# If we fail, maybe admin is passing a domain name.
|
||||
# Note that domains have unique names, just like id.
|
||||
dom = opcloud.search_domains(filters={'name': domain})
|
||||
if dom:
|
||||
domain = dom[0]['id']
|
||||
else:
|
||||
module.fail_json(msg='Domain name or ID does not exist')
|
||||
|
||||
if not filters:
|
||||
filters = {}
|
||||
|
||||
filters['domain_id'] = domain
|
||||
|
||||
projects = opcloud.search_projects(name, filters)
|
||||
module.exit_json(changed=False, ansible_facts=dict(
|
||||
openstack_projects=projects))
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
246
lib/ansible/modules/cloud/openstack/os_recordset.py
Normal file
246
lib/ansible/modules/cloud/openstack/os_recordset.py
Normal file
|
@ -0,0 +1,246 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_recordset
|
||||
short_description: Manage OpenStack DNS recordsets
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.2"
|
||||
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
|
||||
description:
|
||||
- Manage OpenStack DNS recordsets. Recordsets can be created, deleted or
|
||||
updated. Only the I(records), I(description), and I(ttl) values
|
||||
can be updated.
|
||||
options:
|
||||
zone:
|
||||
description:
|
||||
- Zone managing the recordset
|
||||
required: true
|
||||
name:
|
||||
description:
|
||||
- Name of the recordset
|
||||
required: true
|
||||
recordset_type:
|
||||
description:
|
||||
- Recordset type
|
||||
required: true
|
||||
records:
|
||||
description:
|
||||
- List of recordset definitions
|
||||
required: true
|
||||
description:
|
||||
description:
|
||||
- Description of the recordset
|
||||
required: false
|
||||
default: None
|
||||
ttl:
|
||||
description:
|
||||
- TTL (Time To Live) value in seconds
|
||||
required: false
|
||||
default: None
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a recordset named "www.example.net."
|
||||
- os_recordset:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
zone: example.net.
|
||||
name: www
|
||||
recordset_type: primary
|
||||
records: ['10.1.1.1']
|
||||
description: test recordset
|
||||
ttl: 3600
|
||||
|
||||
# Update the TTL on existing "www.example.net." recordset
|
||||
- os_recordset:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
zone: example.net.
|
||||
name: www
|
||||
ttl: 7200
|
||||
|
||||
# Delete recorset named "www.example.net."
|
||||
- os_recordset:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
zone: example.net.
|
||||
name: www
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
recordset:
|
||||
description: Dictionary describing the recordset.
|
||||
returned: On success when I(state) is 'present'.
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Unique recordset ID
|
||||
type: string
|
||||
sample: "c1c530a3-3619-46f3-b0f6-236927b2618c"
|
||||
name:
|
||||
description: Recordset name
|
||||
type: string
|
||||
sample: "www.example.net."
|
||||
zone_id:
|
||||
description: Zone id
|
||||
type: string
|
||||
sample: 9508e177-41d8-434e-962c-6fe6ca880af7
|
||||
type:
|
||||
description: Recordset type
|
||||
type: string
|
||||
sample: "A"
|
||||
description:
|
||||
description: Recordset description
|
||||
type: string
|
||||
sample: "Test description"
|
||||
ttl:
|
||||
description: Zone TTL value
|
||||
type: int
|
||||
sample: 3600
|
||||
records:
|
||||
description: Recordset records
|
||||
type: list
|
||||
sample: ['10.0.0.1']
|
||||
'''
|
||||
|
||||
|
||||
def _system_state_change(state, records, description, ttl, zone, recordset):
|
||||
if state == 'present':
|
||||
if recordset is None:
|
||||
return True
|
||||
if records is not None and recordset.records != records:
|
||||
return True
|
||||
if description is not None and recordset.description != description:
|
||||
return True
|
||||
if ttl is not None and recordset.ttl != ttl:
|
||||
return True
|
||||
if state == 'absent' and recordset:
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
zone=dict(required=True),
|
||||
name=dict(required=True),
|
||||
recordset_type=dict(required=False),
|
||||
records=dict(required=False, type='list'),
|
||||
description=dict(required=False, default=None),
|
||||
ttl=dict(required=False, default=None, type='int'),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
required_if=[
|
||||
('state', 'present',
|
||||
['recordset_type', 'records'])],
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
if StrictVersion(shade.__version__) <= StrictVersion('1.8.0'):
|
||||
module.fail_json(msg="To utilize this module, the installed version of "
|
||||
"the shade library MUST be >1.8.0")
|
||||
|
||||
zone = module.params.get('zone')
|
||||
name = module.params.get('name')
|
||||
state = module.params.get('state')
|
||||
|
||||
try:
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
recordset = cloud.get_recordset(zone, name + '.' + zone)
|
||||
|
||||
|
||||
if state == 'present':
|
||||
recordset_type = module.params.get('recordset_type')
|
||||
records = module.params.get('records')
|
||||
description = module.params.get('description')
|
||||
ttl = module.params.get('ttl')
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state,
|
||||
records, description,
|
||||
ttl, zone,
|
||||
recordset))
|
||||
|
||||
if recordset is None:
|
||||
recordset = cloud.create_recordset(
|
||||
zone=zone, name=name, recordset_type=recordset_type,
|
||||
records=records, description=description, ttl=ttl)
|
||||
changed = True
|
||||
else:
|
||||
if records is None:
|
||||
records = []
|
||||
|
||||
pre_update_recordset = recordset
|
||||
changed = _system_state_change(state, records,
|
||||
description, ttl,
|
||||
zone, pre_update_recordset)
|
||||
if changed:
|
||||
zone = cloud.update_recordset(
|
||||
zone, name + '.' + zone,
|
||||
records=records,
|
||||
description=description,
|
||||
ttl=ttl)
|
||||
module.exit_json(changed=changed, recordset=recordset)
|
||||
|
||||
elif state == 'absent':
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state,
|
||||
None, None,
|
||||
None,
|
||||
None, recordset))
|
||||
|
||||
if recordset is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_recordset(zone, name + '.' + zone)
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
186
lib/ansible/modules/cloud/openstack/os_server_group.py
Normal file
186
lib/ansible/modules/cloud/openstack/os_server_group.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2016 Catalyst IT Limited
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_server_group
|
||||
short_description: Manage OpenStack server groups
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.2"
|
||||
author: "Lingxian Kong (@kong)"
|
||||
description:
|
||||
- Add or remove server groups from OpenStack.
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
- Indicate desired state of the resource. When I(state) is 'present',
|
||||
then I(policies) is required.
|
||||
choices: ['present', 'absent']
|
||||
required: false
|
||||
default: present
|
||||
name:
|
||||
description:
|
||||
- Server group name.
|
||||
required: true
|
||||
policies:
|
||||
description:
|
||||
- A list of one or more policy names to associate with the server
|
||||
group. The list must contain at least one policy name. The current
|
||||
valid policy names are anti-affinity, affinity, soft-anti-affinity
|
||||
and soft-affinity.
|
||||
required: false
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a server group with 'affinity' policy.
|
||||
- os_server_group:
|
||||
state: present
|
||||
auth:
|
||||
auth_url: https://api.cloud.catalyst.net.nz:5000/v2.0
|
||||
username: admin
|
||||
password: admin
|
||||
project_name: admin
|
||||
name: my_server_group
|
||||
policies:
|
||||
- affinity
|
||||
|
||||
# Delete 'my_server_group' server group.
|
||||
- os_server_group:
|
||||
state: absent
|
||||
auth:
|
||||
auth_url: https://api.cloud.catalyst.net.nz:5000/v2.0
|
||||
username: admin
|
||||
password: admin
|
||||
project_name: admin
|
||||
name: my_server_group
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
id:
|
||||
description: Unique UUID.
|
||||
returned: success
|
||||
type: string
|
||||
name:
|
||||
description: The name of the server group.
|
||||
returned: success
|
||||
type: string
|
||||
policies:
|
||||
description: A list of one or more policy names of the server group.
|
||||
returned: success
|
||||
type: list of strings
|
||||
members:
|
||||
description: A list of members in the server group.
|
||||
returned: success
|
||||
type: list of strings
|
||||
metadata:
|
||||
description: Metadata key and value pairs.
|
||||
returned: success
|
||||
type: dict
|
||||
project_id:
|
||||
description: The project ID who owns the server group.
|
||||
returned: success
|
||||
type: string
|
||||
user_id:
|
||||
description: The user ID who owns the server group.
|
||||
returned: success
|
||||
type: string
|
||||
'''
|
||||
|
||||
|
||||
def _system_state_change(state, server_group):
|
||||
if state == 'present' and not server_group:
|
||||
return True
|
||||
if state == 'absent' and server_group:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
policies=dict(required=False, type='list'),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(
|
||||
argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs
|
||||
)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
name = module.params['name']
|
||||
policies = module.params['policies']
|
||||
state = module.params['state']
|
||||
|
||||
try:
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
server_group = cloud.get_server_group(name)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(
|
||||
changed=_system_state_change(state, server_group)
|
||||
)
|
||||
|
||||
changed = False
|
||||
if state == 'present':
|
||||
if not server_group:
|
||||
if not policies:
|
||||
module.fail_json(
|
||||
msg="Parameter 'policies' is required in Server Group "
|
||||
"Create"
|
||||
)
|
||||
server_group = cloud.create_server_group(name, policies)
|
||||
changed = True
|
||||
|
||||
module.exit_json(
|
||||
changed=changed,
|
||||
id=server_group['id'],
|
||||
server_group=server_group
|
||||
)
|
||||
if state == 'absent':
|
||||
if server_group:
|
||||
cloud.delete_server_group(server_group['id'])
|
||||
changed = True
|
||||
module.exit_json(changed=changed)
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e), extra_data=e.extra_data)
|
||||
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
267
lib/ansible/modules/cloud/openstack/os_stack.py
Normal file
267
lib/ansible/modules/cloud/openstack/os_stack.py
Normal file
|
@ -0,0 +1,267 @@
|
|||
#!/usr/bin/python
|
||||
#coding: utf-8 -*-
|
||||
|
||||
# (c) 2016, Mathieu Bultel <mbultel@redhat.com>
|
||||
# (c) 2016, Steve Baker <sbaker@redhat.com>
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from time import sleep
|
||||
from distutils.version import StrictVersion
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_stack
|
||||
short_description: Add/Remove Heat Stack
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.2"
|
||||
author: "Mathieu Bultel (matbu), Steve Baker (steveb)"
|
||||
description:
|
||||
- Add or Remove a Stack to an OpenStack Heat
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
- Indicate desired state of the resource
|
||||
choices: ['present', 'absent']
|
||||
required: false
|
||||
default: present
|
||||
name:
|
||||
description:
|
||||
- Name of the stack that should be created, name could be char and digit, no space
|
||||
required: true
|
||||
template:
|
||||
description:
|
||||
- Path of the template file to use for the stack creation
|
||||
required: false
|
||||
default: None
|
||||
environment:
|
||||
description:
|
||||
- List of environment files that should be used for the stack creation
|
||||
required: false
|
||||
default: None
|
||||
parameters:
|
||||
description:
|
||||
- Dictionary of parameters for the stack creation
|
||||
required: false
|
||||
default: None
|
||||
rollback:
|
||||
description:
|
||||
- Rollback stack creation
|
||||
required: false
|
||||
default: false
|
||||
timeout:
|
||||
description:
|
||||
- Maximum number of seconds to wait for the stack creation
|
||||
required: false
|
||||
default: 3600
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
EXAMPLES = '''
|
||||
---
|
||||
- name: create stack
|
||||
ignore_errors: True
|
||||
register: stack_create
|
||||
os_stack:
|
||||
name: "{{ stack_name }}"
|
||||
state: present
|
||||
template: "/path/to/my_stack.yaml"
|
||||
environment:
|
||||
- /path/to/resource-registry.yaml
|
||||
- /path/to/environment.yaml
|
||||
parameters:
|
||||
bmc_flavor: m1.medium
|
||||
bmc_image: CentOS
|
||||
key_name: default
|
||||
private_net: {{ private_net_param }}
|
||||
node_count: 2
|
||||
name: undercloud
|
||||
image: CentOS
|
||||
my_flavor: m1.large
|
||||
external_net: {{ external_net_param }}
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
id:
|
||||
description: Stack ID.
|
||||
type: string
|
||||
sample: "97a3f543-8136-4570-920e-fd7605c989d6"
|
||||
|
||||
stack:
|
||||
action:
|
||||
description: Action, could be Create or Update.
|
||||
type: string
|
||||
sample: "CREATE"
|
||||
creation_time:
|
||||
description: Time when the action has been made.
|
||||
type: string
|
||||
sample: "2016-07-05T17:38:12Z"
|
||||
description:
|
||||
description: Description of the Stack provided in the heat template.
|
||||
type: string
|
||||
sample: "HOT template to create a new instance and networks"
|
||||
id:
|
||||
description: Stack ID.
|
||||
type: string
|
||||
sample: "97a3f543-8136-4570-920e-fd7605c989d6"
|
||||
name:
|
||||
description: Name of the Stack
|
||||
type: string
|
||||
sample: "test-stack"
|
||||
identifier:
|
||||
description: Identifier of the current Stack action.
|
||||
type: string
|
||||
sample: "test-stack/97a3f543-8136-4570-920e-fd7605c989d6"
|
||||
links:
|
||||
description: Links to the current Stack.
|
||||
type: list of dict
|
||||
sample: "[{'href': 'http://foo:8004/v1/7f6a/stacks/test-stack/97a3f543-8136-4570-920e-fd7605c989d6']"
|
||||
outputs:
|
||||
description: Output returned by the Stack.
|
||||
type: list of dict
|
||||
sample: "{'description': 'IP address of server1 in private network',
|
||||
'output_key': 'server1_private_ip',
|
||||
'output_value': '10.1.10.103'}"
|
||||
parameters:
|
||||
description: Parameters of the current Stack
|
||||
type: dict
|
||||
sample: "{'OS::project_id': '7f6a3a3e01164a4eb4eecb2ab7742101',
|
||||
'OS::stack_id': '97a3f543-8136-4570-920e-fd7605c989d6',
|
||||
'OS::stack_name': 'test-stack',
|
||||
'stack_status': 'CREATE_COMPLETE',
|
||||
'stack_status_reason': 'Stack CREATE completed successfully',
|
||||
'status': 'COMPLETE',
|
||||
'template_description': 'HOT template to create a new instance and networks',
|
||||
'timeout_mins': 60,
|
||||
'updated_time': null}"
|
||||
'''
|
||||
|
||||
def _create_stack(module, stack, cloud):
|
||||
try:
|
||||
stack = cloud.create_stack(module.params['name'],
|
||||
template_file=module.params['template'],
|
||||
environment_files=module.params['environment'],
|
||||
timeout=module.params['timeout'],
|
||||
wait=True,
|
||||
rollback=module.params['rollback'],
|
||||
**module.params['parameters'])
|
||||
|
||||
stack = cloud.get_stack(stack.id, None)
|
||||
if stack.stack_status == 'CREATE_COMPLETE':
|
||||
return stack
|
||||
else:
|
||||
return False
|
||||
module.fail_json(msg = "Failure in creating stack: ".format(stack))
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
def _update_stack(module, stack, cloud):
|
||||
try:
|
||||
stack = cloud.update_stack(
|
||||
module.params['name'],
|
||||
template_file=module.params['template'],
|
||||
environment_files=module.params['environment'],
|
||||
timeout=module.params['timeout'],
|
||||
rollback=module.params['rollback'],
|
||||
wait=module.params['wait'],
|
||||
**module.params['parameters'])
|
||||
|
||||
if stack['stack_status'] == 'UPDATE_COMPLETE':
|
||||
return stack
|
||||
else:
|
||||
module.fail_json(msg = "Failure in updating stack: %s" %
|
||||
stack['stack_status_reason'])
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
def _system_state_change(module, stack, cloud):
|
||||
state = module.params['state']
|
||||
if state == 'present':
|
||||
if not stack:
|
||||
return True
|
||||
if state == 'absent' and stack:
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
template=dict(default=None),
|
||||
environment=dict(default=None, type='list'),
|
||||
parameters=dict(default={}, type='dict'),
|
||||
rollback=dict(default=False, type='bool'),
|
||||
timeout=dict(default=3600, type='int'),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
# stack API introduced in 1.8.0
|
||||
if not HAS_SHADE or (StrictVersion(shade.__version__) < StrictVersion('1.8.0')):
|
||||
module.fail_json(msg='shade 1.8.0 or higher is required for this module')
|
||||
|
||||
state = module.params['state']
|
||||
name = module.params['name']
|
||||
# Check for required parameters when state == 'present'
|
||||
if state == 'present':
|
||||
for p in ['template']:
|
||||
if not module.params[p]:
|
||||
module.fail_json(msg='%s required with present state' % p)
|
||||
|
||||
try:
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
stack = cloud.get_stack(name)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(module, stack,
|
||||
cloud))
|
||||
|
||||
if state == 'present':
|
||||
if not stack:
|
||||
stack = _create_stack(module, stack, cloud)
|
||||
else:
|
||||
stack = _update_stack(module, stack, cloud)
|
||||
changed = True
|
||||
module.exit_json(changed=changed,
|
||||
stack=stack,
|
||||
id=stack.id)
|
||||
elif state == 'absent':
|
||||
if not stack:
|
||||
changed = False
|
||||
else:
|
||||
changed = True
|
||||
if not cloud.delete_stack(name, wait=module.params['wait']):
|
||||
module.fail_json(msg='delete stack failed for stack: %s' % name)
|
||||
module.exit_json(changed=changed)
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
if __name__ == '__main__':
|
||||
main()
|
180
lib/ansible/modules/cloud/openstack/os_user_facts.py
Normal file
180
lib/ansible/modules/cloud/openstack/os_user_facts.py
Normal file
|
@ -0,0 +1,180 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise Corporation
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_user_facts
|
||||
short_description: Retrieve facts about one or more OpenStack users
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.1"
|
||||
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
|
||||
description:
|
||||
- Retrieve facts about a one or more OpenStack users
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name or ID of the user
|
||||
required: true
|
||||
domain:
|
||||
description:
|
||||
- Name or ID of the domain containing the user if the cloud supports domains
|
||||
required: false
|
||||
default: None
|
||||
filters:
|
||||
description:
|
||||
- A dictionary of meta data to use for further filtering. Elements of
|
||||
this dictionary may be additional dictionaries.
|
||||
required: false
|
||||
default: None
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Gather facts about previously created users
|
||||
- os_user_facts:
|
||||
cloud: awesomecloud
|
||||
- debug:
|
||||
var: openstack_users
|
||||
|
||||
# Gather facts about a previously created user by name
|
||||
- os_user_facts:
|
||||
cloud: awesomecloud
|
||||
name: demouser
|
||||
- debug:
|
||||
var: openstack_users
|
||||
|
||||
# Gather facts about a previously created user in a specific domain
|
||||
- os_user_facts
|
||||
cloud: awesomecloud
|
||||
name: demouser
|
||||
domain: admindomain
|
||||
- debug:
|
||||
var: openstack_users
|
||||
|
||||
# Gather facts about a previously created user in a specific domain
|
||||
with filter
|
||||
- os_user_facts
|
||||
cloud: awesomecloud
|
||||
name: demouser
|
||||
domain: admindomain
|
||||
filters:
|
||||
enabled: False
|
||||
- debug:
|
||||
var: openstack_users
|
||||
'''
|
||||
|
||||
|
||||
RETURN = '''
|
||||
openstack_users:
|
||||
description: has all the OpenStack facts about users
|
||||
returned: always, but can be null
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Unique UUID.
|
||||
returned: success
|
||||
type: string
|
||||
name:
|
||||
description: Name given to the user.
|
||||
returned: success
|
||||
type: string
|
||||
enabled:
|
||||
description: Flag to indicate if the user is enabled
|
||||
returned: success
|
||||
type: bool
|
||||
domain_id:
|
||||
description: Domain ID containing the user
|
||||
returned: success
|
||||
type: string
|
||||
default_project_id:
|
||||
description: Default project ID of the user
|
||||
returned: success
|
||||
type: string
|
||||
email:
|
||||
description: Email of the user
|
||||
returned: success
|
||||
type: string
|
||||
username:
|
||||
description: Username of the user
|
||||
returned: success
|
||||
type: string
|
||||
'''
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=False, default=None),
|
||||
domain=dict(required=False, default=None),
|
||||
filters=dict(required=False, type='dict', default=None),
|
||||
)
|
||||
|
||||
module = AnsibleModule(argument_spec)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
|
||||
try:
|
||||
name = module.params['name']
|
||||
domain = module.params['domain']
|
||||
filters = module.params['filters']
|
||||
|
||||
opcloud = shade.operator_cloud(**module.params)
|
||||
|
||||
if domain:
|
||||
try:
|
||||
# We assume admin is passing domain id
|
||||
dom = opcloud.get_domain(domain)['id']
|
||||
domain = dom
|
||||
except:
|
||||
# If we fail, maybe admin is passing a domain name.
|
||||
# Note that domains have unique names, just like id.
|
||||
dom = opcloud.search_domains(filters={'name': domain})
|
||||
if dom:
|
||||
domain = dom[0]['id']
|
||||
else:
|
||||
module.fail_json(msg='Domain name or ID does not exist')
|
||||
|
||||
if not filters:
|
||||
filters = {}
|
||||
|
||||
filters['domain_id'] = domain
|
||||
|
||||
users = opcloud.search_users(name,
|
||||
filters)
|
||||
module.exit_json(changed=False, ansible_facts=dict(
|
||||
openstack_users=users))
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
216
lib/ansible/modules/cloud/openstack/os_user_role.py
Normal file
216
lib/ansible/modules/cloud/openstack/os_user_role.py
Normal file
|
@ -0,0 +1,216 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 IBM
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_user_role
|
||||
short_description: Associate OpenStack Identity users and roles
|
||||
extends_documentation_fragment: openstack
|
||||
author: "Monty Taylor (@emonty), David Shrewsbury (@Shrews)"
|
||||
version_added: "2.1"
|
||||
description:
|
||||
- Grant and revoke roles in either project or domain context for
|
||||
OpenStack Identity Users.
|
||||
options:
|
||||
role:
|
||||
description:
|
||||
- Name or ID for the role.
|
||||
required: true
|
||||
user:
|
||||
description:
|
||||
- Name or ID for the user. If I(user) is not specified, then
|
||||
I(group) is required. Both may not be specified.
|
||||
required: false
|
||||
default: null
|
||||
group:
|
||||
description:
|
||||
- Name or ID for the group. Valid only with keystone version 3.
|
||||
If I(group) is not specified, then I(user) is required. Both
|
||||
may not be specified.
|
||||
required: false
|
||||
default: null
|
||||
project:
|
||||
description:
|
||||
- Name or ID of the project to scope the role assocation to.
|
||||
If you are using keystone version 2, then this value is required.
|
||||
required: false
|
||||
default: null
|
||||
domain:
|
||||
description:
|
||||
- ID of the domain to scope the role association to. Valid only with
|
||||
keystone version 3, and required if I(project) is not specified.
|
||||
required: false
|
||||
default: null
|
||||
state:
|
||||
description:
|
||||
- Should the roles be present or absent on the user.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Grant an admin role on the user admin in the project project1
|
||||
- os_user_role:
|
||||
cloud: mycloud
|
||||
user: admin
|
||||
role: admin
|
||||
project: project1
|
||||
|
||||
# Revoke the admin role from the user barney in the newyork domain
|
||||
- os_user_role:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
user: barney
|
||||
role: admin
|
||||
domain: newyork
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
#
|
||||
'''
|
||||
|
||||
def _system_state_change(state, assignment):
|
||||
if state == 'present' and not assignment:
|
||||
return True
|
||||
elif state == 'absent' and assignment:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _build_kwargs(user, group, project, domain):
|
||||
kwargs = {}
|
||||
if user:
|
||||
kwargs['user'] = user
|
||||
if group:
|
||||
kwargs['group'] = group
|
||||
if project:
|
||||
kwargs['project'] = project
|
||||
if domain:
|
||||
kwargs['domain'] = domain
|
||||
return kwargs
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
role=dict(required=True),
|
||||
user=dict(required=False),
|
||||
group=dict(required=False),
|
||||
project=dict(required=False),
|
||||
domain=dict(required=False),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs(
|
||||
required_one_of=[
|
||||
['user', 'group']
|
||||
])
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
# role grant/revoke API introduced in 1.5.0
|
||||
if not HAS_SHADE or (StrictVersion(shade.__version__) < StrictVersion('1.5.0')):
|
||||
module.fail_json(msg='shade 1.5.0 or higher is required for this module')
|
||||
|
||||
role = module.params.pop('role')
|
||||
user = module.params.pop('user')
|
||||
group = module.params.pop('group')
|
||||
project = module.params.pop('project')
|
||||
domain = module.params.pop('domain')
|
||||
state = module.params.pop('state')
|
||||
|
||||
try:
|
||||
cloud = shade.operator_cloud(**module.params)
|
||||
|
||||
filters = {}
|
||||
|
||||
r = cloud.get_role(role)
|
||||
if r is None:
|
||||
module.fail_json(msg="Role %s is not valid" % role)
|
||||
filters['role'] = r['id']
|
||||
|
||||
if user:
|
||||
u = cloud.get_user(user)
|
||||
if u is None:
|
||||
module.fail_json(msg="User %s is not valid" % user)
|
||||
filters['user'] = u['id']
|
||||
if group:
|
||||
g = cloud.get_group(group)
|
||||
if g is None:
|
||||
module.fail_json(msg="Group %s is not valid" % group)
|
||||
filters['group'] = g['id']
|
||||
if domain:
|
||||
d = cloud.get_domain(domain)
|
||||
if d is None:
|
||||
module.fail_json(msg="Domain %s is not valid" % domain)
|
||||
filters['domain'] = d['id']
|
||||
if project:
|
||||
if domain:
|
||||
p = cloud.get_project(project, domain_id=filters['domain'])
|
||||
else:
|
||||
p = cloud.get_project(project)
|
||||
|
||||
if p is None:
|
||||
module.fail_json(msg="Project %s is not valid" % project)
|
||||
filters['project'] = p['id']
|
||||
|
||||
assignment = cloud.list_role_assignments(filters=filters)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state, assignment))
|
||||
|
||||
changed = False
|
||||
|
||||
if state == 'present':
|
||||
if not assignment:
|
||||
kwargs = _build_kwargs(user, group, project, domain)
|
||||
cloud.grant_role(role, **kwargs)
|
||||
changed = True
|
||||
|
||||
elif state == 'absent':
|
||||
if assignment:
|
||||
kwargs = _build_kwargs(user, group, project, domain)
|
||||
cloud.revoke_role(role, **kwargs)
|
||||
changed=True
|
||||
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
241
lib/ansible/modules/cloud/openstack/os_zone.py
Normal file
241
lib/ansible/modules/cloud/openstack/os_zone.py
Normal file
|
@ -0,0 +1,241 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
import shade
|
||||
HAS_SHADE = True
|
||||
except ImportError:
|
||||
HAS_SHADE = False
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: os_zone
|
||||
short_description: Manage OpenStack DNS zones
|
||||
extends_documentation_fragment: openstack
|
||||
version_added: "2.2"
|
||||
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
|
||||
description:
|
||||
- Manage OpenStack DNS zones. Zones can be created, deleted or
|
||||
updated. Only the I(email), I(description), I(ttl) and I(masters) values
|
||||
can be updated.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Zone name
|
||||
required: true
|
||||
zone_type:
|
||||
description:
|
||||
- Zone type
|
||||
choices: [primary, secondary]
|
||||
default: None
|
||||
email:
|
||||
description:
|
||||
- Email of the zone owner (only applies if zone_type is primary)
|
||||
required: false
|
||||
description:
|
||||
description:
|
||||
- Zone description
|
||||
required: false
|
||||
default: None
|
||||
ttl:
|
||||
description:
|
||||
- TTL (Time To Live) value in seconds
|
||||
required: false
|
||||
default: None
|
||||
masters:
|
||||
description:
|
||||
- Master nameservers (only applies if zone_type is secondary)
|
||||
required: false
|
||||
default: None
|
||||
state:
|
||||
description:
|
||||
- Should the resource be present or absent.
|
||||
choices: [present, absent]
|
||||
default: present
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "shade"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a zone named "example.net"
|
||||
- os_zone:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: example.net.
|
||||
zone_type: primary
|
||||
email: test@example.net
|
||||
description: Test zone
|
||||
ttl: 3600
|
||||
|
||||
# Update the TTL on existing "example.net." zone
|
||||
- os_zone:
|
||||
cloud: mycloud
|
||||
state: present
|
||||
name: example.net.
|
||||
ttl: 7200
|
||||
|
||||
# Delete zone named "example.net."
|
||||
- os_zone:
|
||||
cloud: mycloud
|
||||
state: absent
|
||||
name: example.net.
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
zone:
|
||||
description: Dictionary describing the zone.
|
||||
returned: On success when I(state) is 'present'.
|
||||
type: dictionary
|
||||
contains:
|
||||
id:
|
||||
description: Unique zone ID
|
||||
type: string
|
||||
sample: "c1c530a3-3619-46f3-b0f6-236927b2618c"
|
||||
name:
|
||||
description: Zone name
|
||||
type: string
|
||||
sample: "example.net."
|
||||
type:
|
||||
description: Zone type
|
||||
type: string
|
||||
sample: "PRIMARY"
|
||||
email:
|
||||
description: Zone owner email
|
||||
type: string
|
||||
sample: "test@example.net"
|
||||
description:
|
||||
description: Zone description
|
||||
type: string
|
||||
sample: "Test description"
|
||||
ttl:
|
||||
description: Zone TTL value
|
||||
type: int
|
||||
sample: 3600
|
||||
masters:
|
||||
description: Zone master nameservers
|
||||
type: list
|
||||
sample: []
|
||||
'''
|
||||
|
||||
|
||||
def _system_state_change(state, email, description, ttl, masters, zone):
|
||||
if state == 'present':
|
||||
if not zone:
|
||||
return True
|
||||
if email is not None and zone.email != email:
|
||||
return True
|
||||
if description is not None and zone.description != description:
|
||||
return True
|
||||
if ttl is not None and zone.ttl != ttl:
|
||||
return True
|
||||
if masters is not None and zone.masters != masters:
|
||||
return True
|
||||
if state == 'absent' and zone:
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_full_argument_spec(
|
||||
name=dict(required=True),
|
||||
zone_type=dict(required=False, choice=['primary', 'secondary']),
|
||||
email=dict(required=False, default=None),
|
||||
description=dict(required=False, default=None),
|
||||
ttl=dict(required=False, default=None, type='int'),
|
||||
masters=dict(required=False, default=None, type='list'),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
)
|
||||
|
||||
module_kwargs = openstack_module_kwargs()
|
||||
module = AnsibleModule(argument_spec,
|
||||
supports_check_mode=True,
|
||||
**module_kwargs)
|
||||
|
||||
if not HAS_SHADE:
|
||||
module.fail_json(msg='shade is required for this module')
|
||||
if StrictVersion(shade.__version__) < StrictVersion('1.8.0'):
|
||||
module.fail_json(msg="To utilize this module, the installed version of"
|
||||
"the shade library MUST be >=1.8.0")
|
||||
|
||||
name = module.params.get('name')
|
||||
state = module.params.get('state')
|
||||
|
||||
try:
|
||||
cloud = shade.openstack_cloud(**module.params)
|
||||
zone = cloud.get_zone(name)
|
||||
|
||||
|
||||
if state == 'present':
|
||||
zone_type = module.params.get('zone_type')
|
||||
email = module.params.get('email')
|
||||
description = module.params.get('description')
|
||||
ttl = module.params.get('ttl')
|
||||
masters = module.params.get('masters')
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state, email,
|
||||
description, ttl,
|
||||
masters, zone))
|
||||
|
||||
if zone is None:
|
||||
zone = cloud.create_zone(
|
||||
name=name, zone_type=zone_type, email=email,
|
||||
description=description, ttl=ttl, masters=masters)
|
||||
changed = True
|
||||
else:
|
||||
if masters is None:
|
||||
masters = []
|
||||
|
||||
pre_update_zone = zone
|
||||
changed = _system_state_change(state, email,
|
||||
description, ttl,
|
||||
masters, pre_update_zone)
|
||||
if changed:
|
||||
zone = cloud.update_zone(
|
||||
name, email=email,
|
||||
description=description,
|
||||
ttl=ttl, masters=masters)
|
||||
module.exit_json(changed=changed, zone=zone)
|
||||
|
||||
elif state == 'absent':
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=_system_state_change(state, None,
|
||||
None, None,
|
||||
None, zone))
|
||||
|
||||
if zone is None:
|
||||
changed=False
|
||||
else:
|
||||
cloud.delete_zone(name)
|
||||
changed=True
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
except shade.OpenStackCloudException as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.openstack import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue