Added some Okta work. This lets Ansible become the source of truth soon. Need to work the api module to exact search rather then a fuzzy search. Started to get back into docker to maintain homelab.
This commit is contained in:
parent
2081ea949b
commit
c95f1099a0
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"cSpell.ignoreWords": [
|
||||||
|
"ansible",
|
||||||
|
"okta",
|
||||||
|
"specialcounsel",
|
||||||
|
"vault"
|
||||||
|
]
|
||||||
|
}
|
@ -11,8 +11,11 @@
|
|||||||
|
|
||||||
# some basic default values...
|
# some basic default values...
|
||||||
|
|
||||||
inventory = ./hosts
|
inventory = ./inventory/
|
||||||
library = /usr/share/my_modules/
|
#library = /usr/share/my_modules/:./modules/
|
||||||
|
|
||||||
|
# Looks like modules can only be pointed to a single directory
|
||||||
|
library = ./modules/
|
||||||
module_utils = /usr/share/my_module_utils/
|
module_utils = /usr/share/my_module_utils/
|
||||||
remote_tmp = ~/.ansible/tmp
|
remote_tmp = ~/.ansible/tmp
|
||||||
local_tmp = ~/.ansible/tmp
|
local_tmp = ~/.ansible/tmp
|
||||||
@ -255,7 +258,7 @@ vault_password_file = ./.ansible_vault
|
|||||||
# You can enable this feature by setting retry_files_enabled to True
|
# You can enable this feature by setting retry_files_enabled to True
|
||||||
# and you can change the location of the files by setting retry_files_save_path
|
# and you can change the location of the files by setting retry_files_save_path
|
||||||
|
|
||||||
#retry_files_enabled = False
|
retry_files_enabled = False
|
||||||
#retry_files_save_path = ~/.ansible-retry
|
#retry_files_save_path = ~/.ansible-retry
|
||||||
|
|
||||||
# squash actions
|
# squash actions
|
||||||
|
46
dev.yml
46
dev.yml
@ -1,46 +0,0 @@
|
|||||||
---
|
|
||||||
all:
|
|
||||||
hosts:
|
|
||||||
dmi-dev01:
|
|
||||||
children:
|
|
||||||
linux:
|
|
||||||
hosts:
|
|
||||||
172.20.0.142:
|
|
||||||
vars:
|
|
||||||
ansible_user: ansible
|
|
||||||
ansible_connection: ssh
|
|
||||||
ansible_password: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
33353561613531336536313335356236643530346538373638653330306636386435633965336136
|
|
||||||
3464366635373661383466333464663238663565343839310a376666386237313566386235633739
|
|
||||||
66323434636365303335326133396137393031396531313533326263363066636237313139353538
|
|
||||||
6134616232336365610a363033343639616563316330363966326330646162613034633532366230
|
|
||||||
3439
|
|
||||||
ansible_become_method: sudo
|
|
||||||
ansible_become_pass: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
33353561613531336536313335356236643530346538373638653330306636386435633965336136
|
|
||||||
3464366635373661383466333464663238663565343839310a376666386237313566386235633739
|
|
||||||
66323434636365303335326133396137393031396531313533326263363066636237313139353538
|
|
||||||
6134616232336365610a363033343639616563316330363966326330646162613034633532366230
|
|
||||||
3439
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
windows:
|
|
||||||
hosts:
|
|
||||||
dmi-dev01:
|
|
||||||
vars:
|
|
||||||
ansible_user: svcansible
|
|
||||||
ansible_password: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
33353561613531336536313335356236643530346538373638653330306636386435633965336136
|
|
||||||
3464366635373661383466333464663238663565343839310a376666386237313566386235633739
|
|
||||||
66323434636365303335326133396137393031396531313533326263363066636237313139353538
|
|
||||||
6134616232336365610a363033343639616563316330363966326330646162613034633532366230
|
|
||||||
3439
|
|
||||||
ansible_connection: winrm
|
|
||||||
ansible_port: 5985
|
|
||||||
ansible_winrm_scheme: http
|
|
||||||
ansible_winrm_transport: ntlm
|
|
||||||
ansible_winrm_server_cert_validation: ignore
|
|
||||||
|
|
||||||
|
|
32
inventory/home.yaml
Normal file
32
inventory/home.yaml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
all:
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
children:
|
||||||
|
linux:
|
||||||
|
192.160.0.60
|
||||||
|
vars:
|
||||||
|
ansible_user: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
33393963653363383638373235363531386238626138366632336531663437373634333766656437
|
||||||
|
3462613266323931343431616465623439626534646238640a616461633434626631376266383234
|
||||||
|
61386535373738386632626331353665643137373234323566326633386234666534616330306639
|
||||||
|
3739633437353337380a373437643563663163653834653637363861663639363635333866613435
|
||||||
|
6636
|
||||||
|
ansible_password: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
62386164373234666130346666653866663136623261386364636632303430616135343132303631
|
||||||
|
3632316465666237613232313761353135316433376562360a633931646238326139336532373633
|
||||||
|
32666636326332346536366165373030346265626633646335303033636337333336323164636338
|
||||||
|
3036393466633634640a313262373661623731623639343565653061663830303537666136346165
|
||||||
|
3834
|
||||||
|
ansible_connection: ssh
|
||||||
|
ansible_become_method: sudo
|
||||||
|
ansible_become_pass: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
62386164373234666130346666653866663136623261386364636632303430616135343132303631
|
||||||
|
3632316465666237613232313761353135316433376562360a633931646238326139336532373633
|
||||||
|
32666636326332346536366165373030346265626633646335303033636337333336323164636338
|
||||||
|
3036393466633634640a313262373661623731623639343565653061663830303537666136346165
|
||||||
|
3834
|
||||||
|
ansible_python_interpreter: /usr/bin/python3
|
317
modules/okta_groups.py
Normal file
317
modules/okta_groups.py
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
#!/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_groups
|
||||||
|
short_description: Communicate with the Okta API to manage groups
|
||||||
|
description:
|
||||||
|
- The Okta groups module manages Okta groups
|
||||||
|
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 groups API.
|
||||||
|
required: false
|
||||||
|
default: list
|
||||||
|
choices: [ create, update, delete, list, add_user, remove_user ]
|
||||||
|
id:
|
||||||
|
description:
|
||||||
|
- ID of the group.
|
||||||
|
required: false
|
||||||
|
default: None
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Group name.
|
||||||
|
required: false
|
||||||
|
default: None
|
||||||
|
description:
|
||||||
|
description:
|
||||||
|
- Group description.
|
||||||
|
required: false
|
||||||
|
default: yes
|
||||||
|
limit:
|
||||||
|
description:
|
||||||
|
- List limit.
|
||||||
|
required: false
|
||||||
|
default: 200
|
||||||
|
user_id:
|
||||||
|
description:
|
||||||
|
- ID of user to add to group.
|
||||||
|
required: false
|
||||||
|
default: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
# List groups
|
||||||
|
- okta_groups:
|
||||||
|
organization: "unicorns"
|
||||||
|
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
|
||||||
|
limit: 200
|
||||||
|
|
||||||
|
# Create group
|
||||||
|
- okta_groups:
|
||||||
|
action: create
|
||||||
|
organization: "unicorns"
|
||||||
|
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
|
||||||
|
name: "Imaginary Creatures"
|
||||||
|
description: "They are so majestic"
|
||||||
|
|
||||||
|
# Update group
|
||||||
|
- okta_groups:
|
||||||
|
action: update
|
||||||
|
organization: "unicorns"
|
||||||
|
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
|
||||||
|
id: "01c5pEucucMPWXjFM457"
|
||||||
|
name: "Imaginary Creatures"
|
||||||
|
description: "They are so majestic and beautiful"
|
||||||
|
|
||||||
|
# Add user to group
|
||||||
|
- okta_groups:
|
||||||
|
action: add_user
|
||||||
|
organization: "unicorns"
|
||||||
|
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
|
||||||
|
id: "01c5pEucucMPWXjFM457"
|
||||||
|
user_id: "01c5pEucucMPWXjFM456"
|
||||||
|
|
||||||
|
# Remove user from group
|
||||||
|
- okta_groups:
|
||||||
|
action: remove_user
|
||||||
|
organization: "unicorns"
|
||||||
|
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
|
||||||
|
id: "01c5pEucucMPWXjFM457"
|
||||||
|
user_id: "01c5pEucucMPWXjFM456"
|
||||||
|
|
||||||
|
# Delete group
|
||||||
|
- okta_groups:
|
||||||
|
action: delete
|
||||||
|
organization: "unicorns"
|
||||||
|
api_key: "TmHvH4LY9HH9MDRDiLChLGwhRjHsarTCBzpwbua3ntnQ"
|
||||||
|
id: "01c5pEucucMPWXjFM457"
|
||||||
|
'''
|
||||||
|
|
||||||
|
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,name,description):
|
||||||
|
|
||||||
|
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
|
||||||
|
|
||||||
|
payload = {}
|
||||||
|
profile = {}
|
||||||
|
|
||||||
|
if name is not None:
|
||||||
|
profile['name'] = name
|
||||||
|
if description is not None:
|
||||||
|
profile['description'] = description
|
||||||
|
|
||||||
|
payload['profile'] = profile
|
||||||
|
|
||||||
|
url = base_url
|
||||||
|
|
||||||
|
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,name,description):
|
||||||
|
|
||||||
|
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
|
||||||
|
|
||||||
|
payload = {}
|
||||||
|
profile = {}
|
||||||
|
|
||||||
|
if name is not None:
|
||||||
|
profile['name'] = name
|
||||||
|
if description is not None:
|
||||||
|
profile['description'] = description
|
||||||
|
|
||||||
|
payload['profile'] = profile
|
||||||
|
|
||||||
|
url = base_url+"/%s" % (id)
|
||||||
|
|
||||||
|
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='PUT', 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') # 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 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 add_user(module,base_url,api_key,id,user_id):
|
||||||
|
|
||||||
|
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
|
||||||
|
|
||||||
|
url = base_url+"/%s/users/%s" % (id,user_id)
|
||||||
|
|
||||||
|
response, info = fetch_url(module=module, url=url, headers=json.loads(headers), method='PUT')
|
||||||
|
|
||||||
|
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 remove_user(module,base_url,api_key,id,user_id):
|
||||||
|
|
||||||
|
headers = '{ "Content-Type": "application/json", "Authorization": "SSWS %s", "Accept": "application/json" }' % (api_key)
|
||||||
|
|
||||||
|
url = base_url+"/%s/users/%s" % (id,user_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 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', 'add_user', 'remove_user']),
|
||||||
|
id = dict(type='str', default=None),
|
||||||
|
user_id = dict(type='str', default=None),
|
||||||
|
name = dict(type='str', default=None),
|
||||||
|
description = dict(type='str', default=None),
|
||||||
|
limit = dict(type='int', default=200)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
organization = module.params['organization']
|
||||||
|
api_key = module.params['api_key']
|
||||||
|
action = module.params['action']
|
||||||
|
id = module.params['id']
|
||||||
|
user_id = module.params['user_id']
|
||||||
|
name = module.params['name']
|
||||||
|
description = module.params['description']
|
||||||
|
limit = module.params['limit']
|
||||||
|
|
||||||
|
base_url = "https://%s-admin.okta.com/api/v1/groups" % (organization)
|
||||||
|
|
||||||
|
if action == "create":
|
||||||
|
status, message, content, url = create(module,base_url,api_key,name,description)
|
||||||
|
elif action == "update":
|
||||||
|
status, message, content, url = update(module,base_url,api_key,id,name,description)
|
||||||
|
elif action == "delete":
|
||||||
|
status, message, content, url = delete(module,base_url,api_key,id)
|
||||||
|
elif action == "list":
|
||||||
|
status, message, content, url = list(module,base_url,api_key,limit)
|
||||||
|
elif action == "add_user":
|
||||||
|
status, message, content, url = add_user(module,base_url,api_key,id,user_id)
|
||||||
|
elif action == "remove_user":
|
||||||
|
status, message, content, url = remove_user(module,base_url,api_key,id,user_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()
|
455
modules/okta_users.py
Normal file
455
modules/okta_users.py
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
#!/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()
|
47
playbook/docker/mediaserver/hydra.yml
Normal file
47
playbook/docker/mediaserver/hydra.yml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
# https://github.com/linuxserver/docker-hydra2
|
||||||
|
- name: Media Server
|
||||||
|
hosts: localhost
|
||||||
|
vars_files:
|
||||||
|
- vars.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: pip docker
|
||||||
|
pip:
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
- name: Hydra Config
|
||||||
|
docker_volume:
|
||||||
|
name: "{{ hydra_config }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Volume Shared Downloads
|
||||||
|
docker_volume:
|
||||||
|
name: "{{ shared_downloads }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Hydra Network
|
||||||
|
docker_network:
|
||||||
|
name: "{{ network }}"
|
||||||
|
|
||||||
|
- name: stop hydra
|
||||||
|
docker_container:
|
||||||
|
name: hydra
|
||||||
|
state: stopped
|
||||||
|
|
||||||
|
- name: Make Hydra
|
||||||
|
docker_container:
|
||||||
|
name: hydra
|
||||||
|
image: linuxserver/hydra2
|
||||||
|
state: started
|
||||||
|
env:
|
||||||
|
PUID=1000
|
||||||
|
PGID=1000
|
||||||
|
TZ=Europe/London
|
||||||
|
ports:
|
||||||
|
- 5076:5076
|
||||||
|
volumes:
|
||||||
|
- "{{ hydra_config }}:/config"
|
||||||
|
- "{{ shared_downloads }}:/downloads"
|
||||||
|
networks:
|
||||||
|
- name: "{{ network }}"
|
12
playbook/docker/mediaserver/vars.yml
Normal file
12
playbook/docker/mediaserver/vars.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
# Volumes
|
||||||
|
sonarr_data: sonarr_data
|
||||||
|
sonarr_config: sonarr_config
|
||||||
|
|
||||||
|
osx_sonarr_data: ~/doc
|
||||||
|
|
||||||
|
hydra_config: hydra_config
|
||||||
|
shared_downloads: media_downloads
|
||||||
|
|
||||||
|
# Networks
|
||||||
|
network: net_hydra
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
- name: Deploy OwnCloud
|
|
||||||
hosts: linux
|
|
||||||
become_method: sudo
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if docker is installed.
|
|
||||||
apt:
|
|
||||||
name: docker
|
|
||||||
state: present
|
|
||||||
|
|
||||||
|
|
41
playbook/localhost/okta/debug.yml
Normal file
41
playbook/localhost/okta/debug.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
- name: maintain okta users
|
||||||
|
hosts: localhost
|
||||||
|
vars_files:
|
||||||
|
- okta_vars.yml
|
||||||
|
|
||||||
|
vars:
|
||||||
|
first_name: API
|
||||||
|
last_name: Test
|
||||||
|
email: "{{ email_deleteme }}"
|
||||||
|
login: "{{ email_deleteme }}"
|
||||||
|
isActive: True
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Check for {{ login }}
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
action: list
|
||||||
|
login: "{{ login }}"
|
||||||
|
register: oktalist
|
||||||
|
|
||||||
|
- name: debug
|
||||||
|
debug:
|
||||||
|
msg: "{{ oktalist }}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# if the account is not found, make it
|
||||||
|
#- name: Create {{ login }}
|
||||||
|
# okta_users:
|
||||||
|
## organization: "{{ organization }}"
|
||||||
|
# api_key: "{{ api_key }}"
|
||||||
|
# action: create
|
||||||
|
# login: "{{ login }}"
|
||||||
|
# email: "{{ email }}"
|
||||||
|
# first_name: "{{ first_name }}"
|
||||||
|
# last_name: "{{ last_name }}"
|
||||||
|
# when:
|
||||||
|
# - oktalist['json'] is not defined
|
||||||
|
# - isActive|bool == True
|
18
playbook/localhost/okta/debugGroupResult.yml
Normal file
18
playbook/localhost/okta/debugGroupResult.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
- name: Debug Okta Groups
|
||||||
|
hosts: localhost
|
||||||
|
vars_files: okta_vars.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Get Okta Group
|
||||||
|
okta_groups:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
action: list
|
||||||
|
limit: 200
|
||||||
|
register: res
|
||||||
|
|
||||||
|
- name: show res
|
||||||
|
debug:
|
||||||
|
msg: "{{ item.profile.name }} {{ item.id }}"
|
||||||
|
loop: "{{ res.json }}"
|
32
playbook/localhost/okta/debugUserResult.yml
Normal file
32
playbook/localhost/okta/debugUserResult.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
- name: Show okta_users result
|
||||||
|
hosts: localhost
|
||||||
|
vars_files: okta_vars.yml
|
||||||
|
|
||||||
|
#include_vars: okta_vars.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: list 1
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
action: list
|
||||||
|
email: "{{ email_deleteme }}"
|
||||||
|
#limit: 1
|
||||||
|
register: res
|
||||||
|
|
||||||
|
- name: display result
|
||||||
|
debug:
|
||||||
|
msg: "{{ res.json }}"
|
||||||
|
|
||||||
|
- name: user groups
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
action: usergroups
|
||||||
|
id: "{{ res.json.0.id }}"
|
||||||
|
register: grps
|
||||||
|
|
||||||
|
- name: display groups
|
||||||
|
debug:
|
||||||
|
msg: "{{ grps }}"
|
13
playbook/localhost/okta/grouptest.yml
Normal file
13
playbook/localhost/okta/grouptest.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Group Test
|
||||||
|
hosts: localhost
|
||||||
|
vars_files: okta_vars.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: add group
|
||||||
|
okta_groups:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
action: add_user
|
||||||
|
id: "00g1jfcegwGw1Lsuh357"
|
||||||
|
user_id: 00u1kekdg8ewrmdmt357
|
39
playbook/localhost/okta/okta_role.yml
Normal file
39
playbook/localhost/okta/okta_role.yml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
- name: maintain okta users
|
||||||
|
hosts: localhost
|
||||||
|
vars_files:
|
||||||
|
- okta_vars.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: manage delete.me
|
||||||
|
include_role:
|
||||||
|
name: luther38.okta
|
||||||
|
vars:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
first_name: API
|
||||||
|
last_name: Test
|
||||||
|
email: "{{ email_deleteme }}"
|
||||||
|
login: "{{ email_deleteme }}"
|
||||||
|
isActive: True
|
||||||
|
add_groups:
|
||||||
|
#- 00g1jfcegwGw1Lsuh357
|
||||||
|
remove_groups:
|
||||||
|
- 00g1jfcegwGw1Lsuh357
|
||||||
|
|
||||||
|
- name: delete me2
|
||||||
|
include_role:
|
||||||
|
name: luther38.okta
|
||||||
|
vars:
|
||||||
|
organization: "{{ org }}"
|
||||||
|
api_key: "{{ api }}"
|
||||||
|
first_name: API
|
||||||
|
last_name: Test2
|
||||||
|
email: "{{ email_deleteme2 }}"
|
||||||
|
login: "{{ email_deleteme2 }}"
|
||||||
|
isActive: True
|
||||||
|
add_groups:
|
||||||
|
#- 00g1jfcegwGw1Lsuh357
|
||||||
|
remove_groups:
|
||||||
|
- 00g1jfcegwGw1Lsuh357
|
||||||
|
|
25
playbook/localhost/okta/okta_vars.yml
Normal file
25
playbook/localhost/okta/okta_vars.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
org: specialcounsel
|
||||||
|
api: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
38653364346561346262373864383039383062363465656531393561313162313764363230616461
|
||||||
|
3861383930646331366132626132346430313238366439320a363636363938363431646631316362
|
||||||
|
30663937343631353430326161616331373539343064613663393862653364643838623335303639
|
||||||
|
6561326532373939630a633134323530303632653733663039323238363961373832386638666535
|
||||||
|
61646234656263643439613135303934323264303235313737656238366462633365333762646162
|
||||||
|
6461376235383531643464396638323162373364373433353934
|
||||||
|
|
||||||
|
email_deleteme: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
61326435326361386537303861313332643434316433643737356434333836346435626361396539
|
||||||
|
6536373565343363366433343931643363653465636264320a363466646337633138663134666263
|
||||||
|
64613133383336653132366663393734343135633932323731326164653137323936366432613765
|
||||||
|
3737653131353635370a656339366330373761326135653739313731613230383561306431646165
|
||||||
|
36656339616330393539336563343663303638626337336564306234376161383634
|
||||||
|
|
||||||
|
email_demeteme2: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
39646663353734646332613430656433356265623235383931636334653463393030653733653963
|
||||||
|
6638326232613733613462363133663833323532653939620a646239303535626462636331616562
|
||||||
|
36353836393333333664386131376139323662336538373435653939626565363837356234306531
|
||||||
|
6539386434623366320a303438643832353732393833353434363662326635666430613333636431
|
||||||
|
61366265643632363939666534613138623262626230613739373833363538383030
|
7
playbook/localhost/readme.md
Normal file
7
playbook/localhost/readme.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# localhost
|
||||||
|
|
||||||
|
The playbooks found here are not working against another host to maintain the configuration. They only need the ansible host that contains the playbook and some modules.
|
||||||
|
|
||||||
|
## Okta
|
||||||
|
|
||||||
|
These playbooks work with Okta's REST API so you do not need to jump into another server.
|
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#TODO The job seems to stop here for some reason
|
#TODO The job seems to stop here for some reason
|
||||||
- name: remove cask - dotnet-sdk
|
- name: remove cask - dotnet-sdk
|
||||||
|
become: true
|
||||||
homebrew_cask:
|
homebrew_cask:
|
||||||
name: dotnet-sdk
|
name: dotnet-sdk
|
||||||
state: absent
|
state: absent
|
||||||
|
12
roles/luther38.okta/defaults/main.yml
Normal file
12
roles/luther38.okta/defaults/main.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
organization: ''
|
||||||
|
api_key: ''
|
||||||
|
|
||||||
|
first_name: ''
|
||||||
|
last_name: ''
|
||||||
|
email: ''
|
||||||
|
login: ''
|
||||||
|
status: ''
|
||||||
|
|
||||||
|
add_groups:
|
||||||
|
remove_groups:
|
90
roles/luther38.okta/tasks/main.yml
Normal file
90
roles/luther38.okta/tasks/main.yml
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
- name: Check for {{ login }}
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
action: list
|
||||||
|
login: "{{ login }}"
|
||||||
|
register: oktalist
|
||||||
|
|
||||||
|
# if the account is not found, make it
|
||||||
|
- name: Create {{ login }}
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
action: create
|
||||||
|
login: "{{ login }}"
|
||||||
|
email: "{{ email }}"
|
||||||
|
first_name: "{{ first_name }}"
|
||||||
|
last_name: "{{ last_name }}"
|
||||||
|
when:
|
||||||
|
- oktalist['json'] is not defined
|
||||||
|
- isActive|bool == True
|
||||||
|
|
||||||
|
- name: Update {{ login }} first_name
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
action: update
|
||||||
|
id: "{{ oktalist.json.0.id }}"
|
||||||
|
first_name: "{{ first_name }}"
|
||||||
|
when:
|
||||||
|
- oktalist.json.0.profile.firstName != first_name
|
||||||
|
- isActive|bool == True
|
||||||
|
|
||||||
|
- name: Update {{ login }} last_name
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
action: update
|
||||||
|
id: "{{ oktalist.json.0.id }}"
|
||||||
|
last_name: "{{ last_name }}"
|
||||||
|
when:
|
||||||
|
- oktalist.json.0.profile.lastName != last_name
|
||||||
|
- isActive|bool == True
|
||||||
|
|
||||||
|
- name: Update {{ login }} email
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
action: update
|
||||||
|
id: "{{ oktalist.json.0.id }}"
|
||||||
|
email: "{{ email }}"
|
||||||
|
when:
|
||||||
|
- oktalist.json.0.profile.email != email
|
||||||
|
- isActive|bool == True
|
||||||
|
|
||||||
|
- name: Disable {{ login }}
|
||||||
|
okta_users:
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
action: deactivate
|
||||||
|
id: "{{ oktalist.json.0.id }}"
|
||||||
|
when:
|
||||||
|
- oktalist.json is defined
|
||||||
|
- isActive|bool == False
|
||||||
|
|
||||||
|
- name: debug
|
||||||
|
debug:
|
||||||
|
msg: "{{ item }}"
|
||||||
|
with_items: "{{ add_groups }}"
|
||||||
|
|
||||||
|
- name: add groups
|
||||||
|
okta_groups:
|
||||||
|
action: add_user
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
user_id: "{{ oktalist.json.0.id }}"
|
||||||
|
id: "{{ item }}"
|
||||||
|
with_items: "{{ add_groups }}"
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: remove groups
|
||||||
|
okta_groups:
|
||||||
|
action: remove_user
|
||||||
|
organization: "{{ organization }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
|
user_id: "{{ oktalist.json.0.id }}"
|
||||||
|
id: "{{ item }}"
|
||||||
|
with_items: "{{ remove_groups }}"
|
||||||
|
ignore_errors: yes
|
Loading…
Reference in New Issue
Block a user