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 new module for AD Users #402

Merged
merged 32 commits into from
Apr 19, 2021
Merged
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
72b6f3b
init
coleneubauer Jan 19, 2021
e72a29c
functional
coleneubauer Jan 20, 2021
7e03901
fully functional
coleneubauer Jan 20, 2021
8d84c45
fix pep8 compliance
coleneubauer Jan 20, 2021
2996ce1
pass sanity tests
coleneubauer Jan 20, 2021
03a964b
add param
coleneubauer Jan 21, 2021
857cd42
add tests
coleneubauer Jan 21, 2021
ce7ae60
fix tabs in test tasks
coleneubauer Jan 21, 2021
8c60458
correct spelling
coleneubauer Jan 21, 2021
888861a
Update documentation to include required_together and mutually_exclus…
coleneubauer Jan 22, 2021
7ad8ac3
remove whitespace
coleneubauer Jan 22, 2021
61861cd
move documentation string
coleneubauer Jan 22, 2021
39737d3
Merge branch 'dev' into ad-user-info-module-new
coleneubauer Jan 25, 2021
ee3ee49
Update plugins/modules/azure_rm_aduser_info.py
coleneubauer Feb 9, 2021
ab97844
Update tests/integration/targets/azure_rm_aduser/tasks/main.yml
coleneubauer Feb 9, 2021
50d853d
Update collection references in tests
coleneubauer Feb 12, 2021
3d93b09
added modify module and updated tests
coleneubauer Feb 17, 2021
7108cd1
Merge branch 'dev' into ad-user-info-module-new
coleneubauer Feb 17, 2021
c77aecc
Update to remove meta data block
coleneubauer Mar 5, 2021
28e59ec
Add metaclass line back in
coleneubauer Mar 5, 2021
299814f
Merge branch 'dev' into ad-user-info-module-new
coleneubauer Mar 5, 2021
6aa1763
Remove requested lines
coleneubauer Mar 5, 2021
a82cec0
Merge branch 'ad-user-info-module-new' of github.com:coleneubauer/azu…
coleneubauer Mar 5, 2021
9cc66b3
test to confirm the build fails with removals
coleneubauer Mar 5, 2021
0344b80
Remove requested metadata block
coleneubauer Mar 5, 2021
3d126d4
Apply suggestions from code review
coleneubauer Mar 8, 2021
5ba65ee
Update azure_rm_aduser_info.py
coleneubauer Mar 8, 2021
c4ea592
Update azure_rm_aduser.py
coleneubauer Mar 8, 2021
12396fb
Merge branch 'dev' into ad-user-info-module-new
Fred-sun Mar 23, 2021
5d5539a
Merge branch 'dev' into ad-user-info-module-new
coleneubauer Mar 30, 2021
24e0d27
Add idempotency and test. Operations now only apply to one user only
coleneubauer Mar 31, 2021
39c1fd6
Merge branch 'dev' into ad-user-info-module-new
haiyuazhang Apr 18, 2021
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
Prev Previous commit
Next Next commit
fix pep8 compliance
  • Loading branch information
coleneubauer committed Jan 20, 2021
commit 8d84c453f052798272fce5c2094c343562108025
331 changes: 166 additions & 165 deletions plugins/modules/azure_rm_aduser_info.py
Original file line number Diff line number Diff line change
@@ -1,165 +1,166 @@
#!/usr/bin/python
#
# Copyright (c) 2020 Cole Neubauer, (@coleneubauer)
#
# 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_aduser_info

version_added: "1.3.2"

short_description: Get Azure Active Directory user info

description:
- Get Azure Active Directory user info.

options:
tenant:
description:
- The tenant ID.
type: str
required: True
object_id:
description:
- It's service principal's object ID.
type: str
app_id:
description:
- The application ID.
type: str
extends_documentation_fragment:
- azure.azcollection.azure

author:
- Cole Neubauer(@coleneubauer)

'''

EXAMPLES = '''
- name: get ad user info
azure_rm_adserviceprincipal_info:
app_id: "{{ app_id }}"
tenant: "{{ tenant_id }}"

'''

RETURN = '''
app_role_assignment_required:
description:
- Whether the Role of the Service Principal is set.
type: bool
returned: always
sample: false
object_id:
description:
- It's service principal's object ID.
returned: always
type: str
sample: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx


'''

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

try:
from msrestazure.azure_exceptions import CloudError
from azure.graphrbac.models import GraphErrorException
except ImportError:
# This is handled in azure_rm_common
pass


class AzureRMADUserInfo(AzureRMModuleBase):
def __init__(self):

self.module_arg_spec = dict(
user_principle_name=dict(type='str'),
object_id=dict(type='str'),
attribute_name=dict(type='str'),
attribute_value=dict(type='str'),
odata_filter=dict(type='str'),
tenant=dict(type='str', required=True),
)

self.tenant = None
self.user_principle_name = None
self.object_id = None
self.attribute_name = None
self.attribute_value = None
self.odata_filter = None

self.results = dict(changed=False)

# TODO: limit object id, user_principle_name, and filter params
# TODO: add tests
# TODO: documentation
# TODO: cleanup
# TODO: consider adding a "filter" parameter for more complex limits.
# Would probably be easier for most to do the query directly

super(AzureRMADUserInfo, self).__init__(derived_arg_spec=self.module_arg_spec,
supports_check_mode=False,
supports_tags=False,
is_ad_resource=True)

def exec_module(self, **kwargs):

for key in list(self.module_arg_spec.keys()):
setattr(self, key, kwargs[key])

ad_users = []

try:
client = self.get_graphrbac_client(self.tenant)

if self.user_principle_name is not None:
ad_users = [client.users.get(self.user_principle_name)]
elif self.object_id is not None:
ad_users = [client.users.get(self.object_id)]
elif self.attribute_name is not None and self.attribute_value is not None:
try:
ad_users = list(client.users.list(filter="{0} eq '{1}'".format(self.attribute_name, self.attribute_value)))
except GraphErrorException as e:
# the type doesn't get more specific. Could check the error message but no guarantees that message doesn't change in the future
# more stable to try again assuming the first error came from the attribute being a list
try:
ad_users = list(client.users.list(filter="{0}/any(c:c eq '{1}')".format(self.attribute_name, self.attribute_value)))
except GraphErrorException as sub_e:
raise #TODO add previous failure message as well before raising
else: # run a filter based on user input to return based on any given attribute/query
ad_users = list(client.users.list(filter=self.odata_filter))

self.results['ad_users'] = [self.to_dict(user) for user in ad_users]

except GraphErrorException as e:
self.fail("failed to get ad user info {0}".format(str(e)))

return self.results

def to_dict(self, object):
return dict(
object_id=object.object_id,
display_name=object.display_name,
user_principal_name=object.user_principal_name,
mail_nickname=object.mail_nickname,
mail=object.mail,
account_enabled=object.account_enabled,
user_type=object.user_type
)

def main():
AzureRMADUserInfo()


if __name__ == '__main__':
main()
#!/usr/bin/python
#
# Copyright (c) 2020 Cole Neubauer, (@coleneubauer)
#
# 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_aduser_info

version_added: "1.3.2"

short_description: Get Azure Active Directory user info

description:
- Get Azure Active Directory user info.

options:
tenant:
description:
- The tenant ID.
type: str
required: True
object_id:
description:
- It's service principal's object ID.
type: str
app_id:
description:
- The application ID.
type: str
extends_documentation_fragment:
- azure.azcollection.azure

author:
- Cole Neubauer(@coleneubauer)

'''

EXAMPLES = '''
- name: get ad user info
azure_rm_adserviceprincipal_info:
app_id: "{{ app_id }}"
tenant: "{{ tenant_id }}"

'''

RETURN = '''
app_role_assignment_required:
description:
- Whether the Role of the Service Principal is set.
type: bool
returned: always
sample: false
object_id:
description:
- It's service principal's object ID.
returned: always
type: str
sample: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx


'''

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

try:
from msrestazure.azure_exceptions import CloudError
from azure.graphrbac.models import GraphErrorException
except ImportError:
# This is handled in azure_rm_common
pass


class AzureRMADUserInfo(AzureRMModuleBase):
def __init__(self):

self.module_arg_spec = dict(
user_principle_name=dict(type='str'),
object_id=dict(type='str'),
attribute_name=dict(type='str'),
attribute_value=dict(type='str'),
odata_filter=dict(type='str'),
tenant=dict(type='str', required=True),
)

self.tenant = None
self.user_principle_name = None
self.object_id = None
self.attribute_name = None
self.attribute_value = None
self.odata_filter = None

self.results = dict(changed=False)

# TODO: limit object id, user_principle_name, and filter params
# TODO: add tests
# TODO: documentation
# TODO: cleanup
# TODO: consider adding a "filter" parameter for more complex limits.
# Would probably be easier for most to do the query directly

super(AzureRMADUserInfo, self).__init__(derived_arg_spec=self.module_arg_spec,
supports_check_mode=False,
supports_tags=False,
is_ad_resource=True)

def exec_module(self, **kwargs):

for key in list(self.module_arg_spec.keys()):
setattr(self, key, kwargs[key])

ad_users = []

try:
client = self.get_graphrbac_client(self.tenant)

if self.user_principle_name is not None:
ad_users = [client.users.get(self.user_principle_name)]
elif self.object_id is not None:
ad_users = [client.users.get(self.object_id)]
elif self.attribute_name is not None and self.attribute_value is not None:
try:
ad_users = list(client.users.list(filter="{0} eq '{1}'".format(self.attribute_name, self.attribute_value)))
except GraphErrorException as e:
# the type doesn't get more specific. Could check the error message but no guarantees that message doesn't change in the future
# more stable to try again assuming the first error came from the attribute being a list
try:
ad_users = list(client.users.list(filter="{0}/any(c:c eq '{1}')".format(self.attribute_name, self.attribute_value)))
except GraphErrorException as sub_e:
raise # TODO add previous failure message as well before raising
else: # run a filter based on user input to return based on any given attribute/query
ad_users = list(client.users.list(filter=self.odata_filter))

self.results['ad_users'] = [self.to_dict(user) for user in ad_users]

except GraphErrorException as e:
self.fail("failed to get ad user info {0}".format(str(e)))

return self.results

def to_dict(self, object):
return dict(
object_id=object.object_id,
display_name=object.display_name,
user_principal_name=object.user_principal_name,
mail_nickname=object.mail_nickname,
mail=object.mail,
account_enabled=object.account_enabled,
user_type=object.user_type
)


def main():
AzureRMADUserInfo()


if __name__ == '__main__':
main()