ansible/cloud/azure/azure_rm_resourcegroup.py

276 lines
9.2 KiB
Python
Raw Normal View History

#!/usr/bin/python
#
# Copyright (c) 2016 Matt Davis, <mdavis@ansible.com>
# Chris Houseknecht, <house@redhat.com>
#
# This file is part of Ansible
#
# Ansible 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.
#
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>.
#
DOCUMENTATION = '''
---
module: azure_rm_resourcegroup
version_added: "2.1"
short_description: Manage Azure resource groups.
description:
- Create, update and delete a resource group.
options:
force:
description:
- Remove a resource group and all associated resources. Use with state 'absent' to delete a resource
group that contains resources.
default: false
required: false
location:
description:
- Azure location for the resource group. Required when creating a new resource group. Cannot
be changed once resource group is created.
required: false
default: null
name:
description:
- Name of the resource group.
required: true
state:
description:
- Assert the state of the resource group. Use 'present' to create or update and
'absent' to delete. When 'absent' a resource group containing resources will not be removed unless the
force option is used.
default: present
choices:
- absent
- present
required: false
tags:
description:
- "Dictionary of string:string pairs to assign as metadata to the object. Metadata tags on the object
will be updated with any provided values. To remove tags use the purge_tags option."
required: false
default: null
purge_tags:
description:
- Use to remove tags from an object. Any tags not found in the tags parameter will be removed from
the object's metadata.
default: false
required: false
extends_documentation_fragment:
- azure
author:
- "Chris Houseknecht (@chouseknecht)"
- "Matt Davis (@nitzmahone)"
'''
EXAMPLES = '''
- name: Create a resource group
azure_rm_resourcegroup:
name: Testing
location: westus
tags:
testing: testing
delete: never
- name: Delete a resource group
azure_rm_resourcegroup:
name: Testing
state: absent
'''
RETURN = '''
contains_resources:
description: Whether or not the resource group contains associated resources.
type: bool
sample: True
state:
2016-04-25 15:43:12 +02:00
description: Current state of the resource group.
returned: always
type: dict
sample: {
"id": "/subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX/resourceGroups/Testing",
"location": "westus",
"name": "Testing",
"provisioning_state": "Succeeded",
"tags": {
"delete": "on-exit",
"testing": "no"
}
}
'''
from ansible.module_utils.basic import *
from ansible.module_utils.azure_rm_common import *
try:
from msrestazure.azure_exceptions import CloudError
from azure.common import AzureMissingResourceHttpError
from azure.mgmt.resource.resources.models import ResourceGroup
except ImportError:
pass
def resource_group_to_dict(rg):
return dict(
id=rg.id,
name=rg.name,
location=rg.location,
tags=rg.tags,
provisioning_state=rg.properties.provisioning_state
)
class AzureRMResourceGroup(AzureRMModuleBase):
2016-04-25 15:43:12 +02:00
def __init__(self):
self.module_arg_spec = dict(
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent']),
location=dict(type='str'),
force=dict(type='bool', default=False)
)
self.name = None
self.state = None
self.location = None
self.tags = None
self.force = None
self.results = dict(
changed=False,
contains_resources=False,
state=dict(),
)
super(AzureRMResourceGroup, self).__init__(self.module_arg_spec,
supports_check_mode=True,
supports_tags=True)
def exec_module(self, **kwargs):
for key in self.module_arg_spec.keys() + ['tags']:
setattr(self, key, kwargs[key])
results = dict()
changed = False
rg = None
contains_resources = False
try:
self.log('Fetching resource group {0}'.format(self.name))
rg = self.rm_client.resource_groups.get(self.name)
self.check_provisioning_state(rg, self.state)
contains_resources = self.resources_exist()
results = resource_group_to_dict(rg)
if self.state == 'absent':
self.log("CHANGED: resource group {0} exists but requested state is 'absent'".format(self.name))
changed = True
elif self.state == 'present':
update_tags, results['tags'] = self.update_tags(results['tags'])
if update_tags:
changed = True
if self.location and self.location != results['location']:
self.fail("Resource group '{0}' already exists in location '{1}' and cannot be "
"moved.".format(self.name, results['location']))
except CloudError:
self.log('Resource group {0} does not exist'.format(self.name))
if self.state == 'present':
self.log("CHANGED: resource group {0} does not exist but requested state is "
"'present'".format(self.name))
changed = True
self.results['changed'] = changed
self.results['state'] = results
self.results['contains_resources'] = contains_resources
if self.check_mode:
return self.results
if changed:
if self.state == 'present':
if not rg:
# Create resource group
self.log("Creating resource group {0}".format(self.name))
if not self.location:
self.fail("Parameter error: location is required when creating a resource "
"group.".format(self.name))
if self.name_exists():
self.fail("Error: a resource group with the name {0} already exists in your subscription."
.format(self.name))
params = ResourceGroup(
location=self.location,
tags=self.tags
)
else:
# Update resource group
params = ResourceGroup(
location=results['location'],
tags=results['tags']
)
self.results['state'] = self.create_or_update_resource_group(params)
elif self.state == 'absent':
if contains_resources and not self.force:
self.fail("Error removing resource group {0}. Resources exist within the group.".format(self.name))
self.delete_resource_group()
return self.results
def create_or_update_resource_group(self, params):
try:
result = self.rm_client.resource_groups.create_or_update(self.name, params)
except Exception as exc:
self.fail("Error creating or updating resource group {0} - {1}".format(self.name, str(exc)))
return resource_group_to_dict(result)
def delete_resource_group(self):
try:
poller = self.rm_client.resource_groups.delete(self.name)
self.get_poller_result(poller)
except Exception as exc:
self.fail("Error delete resource group {0} - {1}".format(self.name, str(exc)))
# The delete operation doesn't return anything.
# If we got here, assume all is good
self.results['state']['status'] = 'Deleted'
return True
def resources_exist(self):
found = False
try:
response = self.rm_client.resource_groups.list_resources(self.name)
except Exception as exc:
self.fail("Error checking for resource existence in {0} - {1}".format(self.name, str(exc)))
for item in response:
found = True
break
return found
def name_exists(self):
try:
exists = self.rm_client.resource_groups.check_existence(self.name)
except Exception as exc:
self.fail("Error checking for existence of name {0} - {1}".format(self.name, str(exc)))
return exists
def main():
AzureRMResourceGroup()
if __name__ == '__main__':
main()