Support automation account managment (#56429)

* add automation account

* add test

* update sdk version

* fix doc

* Update azure_rm_automationaccount.py

* Update azure_rm_automationaccount_facts.py

* Update main.yml

* add type define (#64)

* add new (#67)

* change 'example' to 'sample'

* changed 'path' to 'ID'
This commit is contained in:
Yuwei Zhou 2019-08-27 07:38:47 +08:00 committed by Zim Kalinowski
parent ab559c4629
commit 1c06b302bc
8 changed files with 662 additions and 0 deletions

View file

@ -170,6 +170,8 @@ try:
from azure.mgmt.containerinstance import ContainerInstanceManagementClient from azure.mgmt.containerinstance import ContainerInstanceManagementClient
from azure.mgmt.loganalytics import LogAnalyticsManagementClient from azure.mgmt.loganalytics import LogAnalyticsManagementClient
import azure.mgmt.loganalytics.models as LogAnalyticsModels import azure.mgmt.loganalytics.models as LogAnalyticsModels
from azure.mgmt.automation import AutomationClient
import azure.mgmt.automation.models as AutomationModel
except ImportError as exc: except ImportError as exc:
HAS_AZURE_EXC = traceback.format_exc() HAS_AZURE_EXC = traceback.format_exc()
HAS_AZURE = False HAS_AZURE = False
@ -308,6 +310,7 @@ class AzureRMModuleBase(object):
self._resource = None self._resource = None
self._log_analytics_client = None self._log_analytics_client = None
self._servicebus_client = None self._servicebus_client = None
self._automation_client = None
self.check_mode = self.module.check_mode self.check_mode = self.module.check_mode
self.api_profile = self.module.params.get('api_profile') self.api_profile = self.module.params.get('api_profile')
@ -1005,6 +1008,18 @@ class AzureRMModuleBase(object):
def servicebus_models(self): def servicebus_models(self):
return ServicebusModel return ServicebusModel
@property
def automation_client(self):
self.log('Getting automation client')
if not self._automation_client:
self._automation_client = self.get_mgmt_svc_client(AutomationClient,
base_url=self._cloud_environment.endpoints.resource_manager)
return self._automation_client
@property
def automation_models(self):
return AutomationModel
class AzureRMAuthException(Exception): class AzureRMAuthException(Exception):
pass pass

View file

@ -0,0 +1,174 @@
#!/usr/bin/python
#
# Copyright (c) 2017 Yuwei Zhou, <yuwzho@microsoft.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: azure_rm_automationaccount
version_added: "2.9"
short_description: Manage Azure Automation account
description:
- Create, delete an Azure Automation account.
options:
resource_group:
description:
- Name of resource group.
type: str
required: true
name:
description:
- Name of the automation account.
type: str
required: true
state:
description:
- State of the automation account. Use C(present) to create or update a automation account and C(absent) to delete an automation account.
type: str
default: present
choices:
- absent
- present
location:
description:
- Location of the resource.
- If not specified, use resource group location.
type: str
extends_documentation_fragment:
- azure
- azure_tags
author:
- Yuwei Zhou (@yuwzho)
'''
EXAMPLES = '''
- name: Create an automation account
azure_rm_automationaccount:
name: Testing
resource_group: myResourceGroup
- name: Create an automation account
azure_rm_automationaccount:
name: Testing
resource_group: myResourceGroup
location: eastus
'''
RETURN = '''
id:
description:
- Automation account resource ID.
type: str
returned: success
sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Automation/automationAccounts/Testing"
''' # NOQA
from ansible.module_utils.azure_rm_common import AzureRMModuleBase
class AzureRMAutomationAccount(AzureRMModuleBase):
def __init__(self):
self.module_arg_spec = dict(
resource_group=dict(type='str', required=True),
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent']),
location=dict(type='str')
)
self.results = dict(
changed=False,
id=None
)
self.resource_group = None
self.name = None
self.state = None
self.location = None
super(AzureRMAutomationAccount, self).__init__(self.module_arg_spec, supports_check_mode=True)
def exec_module(self, **kwargs):
for key in list(self.module_arg_spec.keys()) + ['tags']:
setattr(self, key, kwargs[key])
account = self.get_account()
changed = False
if self.state == 'present':
if not account:
if not self.location:
resource_group = self.get_resource_group(self.resource_group)
self.location = resource_group.location
param = self.automation_models.AutomationAccountCreateOrUpdateParameters(
location=self.location,
sku=self.automation_models.Sku(name='Basic'),
tags=self.tags
)
changed = True
if not self.check_mode:
account = self.create_or_update(param)
elif self.tags:
update_tags, tags = self.update_tags(account.tags)
if update_tags:
changed = True
param = self.automation_models.AutomationAccountUpdateParameters(
tags=tags
)
changed = True
if not self.check_mode:
self.update_account_tags(param)
if account:
self.results['id'] = account.id
elif account:
changed = True
if not self.check_mode:
self.delete_account()
self.results['changed'] = changed
return self.results
def get_account(self):
try:
return self.automation_client.automation_account.get(self.resource_group, self.name)
except self.automation_models.ErrorResponseException:
pass
def create_or_update(self, param):
try:
return self.automation_client.automation_account.create_or_update(self.resource_group, self.name, param)
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when creating automation account {0}: {1}'.format(self.name, exc.message))
def update_account_tags(self, param):
try:
return self.automation_client.automation_account.update(self.resource_group, self.name, param)
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when updating automation account {0}: {1}'.format(self.name, exc.message))
def delete_account(self):
try:
return self.automation_client.automation_account.delete(self.resource_group, self.name)
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when deleting automation account {0}: {1}'.format(self.name, exc.message))
def main():
AzureRMAutomationAccount()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,377 @@
#!/usr/bin/python
#
# Copyright (c) 2017 Yuwei Zhou, <yuwzho@microsoft.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: azure_rm_automationaccount_facts
version_added: '2.9'
short_description: Get Azure automation account facts
description:
- Get facts of automation account.
options:
resource_group:
description:
- The name of the resource group.
type: str
required: True
name:
description:
- The name of the automation account.
type: str
tags:
description:
- Limit results by providing a list of tags. Format tags as 'key' or 'key:value'.
type: list
list_statistics:
description:
- List statistics details for a automation account.
- Note this will cost network overhead, suggest only used when I(name) set.
type: bool
list_usages:
description:
- List usage details for a automation account.
- Note this will cost network overhead, suggest only used when I(name) set.
type: bool
list_keys:
description:
- List keys for a automation account.
- Note this will cost network overhead, suggest only used when I(name) set.
type: bool
extends_documentation_fragment:
- azure
author:
- Yuwei Zhou (@yuwzho)
'''
EXAMPLES = '''
- name: Get details of an automation account
azure_rm_automationaccount_facts:
name: Testing
resource_group: myResourceGroup
list_statistics: yes
list_usages: yes
list_keys: yes
- name: List automation account in a resource group
azure_rm_automationaccount_facts:
resource_group: myResourceGroup
- name: List automation account in a resource group
azure_rm_automationaccount_facts:
'''
RETURN = '''
automation_accounts:
description:
- List of automation account dicts.
returned: always
type: complex
contains:
id:
description:
- Resource ID.
type: str
returned: always
sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups
/myResourceGroup/providers/Microsoft.Automation/automationAccounts/Testing"
resource_group:
description:
- Resource group name.
type: str
returned: always
sample: myResourceGroup
name:
description:
- Resource name.
type: str
returned: always
sample: Testing
location:
description:
- Resource location.
type: str
returned: always
sample: eastus
creation_time:
description:
- Resource creation date time.
type: str
returned: always
sample: "2019-04-26T02:55:16.500Z"
last_modified_time:
description:
- Resource last modified date time.
type: str
returned: always
sample: "2019-04-26T02:55:16.500Z"
state:
description:
- Resource state.
type: str
returned: always
sample: ok
keys:
description:
- Resource keys.
type: complex
returned: always
contains:
key_name:
description:
- Name of the key.
type: str
returned: always
sample: Primary
permissions:
description:
- Permission of the key.
type: str
returned: always
sample: Full
value:
description:
- Value of the key.
type: str
returned: always
sample: "MbepKTO6IyGwml0GaKBkKN"
statistics:
description:
- Resource statistics.
type: complex
returned: always
contains:
counter_property:
description:
- Property value of the statistic.
type: str
returned: always
sample: New
counter_value:
description:
- Value of the statistic.
type: int
returned: always
sample: 0
end_time:
description:
- EndTime of the statistic.
type: str
returned: always
sample: "2019-04-26T06:29:43.587518Z"
id:
description:
- ID of the statistic.
type: str
returned: always
sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups
/myResourceGroup/providers/Microsoft.Automation/automationAccounts/Testing/statistics/New"
start_time:
description:
- StartTime of the statistic.
type: str
returned: always
sample: "2019-04-26T06:29:43.587518Z"
usages:
description:
- Resource usages.
type: complex
returned: always
contains:
current_value:
description:
- Current usage.
type: float
returned: always
sample: 0.0
limit:
description:
- Max limit, C(-1) for unlimited.
type: long
returned: always
sample: -1
name:
description:
- Usage counter name.
type: complex
returned: always
contains:
localized_value:
description:
- Localized name.
type: str
returned: always
sample: "SubscriptionUsage"
value:
description:
- Name value.
type: str
returned: always
sample: "SubscriptionUsage"
unit:
description:
- Usage unit name.
type: str
returned: always
sample: "Minute"
throttle_status:
description:
- Usage throttle status.
type: str
returned: always
sample: "NotThrottled"
'''
from ansible.module_utils.azure_rm_common import AzureRMModuleBase
try:
from msrestazure.tools import parse_resource_id
except ImportError:
pass
class AzureRMAutomationAccountFacts(AzureRMModuleBase):
def __init__(self):
# define user inputs into argument
self.module_arg_spec = dict(
resource_group=dict(
type='str',
required=True
),
name=dict(
type='str'
),
tags=dict(
type='list'
),
list_statistics=dict(
type='bool'
),
list_usages=dict(
type='bool'
),
list_keys=dict(
type='bool'
)
)
# store the results of the module operation
self.results = dict()
self.resource_group = None
self.name = None
self.tags = None
self.list_statistics = None
self.list_usages = None
self.list_keys = None
super(AzureRMAutomationAccountFacts, self).__init__(self.module_arg_spec, supports_tags=False, facts_module=True)
def exec_module(self, **kwargs):
for key in list(self.module_arg_spec):
setattr(self, key, kwargs[key])
if self.resource_group and self.name:
accounts = [self.get()]
elif self.resource_group:
accounts = self.list_by_resource_group()
else:
accounts = self.list_all()
self.results['automation_accounts'] = [self.to_dict(x) for x in accounts if self.has_tags(x.tags, self.tags)]
return self.results
def to_dict(self, account):
if not account:
return None
id_dict = parse_resource_id(account.id)
result = account.as_dict()
result['resource_group'] = id_dict['resource_group']
if self.list_statistics:
result['statistics'] = self.get_statics(id_dict['resource_group'], account.name)
if self.list_usages:
result['usages'] = self.get_usages(id_dict['resource_group'], account.name)
if self.list_keys:
result['keys'] = self.list_account_keys(id_dict['resource_group'], account.name)
return result
def get(self):
try:
return self.automation_client.automation_account.get(self.resource_group, self.name)
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when getting automation account {0}: {1}'.format(self.name, exc.message))
def list_by_resource_group(self):
result = []
try:
resp = self.automation_client.automation_account.list_by_resource_group(self.resource_group)
while True:
result.append(resp.next())
except StopIteration:
pass
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when listing automation account in resource group {0}: {1}'.format(self.resource_group, exc.message))
return result
def list_all(self):
result = []
try:
resp = self.automation_client.automation_account.list()
while True:
result.append(resp.next())
except StopIteration:
pass
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when listing automation account: {0}'.format(exc.message))
return result
def get_statics(self, resource_group, name):
result = []
try:
resp = self.automation_client.statistics.list_by_automation_account(resource_group, name)
while True:
result.append(resp.next().as_dict())
except StopIteration:
pass
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when getting statics for automation account {0}/{1}: {2}'.format(resource_group, name, exc.message))
return result
def get_usages(self, resource_group, name):
result = []
try:
resp = self.automation_client.usages.list_by_automation_account(resource_group, name)
while True:
result.append(resp.next().as_dict())
except StopIteration:
pass
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when getting usage for automation account {0}/{1}: {2}'.format(resource_group, name, exc.message))
return result
def list_account_keys(self, resource_group, name):
try:
resp = self.automation_client.keys.list_by_automation_account(resource_group, name)
return [x.as_dict() for x in resp.keys]
except self.automation_models.ErrorResponseException as exc:
self.fail('Error when listing keys for automation account {0}/{1}: {2}'.format(resource_group, name, exc.message))
def main():
AzureRMAutomationAccountFacts()
if __name__ == '__main__':
main()

View file

@ -35,3 +35,4 @@ azure-mgmt-cosmosdb==0.5.2
azure-mgmt-hdinsight==0.1.0 azure-mgmt-hdinsight==0.1.0
azure-mgmt-devtestlabs==3.0.0 azure-mgmt-devtestlabs==3.0.0
azure-mgmt-loganalytics==0.2.0 azure-mgmt-loganalytics==0.2.0
azure-mgmt-automation==0.1.1

View file

@ -0,0 +1,4 @@
cloud/azure
shippable/azure/group4
destructive
azure_rm_automationaccount_facts

View file

@ -0,0 +1,2 @@
dependencies:
- setup_azure

View file

@ -0,0 +1,88 @@
- name: Prepare random number
set_fact:
rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
name: "account{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
run_once: yes
- name: Create automation account
azure_rm_automationaccount:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
check_mode: yes
register: output
- assert:
that:
- output.changed
- name: Create automation account
azure_rm_automationaccount:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
register: output
- assert:
that:
- output.changed
- output.id
- name: Create automation account
azure_rm_automationaccount:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
register: output
- assert:
that:
- not output.changed
- name: Get automation account
azure_rm_automationaccount_facts:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
list_statistics: yes
list_usages: yes
list_keys: yes
register: facts
- assert:
that:
- facts.automation_accounts | length == 1
- facts.automation_accounts[0].keys
- facts.automation_accounts[0].usages
- facts.automation_accounts[0].statistics
- facts.automation_accounts[0].state == "Ok"
- name: Delete account
azure_rm_automationaccount:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
state: absent
check_mode: yes
register: output
- assert:
that:
- output.changed
- name: Delete account
azure_rm_automationaccount:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
state: absent
register: output
- assert:
that:
- output.changed
- name: Delete account
azure_rm_automationaccount:
name: "{{ name }}"
resource_group: "{{ resource_group }}"
state: absent
register: output
- assert:
that:
- not output.changed

View file

@ -35,3 +35,4 @@ azure-mgmt-cosmosdb==0.5.2
azure-mgmt-hdinsight==0.1.0 azure-mgmt-hdinsight==0.1.0
azure-mgmt-devtestlabs==3.0.0 azure-mgmt-devtestlabs==3.0.0
azure-mgmt-loganalytics==0.2.0 azure-mgmt-loganalytics==0.2.0
azure-mgmt-automation==0.1.1