diff --git a/lib/ansible/modules/cloud/azure/azure_rm_roleassignment.py b/lib/ansible/modules/cloud/azure/azure_rm_roleassignment.py index 3f264911032..1507bcb918a 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_roleassignment.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_roleassignment.py @@ -69,6 +69,7 @@ EXAMPLES = ''' azure_rm_roleassignment: name: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx scope: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + state: absent ''' @@ -199,7 +200,7 @@ class AzureRMRoleAssignment(AzureRMModuleBase): if self.check_mode: return self.results - self.delete_roleassignment() + self.delete_roleassignment(old_response['id']) self.log('role assignment deleted') @@ -234,7 +235,7 @@ class AzureRMRoleAssignment(AzureRMModuleBase): self.fail("Error creating role assignment: {0}".format(str(exc))) return roleassignment_to_dict(response) - def delete_roleassignment(self): + def delete_roleassignment(self, assignment_id): ''' Deletes specified role assignment. @@ -243,8 +244,7 @@ class AzureRMRoleAssignment(AzureRMModuleBase): self.log("Deleting the role assignment {0}".format(self.name)) scope = self.build_scope() try: - response = self._client.role_assignments.delete(name=self.name, - scope=self.scope) + response = self._client.role_assignments.delete_by_id(role_id=assignment_id) except CloudError as e: self.log('Error attempting to delete the role assignment.') self.fail("Error deleting the role assignment: {0}".format(str(e))) @@ -262,9 +262,11 @@ class AzureRMRoleAssignment(AzureRMModuleBase): response = None try: - response = self._client.role_assignments.get(scope=self.scope, role_assignment_name=self.name) - - return roleassignment_to_dict(response) + response = list(self._client.role_assignments.list()) + if response: + for assignment in response: + if assignment.name == self.name and assignment.scope == self.scope: + return roleassignment_to_dict(assignment) except CloudError as ex: self.log("Didn't find role assignment {0} in scope {1}".format(self.name, self.scope)) diff --git a/lib/ansible/modules/cloud/azure/azure_rm_roleassignment_facts.py b/lib/ansible/modules/cloud/azure/azure_rm_roleassignment_facts.py index 19999edbf83..a25407f2ac2 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_roleassignment_facts.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_roleassignment_facts.py @@ -36,6 +36,9 @@ options: description: - Object id of a user, group or service principal. - Mutually exclusive with I(name). + role_definition_id: + description: + - Resource id of role definition. extends_documentation_fragment: - azure @@ -135,12 +138,16 @@ class AzureRMRoleAssignmentFacts(AzureRMModuleBase): ), assignee=dict( type='str' + ), + role_definition_id=dict( + type='str' ) ) self.name = None self.scope = None self.assignee = None + self.role_definition_id = None self.results = dict( changed=False @@ -170,8 +177,6 @@ class AzureRMRoleAssignmentFacts(AzureRMModuleBase): self.results['roleassignments'] = self.get_by_name() elif self.assignee: self.results['roleassignments'] = self.get_by_assignee() - elif self.resource_group: - self.results['roleassignments'] = self.list_by_resource_group() elif self.scope: self.results['roleassignments'] = self.list_by_scope() else: @@ -187,17 +192,24 @@ class AzureRMRoleAssignmentFacts(AzureRMModuleBase): ''' self.log("Gets role assignment {0} by name".format(self.name)) - response = None + results = [] try: response = self._client.role_assignments.get(scope=self.scope, role_assignment_name=self.name) - return [roleassignment_to_dict(response)] + if response: + response = roleassignment_to_dict(response) + + if self.role_definition_id: + if self.role_definition_id == response['role_definition_id']: + results = [response] + else: + results = [response] except CloudError as ex: self.log("Didn't find role assignment {0} in scope {1}".format(self.name, self.scope)) - return [] + return results def get_by_assignee(self): ''' @@ -207,18 +219,25 @@ class AzureRMRoleAssignmentFacts(AzureRMModuleBase): ''' self.log("Gets role assignment {0} by name".format(self.name)) - response = None + results = [] filter = "principalId eq '{0}'".format(self.assignee) try: response = list(self._client.role_assignments.list(filter=filter)) if response and len(response) > 0: - return [roleassignment_to_dict(a) for a in response] + response = [roleassignment_to_dict(a) for a in response] + + if self.role_definition_id: + for r in response: + if r['role_definition_id'] == self.role_definition_id: + results.append(r) + else: + results = response except CloudError as ex: self.log("Didn't find role assignments to assignee {0}".format(self.assignee)) - return [] + return results def list_by_scope(self): ''' @@ -226,19 +245,26 @@ class AzureRMRoleAssignmentFacts(AzureRMModuleBase): :return: deserialized role assignment dictionary ''' - self.log("Lists role assignment by resource group {0}".format(self.resource_group)) + self.log("Lists role assignment by scope {0}".format(self.scope)) - response = None + results = [] try: response = list(self._client.role_assignments.list_for_scope(scope=self.scope, filter='atScope()')) if response and len(response) > 0: - return [roleassignment_to_dict(a) for a in response] + response = [roleassignment_to_dict(a) for a in response] + + if self.role_definition_id: + for r in response: + if r['role_definition_id'] == self.role_definition_id: + results.append(r) + else: + results = response except CloudError as ex: self.log("Didn't find role assignments to scope {0}".format(self.scope)) - return [] + return results def main(): diff --git a/lib/ansible/modules/cloud/azure/azure_rm_roledefinition.py b/lib/ansible/modules/cloud/azure/azure_rm_roledefinition.py index 179cc175e6a..e679bac0ef1 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_roledefinition.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_roledefinition.py @@ -348,8 +348,7 @@ class AzureRMRoleDefinition(AzureRMModuleBase): self.log("Deleting the role definition {0}".format(self.name)) scope = self.build_scope() try: - response = self._client.role_definitions.delete(name=self.name, - scope=scope, + response = self._client.role_definitions.delete(scope=scope, role_definition_id=role_definition_id) if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): response = self.get_poller_result(response) diff --git a/lib/ansible/modules/cloud/azure/azure_rm_roledefinition_facts.py b/lib/ansible/modules/cloud/azure/azure_rm_roledefinition_facts.py index c83dff03865..f668bbcf711 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_roledefinition_facts.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_roledefinition_facts.py @@ -234,7 +234,7 @@ class AzureRMRoleDefinitionFacts(AzureRMModuleBase): except CloudError as ex: self.log("Didn't find role definition in scope {0}".format(self.scope)) - return [] + return response def get_by_id(self): ''' @@ -252,9 +252,9 @@ class AzureRMRoleDefinitionFacts(AzureRMModuleBase): response = roledefinition_to_dict(response) if self.type: if response.role_type == self.type: - return response + return [response] else: - return response + return [response] except CloudError as ex: self.log("Didn't find role definition by id {0}".format(self.id)) @@ -269,7 +269,7 @@ class AzureRMRoleDefinitionFacts(AzureRMModuleBase): ''' self.log("Get Role Definition by name {0}".format(self.role_name)) - response = None + response = [] try: response = self.list() @@ -282,7 +282,7 @@ class AzureRMRoleDefinitionFacts(AzureRMModuleBase): if len(roles) == 1: self.log("Role Definition : {0} found".format(self.role_name)) - return roles[0] + return roles if len(roles) > 1: self.fail("Found multiple Role Definitions with name: {0}".format(self.role_name)) diff --git a/test/integration/targets/azure_rm_roledefinition/tasks/main.yml b/test/integration/targets/azure_rm_roledefinition/tasks/main.yml index da179736ccc..611e127d544 100644 --- a/test/integration/targets/azure_rm_roledefinition/tasks/main.yml +++ b/test/integration/targets/azure_rm_roledefinition/tasks/main.yml @@ -50,7 +50,7 @@ that: - output.changed -- name: Get facts by name +- name: Get facts by type azure_rm_roledefinition_facts: scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" type: custom @@ -61,19 +61,22 @@ that: - facts['roledefinitions'] | length > 1 -- name: Get facts +- name: Get facts by name azure_rm_roledefinition_facts: scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" role_name: "{{ role_name }}" register: facts + until: "{{ facts.roledefinitions | length > 0 }}" + retries: 50 + delay: 60 - name: Assert facts assert: that: - facts['roledefinitions'] | length == 1 - - facts['roledefinitions']['permissions'] | length == 1 - - facts['roledefinitions']['permissions'][0]['not_data_actions'] | length == 1 - - facts['roledefinitions']['permissions'][0]['data_actions'] | length == 1 + - facts['roledefinitions'][0]['permissions'] | length == 1 + - facts['roledefinitions'][0]['permissions'][0]['not_data_actions'] | length == 1 + - facts['roledefinitions'][0]['permissions'][0]['data_actions'] | length == 1 - name: Update the role definition (idempotent) azure_rm_roledefinition: @@ -126,11 +129,14 @@ scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" type: custom register: roledef + until: "{{ roledef.roledefinitions | length > 0 }}" + retries: 50 + delay: 60 - name: Assert role definition facts assert: that: - - roledef['roledefinitions'] | length > 1 + - roledef['roledefinitions'] | length == 1 - roledef['roledefinitions'][0]['id'] - name: Create a role assignment (Check Mode) @@ -138,7 +144,7 @@ scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" assignee_object_id: "{{ principal_id }}" role_definition_id: "{{ roledef['roledefinitions'][0]['id'] }}" - check_mode: yes + check_mode: yes register: output - name: Assert creating role definition check mode @@ -153,7 +159,7 @@ role_definition_id: "{{ roledef['roledefinitions'][0]['id'] }}" register: output -- name: Assert creating role definition +- name: Assert creating role assignment assert: that: - output.changed @@ -162,24 +168,26 @@ azure_rm_roleassignment_facts: scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" assignee: "{{ principal_id }}" + role_definition_id: "{{ roledef['roledefinitions'][0]['id'] }}" register: facts - name: assert role assignment facts assert: that: - - facts['roleassignments'] | length > 1 + - facts['roleassignments'] | length > 0 - facts['roleassignments'][0]['id'] - name: delete role assignment azure_rm_roleassignment: - name: facts['roleassignments'][0]['id'] - scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" + name: "{{ facts['roleassignments'][0]['id'].split('/')[-1] }}" + scope: "/subscriptions/{{ subscription_id }}" state: absent - name: Delete the role definition (Check Mode) azure_rm_roledefinition: name: "{{ role_name }}" scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" + state: absent check_mode: yes register: output @@ -187,10 +195,11 @@ assert: that: output.changed -- name: Delete the redis cache +- name: Delete the role definition azure_rm_roledefinition: name: "{{ role_name }}" scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}" + state: absent register: output - assert: