Ansible/modules/okta_users.py

456 lines
14 KiB
Python

#!/usr/bin/python
# (c) 2019, Whitney Champion <whitney.ellis.champion@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = """
module: okta_users
short_description: Communicate with the Okta API to manage users
description:
- The Okta user module manages Okta users
version_added: "1.0"
author: "Whitney Champion (@shortstack)"
options:
organization:
description:
- Okta subdomain for your organization. (i.e.
mycompany.okta.com).
required: false
default: None
api_key:
description:
- Okta API key.
required: false
default: None
action:
description:
- Action to take against user API.
required: false
default: list
choices: [ create, update, delete, list, activate, deactivate ]
id:
description:
- ID of the user.
required: false
default: None
login:
description:
- Username.
required: false
default: None
activate:
description:
- Whether or not the new user is activate.
required: false
default: yes
password:
description:
- Password.
required: false
default: None
first_name:
description:
- First name.
required: false
default: None
last_name:
description:
- Last name.
required: false
default: None
email:
description:
- Email.
required: false
default: None
group_ids:
description:
- List of Group IDs to add the user to.
required: false
default: None
limit:
description:
- List limit.
required: false
default: 25
"""
EXAMPLES = '''
# List users
- okta_users:
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
limit: 25
# Create user
- okta_users:
action: create
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
login: "whitney@unicorns.lol"
first_name: "Whitney"
last_name: "Champion"
email: "whitney@unicorns.lol"
password: "cookiesaredelicious"
activate: yes
# Create user in group(s)
- okta_users:
action: create
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
login: "whitney@unicorns.lol"
first_name: "Whitney"
last_name: "Champion"
email: "whitney@unicorns.lol"
password: "cookiesaredelicious"
group_ids:
- "00f5b3gqiLpE114tV2M7"
activate: yes
# Create multiple users in group
- okta_users:
action: create
organization: "crypto"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
login: "{{ item.login }}"
first_name: "{{ item.first_name }}"
last_name: "{{ item.last_name }}"
email: "{{ item.email }}"
password: "{{ item.password }}"
group_ids:
- "00f5b3gqiLpE324tV2M7"
activate: "{{ item.activate }}"
with_items:
- { login: "alice@aol.com", first_name: "Alice", last_name: "A", email: "alice@aolcom", password: "ilovebob111", activate: yes }
- { login: "bob@aol.com", first_name: "Bob", last_name: "B", email: "bob@aolcom", password: "ilovealice111", activate: yes }
# Update user's email address
- okta_users:
action: update
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
id: "01c5pEucucMPWXjFM456"
email: "whitney@ihateunicorns.lol"
# Activate user
- okta_users:
action: activate
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
id: "01c5pEucucMPWXjFM456"
# Deactivate user
- okta_users:
action: deactivate
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
id: "01c5pEucucMPWXjFM456"
# Delete user
- okta_users:
action: delete
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
id: "01c5pEucucMPWXjFM456"
# Get a list of groups a user is in
- okta_users:
action: usergroups
organization: "unicorns"
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
id: "01c5pEucucMPWXjFM456"
'''
RETURN = r'''
json:
description: The JSON response from the Okta API
returned: always
type: complex
msg:
description: The HTTP message from the request
returned: always
type: str
sample: OK (unknown bytes)
status:
description: The HTTP status code from the request
returned: always
type: int
sample: 200
url:
description: The actual URL used for the request
returned: always
type: str
sample: https://www.ansible.com/
'''
def create(module,base_url,api_key,login,password_input,email,first_name,last_name,group_ids,activate):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
payload = {}
profile = {}
credentials = {}
password = {}
groupIds= []
if first_name is not None:
profile['firstName'] = first_name
if last_name is not None:
profile['lastName'] = last_name
if email is not None:
profile['email'] = email
if login is not None:
profile['login'] = login
if password_input is not None:
password['value'] = password_input
if group_ids is not None:
groupIds = group_ids
credentials['password'] = password
payload['credentials'] = credentials
payload['groupIds'] = groupIds
payload['profile'] = profile
url = base_url+"?activate=%s" % (activate)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='POST', data=module.jsonify(payload))
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def update(module,base_url,api_key,id,login,email,first_name,last_name):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"/%s" % (id)
payload = {}
profile = {}
if first_name is not None:
profile['firstName'] = first_name
if last_name is not None:
profile['lastName'] = last_name
if email is not None:
profile['email'] = email
if login is not None:
profile['login'] = login
payload['profile'] = profile
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='POST', data=module.jsonify(payload))
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def delete(module,base_url,api_key,id):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"/%s" % (id)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='DELETE')
if info['status'] != 204:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def activate(module,base_url,api_key,id):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"/%s/lifecycle/activate" % (id)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='POST')
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def deactivate(module,base_url,api_key,id):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"/%s/lifecycle/deactivate" % (id)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='POST')
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def list(module,base_url,api_key,limit):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"/?limit=%s" % (limit)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='GET')
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def findByLogin(module, base_url, api_key, login):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
#url = base_url+"?q=%s&limit=1" % (login)
url = base_url+"?filter=profile.login+eq+\"%s\"" % (login)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='GET')
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def findByName(module, base_url, api_key, Name):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"?q=%s&limit=1" % (Name)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='GET')
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def getusergroups(module, base_url, api_key, id):
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
url = base_url+"/%s/groups" % (id)
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='GET')
if info['status'] != 200:
module.fail_json(msg="Fail: %s" % ( "Status: "+str(info['msg']) + ", Message: " + str(info['body'])))
try:
content = response.read()
except AttributeError:
content = info.pop('body', '')
return info['status'], info['msg'], content, url
def main():
module = AnsibleModule(
argument_spec = dict(
organization = dict(type='str', default=None),
api_key = dict(type='str', no_log=True),
action = dict(type='str', default='list', choices=['create', 'update', 'delete', 'list', 'activate', 'deactivate', 'usergroups']),
id = dict(type='str', default=None),
login = dict(type='str', default=None),
password = dict(type='str', default=None, no_log=True),
first_name = dict(type='str', default=None),
last_name = dict(type='str', default=None),
email = dict(type='str', default=None),
group_ids = dict(type='list', default=None),
limit = dict(type='int', default=25),
activate = dict(type='bool', default='yes')
)
)
organization = module.params['organization']
api_key = module.params['api_key']
action = module.params['action']
id = module.params['id']
login = module.params['login']
password = module.params['password']
first_name = module.params['first_name']
last_name = module.params['last_name']
email = module.params['email']
group_ids = module.params['group_ids']
limit = module.params['limit']
activate = module.params['activate']
base_url = "https://%s-admin.okta.com/api/v1/users" % (organization)
if action == "create":
status, message, content, url = create(module,base_url,api_key,login,password,email,first_name,last_name,group_ids,activate)
elif action == "update":
status, message, content, url = update(module,base_url,api_key,id,login,email,first_name,last_name)
elif action == "delete":
status, message, content, url = deactivate(module,base_url,api_key,id)
status, message, content, url = delete(module,base_url,api_key,id)
elif action == "activate":
status, message, content, url = activate(module,base_url,api_key,id)
elif action == "deactivate":
status, message, content, url = deactivate(module,base_url,api_key,id)
elif action == "list":
if login is not None:
status, message, content, url = findByLogin(module,base_url,api_key,login)
elif first_name is not None:
status, message, content, url = findByName(module,base_url,api_key, first_name)
elif last_name is not None:
status, message, content, url = findByName(module,base_url,api_key,last_name)
else:
status, message, content, url = list(module,base_url,api_key,limit)
elif action == "usergroups":
status, message, content, url = getusergroups(module, base_url, api_key, id)
uresp = {}
content = to_text(content, encoding='UTF-8')
try:
js = json.loads(content)
except ValueError, e:
js = ""
uresp['json'] = js
uresp['status'] = status
uresp['msg'] = message
uresp['url'] = url
module.exit_json(**uresp)
# import module snippets
import json
from ansible.module_utils.basic import *
from ansible.module_utils.urls import *
if __name__ == '__main__':
main()