Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure rm subscription info #2

Merged
merged 10 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions plugins/module_utils/azure_rm_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def default_api_version(self):
'NetworkManagementClient': '2019-06-01',
'ResourceManagementClient': '2017-05-10',
'StorageManagementClient': '2019-06-01',
'SubscriptionClient': '2019-11-01',
'WebSiteManagementClient': '2018-02-01',
'PostgreSQLManagementClient': '2017-12-01',
'MySQLManagementClient': '2017-12-01',
Expand Down Expand Up @@ -397,6 +398,7 @@ def __init__(self, derived_arg_spec, bypass_checks=False, no_log=False,

self._network_client = None
self._storage_client = None
self._subscription_client = None
self._resource_client = None
self._compute_client = None
self._dns_client = None
Expand Down Expand Up @@ -842,7 +844,7 @@ def get_graphrbac_client(self, tenant_id):

return client

def get_mgmt_svc_client(self, client_type, base_url=None, api_version=None):
def get_mgmt_svc_client(self, client_type, base_url=None, api_version=None, suppress_subscription_id=False):
self.log('Getting management service client {0}'.format(client_type.__name__))
self.check_client_version(client_type)

Expand All @@ -852,7 +854,11 @@ def get_mgmt_svc_client(self, client_type, base_url=None, api_version=None):
# most things are resource_manager, don't make everyone specify
base_url = self.azure_auth._cloud_environment.endpoints.resource_manager

client_kwargs = dict(credentials=self.azure_auth.azure_credentials, subscription_id=self.azure_auth.subscription_id, base_url=base_url)
# Some management clients do not take a subscription ID as parameters.
if suppress_subscription_id:
client_kwargs = dict(credentials=self.azure_auth.azure_credentials, base_url=base_url)
else:
client_kwargs = dict(credentials=self.azure_auth.azure_credentials, subscription_id=self.azure_auth.subscription_id, base_url=base_url)

api_profile_dict = {}

Expand Down Expand Up @@ -955,6 +961,20 @@ def storage_client(self):
def storage_models(self):
return StorageManagementClient.models("2019-06-01")

@property
def subscription_client(self):
self.log('Getting subscription client...')
if not self._subscription_client:
self._subscription_client = self.get_mgmt_svc_client(SubscriptionClient,
base_url=self._cloud_environment.endpoints.resource_manager,
suppress_subscription_id=True,
api_version='2019-11-01')
return self._subscription_client

@property
def subscription_models(self):
return SubscriptionClient.models("2019-11-01")

@property
def network_client(self):
self.log('Getting network client')
Expand Down
203 changes: 203 additions & 0 deletions plugins/modules/azure_rm_subscription_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
#!/usr/bin/python
#
# Copyright (c) 2020 Paul Aiton, < @paultaiton >
#
# 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_subscription_info

version_added: "1.2.0"

short_description: Get Azure Subscription facts

description:
- Get facts for a specific subscription or all subscriptions.

options:
id:
description:
- Limit results to a specific subscription by id.
- Cannot be used together with name.
name:
description:
- Limit results to a specific subscription by name.
- Cannot be used together with id.
aliases:
- subscription_name
all:
description:
- If true, will return all subscriptions.
- If false will omit disabled subscriptions (default).
- Option has no effect when searching by id or name.
default: False

extends_documentation_fragment:
- azure.azcollection.azure

author:
- Paul Aiton ( @paultaiton )
'''

EXAMPLES = '''
- name: Get facts for one subscription by id
azure_rm_subscription_info:
id: 00000000-0000-0000-0000-000000000000

- name: Get facts for one subscription by name
azure_rm_subscription_info:
name: "my-subscription"

- name: Get facts for all subscriptions, including ones that are disabled.
azure_rm_subscription_info:
all: True
'''

RETURN = '''
subscriptions:
description:
- List of subscription dicts.
returned: always
type: list
contains:
display_name:
description: Subscription display name.
returned: always
type: str
sample: my-subscription
fqid:
description: Subscription fully qualified id.
returned: always
type: str
sample: "/subscriptions/00000000-0000-0000-0000-000000000000"
subscription_id:
description: Subscription guid.
returned: always
type: str
sample: "00000000-0000-0000-0000-000000000000"
state:
description: Subscription state.
returned: always
type: str
sample: "'Enabled' or 'Disabled'"
tags:
description: Tags assigned to resource group.
returned: always
type: dict
sample: { "tag1": "value1", "tag2": "value2" }
tenant_id:
description: Subscription tenant id
returned: always
type: str
sample: "00000000-0000-0000-0000-000000000000"
'''

try:
from msrestazure.azure_exceptions import CloudError
except Exception:
# This is handled in azure_rm_common
pass

from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase


AZURE_OBJECT_CLASS = 'Subscription'


class AzureRMSubscriptionInfo(AzureRMModuleBase):

def __init__(self):

self.module_arg_spec = dict(
name=dict(type='str'),
id=dict(type='str'),
all=dict(type='bool')
)

self.results = dict(
changed=False,
subscriptions=[]
)

self.name = None
self.id = None
self.all = False

super(AzureRMSubscriptionInfo, self).__init__(self.module_arg_spec,
supports_tags=False,
facts_module=True)

def exec_module(self, **kwargs):
for key in self.module_arg_spec:
setattr(self, key, kwargs[key])

if self.id and self.name:
self.fail("Parameter error: cannot search subscriptions by both name and id.")

result = []

if self.id:
result = self.get_item()
else:
result = self.list_items()

self.results['subscriptions'] = result
return self.results

def get_item(self):
self.log('Get properties for {0}'.format(self.id))
item = None
result = []

try:
item = self.subscription_client.subscriptions.get(self.id)
except CloudError:
pass

result = self.to_dict(item)

return result

def list_items(self):
self.log('List all items')
try:
response = self.subscription_client.subscriptions.list()
except CloudError as exc:
self.fail("Failed to list all items - {0}".format(str(exc)))

results = []
for item in response:
# If the name matches, return result regardless of anything else.
# If name is not defined and either state is Enabled or all is true, return result.
if ( self.name and self.name.lower() == item.display_name.lower() ):
results.append(self.to_dict(item) )
elif ( not self.name and ( self.all or item.state == "Enabled" ) ):
results.append(self.to_dict(item) )

return results

def to_dict(self, subscription_object):
return dict(
display_name=subscription_object.display_name,
fqid=subscription_object.id,
state=subscription_object.state,
subscription_id=subscription_object.subscription_id,
tags=subscription_object.tags,
tenant_id=subscription_object.tenant_id
)

def main():
AzureRMSubscriptionInfo()

if __name__ == '__main__':
main()
5 changes: 5 additions & 0 deletions tests/integration/targets/azure_rm_subscription/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Paul Aiton's note for pull request:
# I don't know what this file does, will someone who does please review for correctness?
cloud/azure
shippable/azure/group2
destructive
2 changes: 2 additions & 0 deletions tests/integration/targets/azure_rm_subscription/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dependencies:
- setup_azure
24 changes: 24 additions & 0 deletions tests/integration/targets/azure_rm_subscription/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
- name: Get list of all subscriptions
azure.azcollection.azure_rm_subscription_info:
all: True
register: az_all_subscriptions

- name: Get a subscription by id
azure.azcollection.azure_rm_subscription_info:
id: "{{ az_all_subscriptions.subscriptions[0].subscription_id }}"

- name: Get a subscription by name
azure.azcollection.azure_rm_subscription_info:
name: "{{ az_all_subscriptions.subscriptions[0].display_name }}"

- name: Test invalid name id combo
azure.azcollection.azure_rm_subscription_info:
name: "{{ az_all_subscriptions.subscriptions[0].display_name }}"
id: "{{ az_all_subscriptions.subscriptions[0].subscription_id }}"
register: invalid_name
ignore_errors: yes

- name: Assert task failed
assert:
that:
- "invalid_name['failed'] == True"