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

Add Managed Identity support to servicebus #1643

Merged
merged 1 commit into from
Aug 15, 2024
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
77 changes: 72 additions & 5 deletions plugins/modules/azure_rm_servicebus.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,42 @@
- basic
- premium
default: standard
identity:
description:
- Identity for this resource.
type: dict
version_added: '2.7.0'
suboptions:
type:
description:
- Type of the managed identity
choices:
- SystemAssigned
- SystemAssigned, UserAssigned
- UserAssigned
- 'None'
default: 'None'
type: str
user_assigned_identities:
description:
- User Assigned Managed Identities and its options
required: false
type: dict
default: {}
suboptions:
id:
description:
- List of the user assigned identities IDs associated to the WebApp
required: false
type: list
elements: str
default: []
append:
description:
- If the list of identities has to be appended to current identities (true) or if it has to replace current identities (false)
required: false
type: bool
default: True
p3ck marked this conversation as resolved.
Show resolved Hide resolved
extends_documentation_fragment:
- azure.azcollection.azure
Expand Down Expand Up @@ -75,7 +111,8 @@
'''

try:
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt
from azure.mgmt.servicebus.v2021_06_01_preview.models import (Identity, UserAssignedIdentity)
except ImportError:
# This is handled in azure_rm_common
pass
Expand All @@ -84,7 +121,7 @@
from datetime import datetime, timedelta


class AzureRMServiceBus(AzureRMModuleBase):
class AzureRMServiceBus(AzureRMModuleBaseExt):

def __init__(self):

Expand All @@ -93,14 +130,22 @@ def __init__(self):
name=dict(type='str', required=True),
location=dict(type='str'),
state=dict(type='str', default='present', choices=['present', 'absent']),
sku=dict(type='str', choices=['basic', 'standard', 'premium'], default='standard')
sku=dict(type='str', choices=['basic', 'standard', 'premium'], default='standard'),
identity=dict(
type="dict",
options=self.managed_identity_multiple_spec
),

)

self.resource_group = None
self.name = None
self.state = None
self.sku = None
self.location = None
self._managed_identity = None
self.identity = None
self.update_identity = False

self.results = dict(
changed=False,
Expand All @@ -111,6 +156,15 @@ def __init__(self):
supports_tags=True,
supports_check_mode=True)

@property
def managed_identity(self):
if not self._managed_identity:
self._managed_identity = {
"identity": Identity,
"user_assigned": UserAssignedIdentity,
}
return self._managed_identity

def exec_module(self, **kwargs):

for key in list(self.module_arg_spec.keys()) + ['tags']:
Expand All @@ -127,6 +181,13 @@ def exec_module(self, **kwargs):
if not original:
self.check_name()

curr_identity = original.identity.as_dict() if original and original.identity else None

if self.identity:
self.update_identity, identity_result = self.update_managed_identity(curr_identity=curr_identity,
new_identity=self.identity)
self.identity = identity_result.as_dict()

if self.state == 'present':
if not self.check_mode:
if original:
Expand All @@ -135,6 +196,9 @@ def exec_module(self, **kwargs):
changed = True
self.tags = new_tags
original = self.create()
if self.update_identity:
changed = True
original = self.create()
else:
changed = False
else:
Expand Down Expand Up @@ -170,10 +234,11 @@ def create(self):
self.name,
self.servicebus_models.SBNamespace(location=self.location,
tags=self.tags,
sku=sku))
sku=sku,
identity=self.identity))
ns = self.get_poller_result(poller)
except Exception as exc:
self.fail('Error creating namespace {0} - {1}'.format(self.name, str(exc.inner_exception) or str(exc)))
self.fail('Error creating namespace {0} - {1}'.format(self.name, str(exc)))
return ns

def delete(self):
Expand Down Expand Up @@ -204,6 +269,8 @@ def to_dict(self, instance):
result[attribute] = to_native(value)
elif attribute == 'max_size_in_megabytes':
result['max_size_in_mb'] = value
elif isinstance(value, Identity):
result['identity'] = value.as_dict()
else:
result[attribute] = value
return result
Expand Down
5 changes: 4 additions & 1 deletion plugins/modules/azure_rm_servicebus_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@

try:
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase
from azure.mgmt.servicebus.v2021_06_01_preview.models import Identity
except Exception:
# This is handled in azure_rm_common
pass
Expand Down Expand Up @@ -498,11 +499,13 @@ def instance_to_dict(self, instance):
result[attribute] = value.name.lower()
elif isinstance(value, datetime):
result[attribute] = str(value)
elif isinstance(value, Identity):
result['identity'] = value.as_dict()
elif isinstance(value, str):
result[attribute] = to_native(value)
elif attribute == 'max_size_in_megabytes':
result['max_size_in_mb'] = value
elif attribute == 'private_endpoint_connections':
elif attribute == 'private_endpoint_connections' and isinstance(value, list):
result['private_endpoint_connections'] = [item.as_dict() for item in value]
else:
result[attribute] = value
Expand Down
133 changes: 133 additions & 0 deletions tests/integration/targets/azure_rm_servicebus/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
- name: Gather Resource Group info
azure.azcollection.azure_rm_resourcegroup_info:
name: "{{ resource_group }}"
register: __rg_info

- name: Prepare random number
ansible.builtin.set_fact:
rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
location: "{{ __rg_info.resourcegroups.0.location }}"
run_once: true

- name: Create User Managed Identities
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ item }}"
api_version: "2023-01-31"
body:
location: "{{ location }}"
state: present
loop:
- "ansible-test-servicebus-identity"
- "ansible-test-servicebus-identity-2"
- "ansible-test-servicebus-identity-3"

- name: Set identities base path
ansible.builtin.set_fact:
identity_base_path: "/subscriptions/{{ azure_subscription_id }}/resourcegroups/{{ resource_group }}/providers/Microsoft.ManagedIdentity"

- name: Set identities IDs to test. Identities ansible-test-servicebus-identity and ansible-test-servicebus-identity-2 have to be created previously
ansible.builtin.set_fact:
user_identity_1: "{{ identity_base_path }}/userAssignedIdentities/ansible-test-servicebus-identity"
user_identity_2: "{{ identity_base_path }}/userAssignedIdentities/ansible-test-servicebus-identity-2"
user_identity_3: "{{ identity_base_path }}/userAssignedIdentities/ansible-test-servicebus-identity-3"

- name: Create a namespace
azure_rm_servicebus:
name: "ns{{ rpfx }}"
Expand All @@ -23,13 +54,102 @@
azure_rm_servicebus:
name: "ns{{ rpfx }}"
resource_group: "{{ resource_group }}"
sku: premium
register: namespace

- name: Assert idempotent
ansible.builtin.assert:
that:
- not namespace.changed

- name: Update namespace - ManagedIdentity SystemAssigned
azure_rm_servicebus:
name: "ns{{ rpfx }}"
resource_group: "{{ resource_group }}"
sku: premium
identity:
type: SystemAssigned
register: namespace

- name: Assert SystemAssigned
ansible.builtin.assert:
that:
- namespace.changed
- namespace.identity.type == "SystemAssigned"

- name: Gather facts
azure_rm_servicebus_info:
name: "ns{{ rpfx }}"
type: namespace
resource_group: "{{ resource_group }}"
register: facts

- name: Debug
ansible.builtin.debug:
var: facts

- name: Update namespace - ManagedIdentity UserAssigned
azure_rm_servicebus:
name: "ns{{ rpfx }}"
resource_group: "{{ resource_group }}"
sku: premium
identity:
type: UserAssigned
user_assigned_identities:
id:
- "{{ user_identity_1 }}"
register: namespace

- name: Assert UserAssigned
ansible.builtin.assert:
that:
- namespace.changed
- namespace.identity.type == "UserAssigned"
- namespace.identity.user_assigned_identities | length == 1
- namespace.identity.user_assigned_identities[user_identity_1] is defined

- name: Update namespace - ManagedIdentity UserAssigned Append
azure_rm_servicebus:
name: "ns{{ rpfx }}"
resource_group: "{{ resource_group }}"
sku: premium
identity:
type: UserAssigned
user_assigned_identities:
id:
- "{{ user_identity_2 }}"
register: namespace

- name: Assert UserAssigned
ansible.builtin.assert:
that:
- namespace.changed
- namespace.identity.type == "UserAssigned"
- namespace.identity.user_assigned_identities | length == 2
- namespace.identity.user_assigned_identities[user_identity_1] is defined
- namespace.identity.user_assigned_identities[user_identity_2] is defined

- name: Update namespace - ManagedIdentity UserAssigned Append false
azure_rm_servicebus:
name: "ns{{ rpfx }}"
resource_group: "{{ resource_group }}"
sku: premium
identity:
type: UserAssigned
user_assigned_identities:
id:
- "{{ user_identity_3 }}"
append: false
register: namespace

- name: Assert UserAssigned
ansible.builtin.assert:
that:
- namespace.changed
- namespace.identity.type == "UserAssigned"
- namespace.identity.user_assigned_identities | length == 1
- namespace.identity.user_assigned_identities[user_identity_3] is defined

- name: Create a queue
azure_rm_servicebusqueue:
name: "queue{{ rpfx }}"
Expand Down Expand Up @@ -189,3 +309,16 @@
name: "ns{{ rpfx }}"
resource_group: "{{ resource_group }}"
state: absent

- name: Destroy User Managed Identities
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ item }}"
api_version: "2023-01-31"
state: absent
loop:
- "ansible-test-servicebus-identity"
- "ansible-test-servicebus-identity-2"
- "ansible-test-servicebus-identity-3"