diff --git a/plugins/modules/azure_rm_registrationassignment.py b/plugins/modules/azure_rm_registrationassignment.py new file mode 100644 index 000000000..f60cd57ed --- /dev/null +++ b/plugins/modules/azure_rm_registrationassignment.py @@ -0,0 +1,279 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# 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_registrationassignment +version_added: '1.3.0' +short_description: Manage Azure RegistrationAssignment instance +description: + - Create and delete instance of Azure RegistrationAssignment. +options: + scope: + description: + - Scope of the registration assignment. Can be in subscription or group level. + required: true + type: str + registration_assignment_id: + description: + - ID of the registration assignment. + - If is not specified, an UUID will be generated for it. + type: str + properties: + description: + - Properties of a registration assignment. + type: dict + suboptions: + registration_definition_id: + description: + - Fully qualified path of the registration definition. + required: true + type: str + state: + description: + - Assert the state of the RegistrationAssignment. + - Use C(present) to create or update an RegistrationAssignment and C(absent) to delete it. + default: present + type: str + choices: + - absent + - present +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) + +''' + +EXAMPLES = ''' + - name: Delete Registration Assignment + azure_rm_registrationassignment: + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + state: absent + + + - name: Create Registration Assignment in subscription level + azure_rm_registrationassignment: + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + properties: + registration_definition_id: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx + + + - name: Create Registration Assignment in resourcegroup level with randomly generating registration_assignment_id + azure_rm_registrationassignment: + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup + properties: + registration_definition_id: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx + +''' + +RETURN = ''' +state: + description: + - The state info of the registration assignment. + type: complex + returned: always + contains: + properties: + description: + - Properties of a registration assignment. + returned: always + type: complex + contains: + registration_definition_id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: null + id: + description: + - The fully qualified path of the registration assignment. + returned: always + type: str + sample: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationAssignments/xxx-xxx + type: + description: + - Type of the resource. + returned: always + type: str + sample: Microsoft.ManagedServices/registrationAssignments + name: + description: + - Name of the registration assignment. + returned: always + type: str + sample: 9b2895ec-fb1e-4a1e-a978-abd9933d6b20 + +''' +import uuid +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMRegistrationAssignment(AzureRMModuleBaseExt): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str', + required=True + ), + registration_assignment_id=dict( + type='str', + ), + properties=dict( + type='dict', + disposition='/properties', + options=dict( + registration_definition_id=dict( + type='str', + disposition='registration_definition_id', + required=True + ) + ) + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.scope = None + self.registration_assignment_id = None + self.expand_registration_definition = False + self.body = {} + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMRegistrationAssignment, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=True) + + def exec_module(self, **kwargs): + for key in list(self.module_arg_spec.keys()): + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.body[key] = kwargs[key] + + self.inflate_parameters(self.module_arg_spec, self.body, 0) + + old_response = None + response = None + if self.registration_assignment_id is None: + self.registration_assignment_id = str(uuid.uuid4()) + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2019-09-01', + suppress_subscription_id=True) + + old_response = self.get_resource() + + if not old_response: + if self.state == 'present': + self.to_do = Actions.Create + else: + if self.state == 'absent': + self.to_do = Actions.Delete + else: + modifiers = {} + self.create_compare_modifiers(self.module_arg_spec, '', modifiers) + self.results['modifiers'] = modifiers + self.results['compare'] = [] + if not self.default_compare(modifiers, self.body, old_response, '', self.results): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.results['changed'] = True + if self.check_mode: + return self.results + response = self.create_update_resource() + self.results['state'] = response + elif self.to_do == Actions.Delete: + self.results['changed'] = True + if self.check_mode: + return self.results + self.delete_resource() + else: + self.results['changed'] = False + response = old_response + self.results['state'] = response + + if self.state is 'present': + if self.results['state'].get('properties', None) is not None: + registration_definition_id = self.results['state']['properties']['registration_definition_id'] + self.results['state']['properties'].clear() + self.results['state']['properties']['registration_definition_id'] = registration_definition_id + + return self.results + + def create_update_resource(self): + try: + response = self.mgmt_client.registration_assignments.create_or_update(scope=self.scope, + registration_assignment_id=self.registration_assignment_id, + properties=self.body.get('properties', None), + request_body=self.body) + if isinstance(response, AzureOperationPoller) or isinstance(response, LROPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the RegistrationAssignment instance.') + self.fail('Error creating the RegistrationAssignment instance: {0}'.format(str(exc))) + return response.as_dict() + + def delete_resource(self): + try: + response = self.mgmt_client.registration_assignments.delete(scope=self.scope, + registration_assignment_id=self.registration_assignment_id) + except CloudError as e: + self.log('Error attempting to delete the RegistrationAssignment instance.') + self.fail('Error deleting the RegistrationAssignment instance: {0}'.format(str(e))) + + return True + + def get_resource(self): + try: + response = self.mgmt_client.registration_assignments.get(scope=self.scope, + registration_assignment_id=self.registration_assignment_id, + expand_registration_definition=self.expand_registration_definition) + except Exception as e: + return False + return response.as_dict() + + +def main(): + AzureRMRegistrationAssignment() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_registrationassignment_info.py b/plugins/modules/azure_rm_registrationassignment_info.py new file mode 100644 index 000000000..0c6b1af4b --- /dev/null +++ b/plugins/modules/azure_rm_registrationassignment_info.py @@ -0,0 +1,193 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# 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_registrationassignment_info +version_added: '1.3.0' +short_description: Get RegistrationAssignment info +description: + - Get info of RegistrationAssignment. +options: + scope: + description: + - Scope of the registration assignment. + required: true + type: str + registration_assignment_id: + description: + - ID of the registration assignment. + type: str +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) + +''' + +EXAMPLES = ''' + - name: Get Registration Assignment + azure_rm_registrationassignment_info: + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup + + + - name: Get All Registration Assignments in scope(subscription) + azure_rm_registrationassignment_info: + scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + + +''' + +RETURN = ''' +registration_assignments: + description: + - A list of dict results where the key is the name of the RegistrationAssignment. + - The values are the facts for that RegistrationAssignment. + returned: always + type: complex + contains: + properties: + description: + - Properties of a registration assignment. + returned: always + type: complex + contains: + registration_definition_id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx + id: + description: + - The fully qualified path of the registration assignment. + returned: always + type: str + sample: /subscriptions/xxx-xxxf/providers/Microsoft.ManagedServices/registrationAssignments/xxx-xxx + type: + description: + - Type of the resource. + returned: always + type: str + sample: Microsoft.ManagedServices/registrationAssignment + name: + description: + - Name of the registration assignment. + returned: always + type: str + sample: 9b2895ec-fb1e-4a1e-a978-abd9933d6b20 +''' + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBase +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class AzureRMRegistrationAssignmentInfo(AzureRMModuleBase): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str', + required=True + ), + registration_assignment_id=dict( + type='str' + ) + ) + + self.scope = None + self.registration_assignment_id = None + self.expand_registration_definition = False + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.url = None + self.status_code = [200] + + self.mgmt_client = None + super(AzureRMRegistrationAssignmentInfo, self).__init__(self.module_arg_spec, supports_tags=True) + + def exec_module(self, **kwargs): + + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2020-09-01', + suppress_subscription_id=True) + + if (self.scope is not None and self.registration_assignment_id is not None): + self.results['registration_assignments'] = self.format_item(self.get()) + elif (self.scope is not None): + self.results['registration_assignments'] = self.format_item(self.list()) + + if len(self.results['registration_assignments']) > 0: + for item in self.results['registration_assignments']: + if item.get('properties', None) is not None: + registration_definition_id = item['properties']['registration_definition_id'] + item['properties'].clear() + item['properties']['registration_definition_id'] = registration_definition_id + return self.results + + def get(self): + response = None + + try: + response = self.mgmt_client.registration_assignments.get(scope=self.scope, + registration_assignment_id=self.registration_assignment_id, + expand_registration_definition=self.expand_registration_definition) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def list(self): + response = None + + try: + response = self.mgmt_client.registration_assignments.list(scope=self.scope, + expand_registration_definition=self.expand_registration_definition) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def format_item(self, item): + if hasattr(item, 'as_dict'): + return [item.as_dict()] + else: + result = [] + items = list(item) + for tmp in items: + result.append(tmp.as_dict()) + return result + + +def main(): + AzureRMRegistrationAssignmentInfo() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_registrationdefinition.py b/plugins/modules/azure_rm_registrationdefinition.py new file mode 100644 index 000000000..f6dc37134 --- /dev/null +++ b/plugins/modules/azure_rm_registrationdefinition.py @@ -0,0 +1,449 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# 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_registrationdefinition +version_added: '1.3.0' +short_description: Manage Azure RegistrationDefinition instance +description: + - Create, update and delete instance of Azure RegistrationDefinition. +options: + registration_definition_id: + description: + - ID of the registration definition. + - If is not specified, an UUID will be generated for it. + type: str + scope: + description: + - The subscription ID defines the subscription in which the registration definition will be created. + - If not specified, will use the subscription derived from AzureRMAuth. + type: str + properties: + description: + - Properties of a registration definition. + type: dict + suboptions: + description: + description: + - Description of the registration definition. + type: str + authorizations: + description: + - Authorization tuple containing principal ID of the user/security group or service principal and ID of the build-in role. + required: true + type: list + suboptions: + principal_id: + description: + - Principal ID of the security group/service principal/user that would be assigned permissions to the projected subscription. + required: true + type: str + role_definition_id: + description: + - The role definition identifier. + - This role will define all the permissions that the security group/service principal/user must have on the projected subscription. + - This role cannot be an owner role. + required: true + type: str + registration_definition_name: + description: + - Name of the registration definition. + type: str + managed_by_tenant_id: + description: + - ID of the managedBy tenant. + required: true + type: str + plan: + description: + - Plan details for the managed services. + type: dict + suboptions: + name: + description: + - The plan name. + required: true + type: str + publisher: + description: + - The publisher ID. + required: true + type: str + product: + description: + - The product code. + required: true + type: str + version: + description: + - The plan's version. + required: true + type: str + state: + description: + - Assert the state of the RegistrationDefinition. + - Use C(present) to create or update an RegistrationDefinition and C(absent) to delete it. + default: present + type: str + choices: + - absent + - present +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) + +''' + +EXAMPLES = ''' + - name: Create Registration Definition without scope + azure_rm_registrationdefinition: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + properties: + description: test + authorizations: + - principal_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + role_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + managed_by_tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_definition_name: def4 + + - name: Create Registration Definition with scope + azure_rm_registrationdefinition: + scope: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + properties: + description: test + authorizations: + - principal_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + role_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + managed_by_tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_definition_name: def5 + + - name: Delete Registration Definition + azure_rm_registrationdefinition: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + state: absent + +''' + +RETURN = ''' +state: + description: + - The state info of the registration assignment. + type: complex + returned: always + contains: + properties: + description: + - Properties of a registration definition. + returned: always + type: complex + contains: + description: + description: + - Description of the registration definition. + returned: always + type: str + sample: test + authorizations: + description: + - Authorization tuple containing principal ID of the user/security group or service principal and ID of the build-in role. + returned: always + type: complex + contains: + principal_id: + description: + - Principal ID of the security group/service principal/user that would be assigned permissions to the projected subscription + returned: always + type: str + sample: 99e3227f-8701-4099-869f-bc3efc7f1e64 + role_definition_id: + description: + - The role definition identifier. + - This role will define all the permissions that the security group/service principal/user must have on the subscription. + - This role cannot be an owner role. + returned: always + type: str + sample: b24988ac-6180-42a0-ab88-20f7382dd24c + registration_definition_name: + description: + - Name of the registration definition. + returned: always + type: str + sample: null + managed_by_tenant_id: + description: + - ID of the managedBy tenant. + returned: always + type: str + sample: null + plan: + description: + - Plan details for the managed services. + returned: always + type: complex + contains: + name: + description: + - The plan name. + returned: always + type: str + sample: null + publisher: + description: + - The publisher ID. + returned: always + type: str + sample: null + product: + description: + - The product code. + returned: always + type: str + sample: null + version: + description: + - The plan's version. + returned: always + type: str + sample: null + id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: null + type: + description: + - Type of the resource. + returned: always + type: str + sample: Microsoft.ManagedServices/registrationDefinitions + name: + description: + - Name of the registration definition. + returned: always + type: str + sample: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +''' +import uuid +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMRegistrationDefinition(AzureRMModuleBaseExt): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str' + ), + registration_definition_id=dict( + type='str', + ), + properties=dict( + type='dict', + disposition='/properties', + options=dict( + description=dict( + type='str', + disposition='description' + ), + authorizations=dict( + type='list', + disposition='authorizations', + required=True, + elements='dict', + options=dict( + principal_id=dict( + type='str', + disposition='principal_id', + required=True + ), + role_definition_id=dict( + type='str', + disposition='role_definition_id', + required=True + ) + ) + ), + registration_definition_name=dict( + type='str', + disposition='registration_definition_name' + ), + managed_by_tenant_id=dict( + type='str', + disposition='managed_by_tenant_id', + required=True + ) + ) + ), + plan=dict( + type='dict', + disposition='/plan', + options=dict( + name=dict( + type='str', + disposition='name', + required=True + ), + publisher=dict( + type='str', + disposition='publisher', + required=True + ), + product=dict( + type='str', + disposition='product', + required=True + ), + version=dict( + type='str', + disposition='version', + required=True + ) + ) + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.scope = None + self.registration_definition_id = None + self.body = {} + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMRegistrationDefinition, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=True) + + def exec_module(self, **kwargs): + for key in list(self.module_arg_spec.keys()): + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.body[key] = kwargs[key] + + self.inflate_parameters(self.module_arg_spec, self.body, 0) + + if self.registration_definition_id is None: + self.registration_definition_id = str(uuid.uuid4()) + + if not self.scope: + self.scope = "/subscriptions/" + self.subscription_id + else: + self.scope = "/subscriptions/" + self.scope + + old_response = None + response = None + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2019-09-01', + suppress_subscription_id=True) + + old_response = self.get_resource() + + if not old_response: + if self.state == 'present': + self.to_do = Actions.Create + else: + if self.state == 'absent': + self.to_do = Actions.Delete + else: + modifiers = {} + self.create_compare_modifiers(self.module_arg_spec, '', modifiers) + self.results['modifiers'] = modifiers + self.results['compare'] = [] + if not self.default_compare(modifiers, self.body, old_response, '', self.results): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.results['changed'] = True + if self.check_mode: + return self.results + response = self.create_update_resource() + self.results['state'] = response + elif self.to_do == Actions.Delete: + self.results['changed'] = True + if self.check_mode: + return self.results + self.delete_resource() + else: + self.results['changed'] = False + response = old_response + + return self.results + + def create_update_resource(self): + + try: + response = self.mgmt_client.registration_definitions.create_or_update(registration_definition_id=self.registration_definition_id, + scope=self.scope, + plan=self.body.get('plan', None), + properties=self.body.get('properties', None), + request_body=self.body) + if isinstance(response, AzureOperationPoller) or isinstance(response, LROPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the RegistrationDefinition instance.') + self.fail('Error creating the RegistrationDefinition instance: {0}'.format(str(exc))) + return response.as_dict() + + def delete_resource(self): + try: + response = self.mgmt_client.registration_definitions.delete(registration_definition_id=self.registration_definition_id, + scope=self.scope) + except CloudError as e: + self.log('Error attempting to delete the RegistrationDefinition instance.') + self.fail('Error deleting the RegistrationDefinition instance: {0}'.format(str(e))) + + return True + + def get_resource(self): + try: + response = self.mgmt_client.registration_definitions.get(scope=self.scope, + registration_definition_id=self.registration_definition_id) + except Exception as e: + return False + return response.as_dict() + + +def main(): + AzureRMRegistrationDefinition() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_registrationdefinition_info.py b/plugins/modules/azure_rm_registrationdefinition_info.py new file mode 100644 index 000000000..616b1c562 --- /dev/null +++ b/plugins/modules/azure_rm_registrationdefinition_info.py @@ -0,0 +1,247 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# 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_registrationdefinition_info +version_added: '1.3.0' +short_description: Get RegistrationDefinition info +description: + - Get info of RegistrationDefinition. +options: + scope: + description: + - The subscription ID defines the subscription in which the registration definition will be retrieved. + - If not specified, will use the subscription derived from AzureRMAuth. + type: str + registration_definition_id: + description: + - ID of the registration definition. + type: str +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) +''' + +EXAMPLES = ''' + - name: Get Registration Definition + azure_rm_registrationdefinition_info: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + + - name: Get All Registration Definitions from AzureRMAuth's subscription + azure_rm_registrationdefinition_info: + + - name: Get All Registration Definitions in the subscription levle + azure_rm_registrationdefinition_info: + scope: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +''' + +RETURN = ''' +registration_definitions: + description: + - A list of dict results where the key is the name of the RegistrationDefinition and the values are the facts for that RegistrationDefinition. + returned: always + type: complex + contains: + properties: + description: + - Properties of a registration definition. + returned: always + type: complex + contains: + description: + description: + - Description of the registration definition. + returned: always + type: str + sample: null + authorizations: + description: + - Authorization tuple containing principal ID of the user/security group or service principal and id of the build-in role. + returned: always + type: complex + contains: + principal_id: + description: + - Principal ID of the security group/service principal/user that would be assigned permissions to the projected subscription. + returned: always + type: str + sample: null + role_definition_id: + description: + - The role definition identifier. + - The role will define all the permissions that the security group/service principal/user must have on the subscription. + - The role cannot be an owner role. + returned: always + type: str + sample: null + registration_definition_name: + description: + - Name of the registration definition. + returned: always + type: str + sample: null + managed_by_tenant_id: + description: + - ID of the managedBy tenant. + returned: always + type: str + sample: null + plan: + description: + - Plan details for the managed services. + returned: always + type: complex + contains: + name: + description: + - The plan name. + returned: always + type: str + sample: null + publisher: + description: + - The publisher ID. + returned: always + type: str + sample: null + product: + description: + - The product code. + returned: always + type: str + sample: null + version: + description: + - The plan's version. + returned: always + type: str + sample: null + id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: null + type: + description: + - Type of the resource. + returned: always + type: str + sample: null + name: + description: + - Name of the registration definition. + returned: always + type: str + sample: null +''' + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBase +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class AzureRMRegistrationDefinitionInfo(AzureRMModuleBase): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str' + ), + registration_definition_id=dict( + type='str' + ) + ) + + self.scope = None + self.registration_definition_id = None + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.url = None + self.status_code = [200] + + self.mgmt_client = None + super(AzureRMRegistrationDefinitionInfo, self).__init__(self.module_arg_spec, supports_tags=True) + + def exec_module(self, **kwargs): + + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + if not self.scope: + self.scope = "/subscriptions/" + self.subscription_id + else: + self.scope = "/subscriptions/" + self.scope + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2019-09-01', + suppress_subscription_id=True) + + if self.registration_definition_id is not None: + self.results['registration_definitions'] = self.format_item(self.get()) + else: + self.results['registration_definitions'] = self.format_item(self.list()) + return self.results + + def get(self): + response = None + + try: + response = self.mgmt_client.registration_definitions.get(scope=self.scope, + registration_definition_id=self.registration_definition_id) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def list(self): + response = None + + try: + response = self.mgmt_client.registration_definitions.list(scope=self.scope) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def format_item(self, item): + if hasattr(item, 'as_dict'): + return [item.as_dict()] + else: + result = [] + items = list(item) + for tmp in items: + result.append(tmp.as_dict()) + return result + + +def main(): + AzureRMRegistrationDefinitionInfo() + + +if __name__ == '__main__': + main() diff --git a/pr-pipelines.yml b/pr-pipelines.yml index c8f052d77..54cd96263 100644 --- a/pr-pipelines.yml +++ b/pr-pipelines.yml @@ -62,6 +62,8 @@ parameters: - "azure_rm_resourcegroup" - "azure_rm_routetable" - "azure_rm_roleassignment" + - "azure_rm_registrationassignment" + - "azure_rm_registrationdefinition" - "azure_rm_securitygroup" - "azure_rm_servicebus" - "azure_rm_sqlserver" @@ -173,7 +175,11 @@ jobs: AZURE_CLIENT_ID: $(AZURE_CLIENT_ID) AZURE_SECRET: $(AZURE_SECRET) AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) + AZURE_SUBSCRIPTION_SEC_ID: $(AZURE_SUBSCRIPTION_SEC_ID) AZURE_TENANT: $(AZURE_TENANT) + AZURE_PRINCIPAL_ID: $(AZURE_PRINCIPAL_ID) + AZURE_MANAGED_BY_TENANT_ID: $(AZURE_MANAGED_BY_TENANT_ID) + AZURE_ROLE_DEFINITION_ID: $(AZURE_ROLE_DEFINITION_ID) RESOURCE_GROUP: $(TEST_RESOURCE_GROUP) RESOURCE_GROUP_SECONDARY: $(TEST_RESOURCE_GROUP_SECONDARY) displayName: 'Running Tests' diff --git a/requirements-azure.txt b/requirements-azure.txt index 50858a028..d0b84379e 100644 --- a/requirements-azure.txt +++ b/requirements-azure.txt @@ -15,6 +15,7 @@ azure-mgmt-dns==2.1.0 azure-mgmt-keyvault==1.1.0 azure-mgmt-marketplaceordering==0.1.0 azure-mgmt-monitor==0.5.2 +azure-mgmt-managedservices==1.0.0 azure-mgmt-network==10.2.0 azure-mgmt-nspkg==2.0.0 azure-mgmt-privatedns==0.1.0 diff --git a/tests/integration/targets/azure_rm_registrationassignment/aliases b/tests/integration/targets/azure_rm_registrationassignment/aliases new file mode 100644 index 000000000..759eafa2d --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationassignment/aliases @@ -0,0 +1,3 @@ +cloud/azure +shippable/azure/group3 +destructive diff --git a/tests/integration/targets/azure_rm_registrationassignment/meta/main.yml b/tests/integration/targets/azure_rm_registrationassignment/meta/main.yml new file mode 100644 index 000000000..95e1952f9 --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationassignment/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml new file mode 100644 index 000000000..055524705 --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml @@ -0,0 +1,78 @@ +- name: set facts + set_fact: + subscription_id: "{{ azure_subscription_id }}" + managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" + principal_id: "{{ azure_principal_id }}" + role_definition_id: "{{ azure_role_definition_id }}" + run_once: yes + +- name: Create a RegistrationDefinition + azure_rm_registrationdefinition: + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: test_def + register: output1 + +- name: Create a RegistrationAssignment ---check mode + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + properties: + registration_definition_id: "{{ output1.state.id }}" + register: output + check_mode: yes + +- assert: + that: + - output.changed + +- name: Create a RegistrationAssignment + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + properties: + registration_definition_id: "{{ output1.state.id }}" + register: output2 + +- assert: + that: + - output2.changed + +- name: Create a RegistrationAssignment -- idempotent + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + registration_assignment_id: "{{ output2.state.name }}" + properties: + registration_definition_id: "{{ output1.state.id }}" + register: output + +- assert: + that: + - not output.changed + +- name: Get a RegistrationAssignment + azure_rm_registrationassignment_info: + scope: subscriptions/{{ subscription_id }} + registration_assignment_id: "{{ output2.state.name }}" + register: output + +- assert: + that: + - output.registration_assignments[0].properties.registration_definition_id == "{{ output1.state.id }}" + +- name: Get all RegistrationAssignment + azure_rm_registrationassignment_info: + scope: subscriptions/{{ subscription_id }} + register: output + +- assert: + that: + - output.registration_assignments | length >= 1 + +- name: Delete the RegistrationAssignment + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + registration_assignment_id: "{{ output2.state.name }}" + state: absent diff --git a/tests/integration/targets/azure_rm_registrationdefinition/aliases b/tests/integration/targets/azure_rm_registrationdefinition/aliases new file mode 100644 index 000000000..759eafa2d --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationdefinition/aliases @@ -0,0 +1,3 @@ +cloud/azure +shippable/azure/group3 +destructive diff --git a/tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml new file mode 100644 index 000000000..95e1952f9 --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml new file mode 100644 index 000000000..2e95f576e --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -0,0 +1,134 @@ +- name: set facts + set_fact: + subscription_id: "{{ azure_subscription_id }}" + subscription_sec_id: "{{ azure_subscription_sec_id }}" + managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" + principal_id: "{{ azure_principal_id }}" + role_definition_id: "{{ azure_role_definition_id }}" + reg_def_name: test_name + run_once: yes + +- name: Create a RegistrationDefinition -- check mode + azure_rm_registrationdefinition: + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + check_mode: yes + register: output + +- name: Assert creating registration definition check mode + assert: + that: + - output.changed + +- name: Create a RegistrationDefinition with scope + azure_rm_registrationdefinition: + scope: "{{ subscription_sec_id }}" + properties: + description: test definition with scope + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + register: output2 + +- name: Assert creating registration definition + assert: + that: + - output2.changed + +- name: Create a RegistrationDefinition + azure_rm_registrationdefinition: + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + register: output1 + +- name: Assert creating registration definition + assert: + that: + - output1.changed + +- name: Create a RegistrationDefinition (idempotent) + azure_rm_registrationdefinition: + registration_definition_id: "{{ output1.state.name }}" + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + register: output + +- name: Assert creating registration definition + assert: + that: + - not output.changed + +- name: Update the RegistrationDefinition properties description and name + azure_rm_registrationdefinition: + registration_definition_id: "{{ output1.state.name }}" + properties: + description: second_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}02" + register: output + +- name: Assert creating registration definition + assert: + that: + - output.changed + +- name: Get the Registration Definition info + azure_rm_registrationdefinition_info: + registration_definition_id: "{{ output1.state.name }}" + register: output + +- name: Assert the registration definition info + assert: + that: + - output.registration_definitions[0].name == "{{ output1.state.name }}" + - output.registration_definitions[0].properties.authorizations[0].principal_id == "{{ principal_id }}" + - output.registration_definitions[0].properties.authorizations[0].role_definition_id == "{{ role_definition_id }}" + - output.registration_definitions[0].properties.provisioning_state == "Succeeded" + - output.registration_definitions[0].properties.description == "second_test" + - output.registration_definitions[0].properties.registration_definition_name == "test_name02" + +- name: Get All Registration Definition info in the subscription + azure_rm_registrationdefinition_info: + scope: "{{ subscription_id }}" + register: output + +- name: Assert all the registration definition info + assert: + that: + - output.registration_definitions | length >=1 + +- name: Delete the registration definition + azure_rm_registrationdefinition: + registration_definition_id: "{{ output1.state.name }}" + state: absent + register: output + +- name: Assert delete registration definition success + assert: + that: + - output.changed + +- name: Delete the registration definition + azure_rm_registrationdefinition: + registration_definition_id: "{{ output2.state.name }}" + state: absent diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 1b4c0fdf5..e8d94a92b 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -241,6 +241,17 @@ plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-type-n plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-list-no-elements plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-requirements-unknown plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationdefinition.py validate-modules:doc-elements-mismatch +plugins/modules/azure_rm_registrationdefinition.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationassignment.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-unknown-key plugins/modules/azure_rm_securitygroup.py validate-modules:doc-choices-do-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:doc-default-does-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:missing-suboption-docs diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 1168ac357..c4358e5ca 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -241,6 +241,17 @@ plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-type-n plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-list-no-elements plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-requirements-unknown plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationassignment.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition.py validate-modules:doc-elements-mismatch +plugins/modules/azure_rm_registrationdefinition.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-unknown-key plugins/modules/azure_rm_securitygroup.py validate-modules:doc-choices-do-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:doc-default-does-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:missing-suboption-docs diff --git a/tests/utils/ado/ado.sh b/tests/utils/ado/ado.sh index 7b9b2fcb1..9638318fd 100755 --- a/tests/utils/ado/ado.sh +++ b/tests/utils/ado/ado.sh @@ -120,8 +120,12 @@ cat <> "${TEST_DIR}"/tests/integration/cloud-config-azure.ini AZURE_CLIENT_ID:${AZURE_CLIENT_ID} AZURE_SECRET:${AZURE_SECRET} AZURE_SUBSCRIPTION_ID:${AZURE_SUBSCRIPTION_ID} +AZURE_SUBSCRIPTION_SEC_ID:${AZURE_SUBSCRIPTION_SEC_ID} AZURE_TENANT:${AZURE_TENANT} RESOURCE_GROUP:${RESOURCE_GROUP} +AZURE_PRINCIPAL_ID:${AZURE_PRINCIPAL_ID} +AZURE_MANAGED_BY_TENANT_ID:${AZURE_MANAGED_BY_TENANT_ID} +AZURE_ROLE_DEFINITION_ID:${AZURE_ROLE_DEFINITION_ID} RESOURCE_GROUP_SECONDARY:${RESOURCE_GROUP_SECONDARY} EOF