commit
23ee532279
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"cSpell.ignoreWords": [
|
||||
"ansible",
|
||||
"okta",
|
||||
"specialcounsel",
|
||||
"vault"
|
||||
]
|
||||
}
|
4230
ansible-vars.all
4230
ansible-vars.all
File diff suppressed because it is too large
Load Diff
11
ansible.cfg
11
ansible.cfg
@ -11,8 +11,11 @@
|
||||
|
||||
# some basic default values...
|
||||
|
||||
inventory = ./hosts
|
||||
library = /usr/share/my_modules/
|
||||
inventory = ./inventory/home.yaml
|
||||
#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/
|
||||
remote_tmp = ~/.ansible/tmp
|
||||
local_tmp = ~/.ansible/tmp
|
||||
@ -137,7 +140,7 @@ roles_path = ./roles/:/etc/ansible/roles
|
||||
|
||||
# If set, configures the path to the Vault password file as an alternative to
|
||||
# specifying --vault-password-file on the command line.
|
||||
#vault_password_file = ./.ansible_vault
|
||||
vault_password_file = ./.ansible_vault
|
||||
|
||||
# format of string {{ ansible_managed }} available within Jinja2
|
||||
# templates indicates to users editing templates files will be replaced.
|
||||
@ -255,7 +258,7 @@ roles_path = ./roles/:/etc/ansible/roles
|
||||
# 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
|
||||
|
||||
#retry_files_enabled = False
|
||||
retry_files_enabled = False
|
||||
#retry_files_save_path = ~/.ansible-retry
|
||||
|
||||
# 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
|
||||
|
||||
|
2
docs/playbook.md
Normal file
2
docs/playbook.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Playbooks
|
||||
|
40
docs/readme.md
Normal file
40
docs/readme.md
Normal file
@ -0,0 +1,40 @@
|
||||
# Ansible Docs
|
||||
|
||||
This is the location for my notes with ansible. Hopefully the things I work though will help someone else with learning how ansible functions.
|
||||
|
||||
## Playbooks
|
||||
|
||||
Playbooks should be viewed like the configuration file for you process. This where is where all of your variables and basic tests should be done. Do not treat roles like playbooks! More on that later.
|
||||
|
||||
### Documentation
|
||||
|
||||
YAML allows us to use `#` as a comment value, make use of it. You can write notes for your team about a task with comments. Use them, it wont hurt.
|
||||
|
||||
When you are writing a playbook and you need a quick refresher on what the syntax that a module supports use `ansible-doc moduleName` command. Example: `ansible-doc pip`
|
||||
|
||||
This will give you a quick way to see what flags are supported without having to go to the browser to find out.
|
||||
|
||||
## Vault
|
||||
|
||||
Vaults are a great way to store secrets in your source code. Never store insecure secrets in a file other then for quick testing. Even then, don't put un-encrypted secrets in public locations.
|
||||
|
||||
### Config changes
|
||||
|
||||
Before you use ansible-value you will want to update your ansible.cfg file. Uncomment ```#vault_password_file``` and update it to where you will store your secret file. This is a file that should be added to ```.gitignore``` so that the password is stored safely. For reference I use .ansible_vault as my file and you can see my .gitignore file to see how I ignore it.
|
||||
|
||||
### How to use Vault
|
||||
|
||||
Make sure you adjusted your ansible.cfg before doing this. That password is how vault decrypts values.
|
||||
|
||||
```bash
|
||||
echo 'secret' > .ansible_vault
|
||||
ansible-value encrypt_string 'sshPassword'
|
||||
```
|
||||
|
||||
With the value that was exported you would add that to the playbook that needs to be able to decrypt the secret to use it.
|
||||
Something to note. When the password that is stored in .ansible_vault that is defined in ansible.cfg changes, the vault might start to fail to decrypt strings. I have not made it that far yet with vault to confirm how much this is true.
|
||||
|
||||
## Roles
|
||||
|
||||
Roles are very important when it comes to Ansible. If you need to define how say pip handles actions you would build a role for it. With that role you can define how pip would work. Do not treat roles as your playbook. They are meant to be used as a guide and the playbook passes variables to the role to tell it how something should be configured.
|
||||
|
@ -7,7 +7,7 @@ all:
|
||||
hosts:
|
||||
172.20.0.142:
|
||||
vars:
|
||||
ansible_user: ansible
|
||||
ansible_user:
|
||||
ansible_connection: ssh
|
||||
ansible_password:
|
||||
ansible_become_method: sudo
|
||||
@ -17,7 +17,7 @@ all:
|
||||
hosts:
|
||||
dev01:
|
||||
vars:
|
||||
ansible_user: ansible
|
||||
ansible_user:
|
||||
ansible_password:
|
||||
ansible_connection: winrm
|
||||
ansible_port: 5985
|
89
inventory/home.yaml
Normal file
89
inventory/home.yaml
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
all:
|
||||
children:
|
||||
linux-all:
|
||||
hosts:
|
||||
192.168.0.60:
|
||||
192.168.0.76:
|
||||
vars:
|
||||
ansible_user: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
32323438633437386234366165646365303038656639396632313933396431376136343837393738
|
||||
6131653037623836383032613766653233656338303566330a653938333062363432643365316133
|
||||
61626164383063636362343362663133653964646139386635626365373564306238306566633930
|
||||
3139363666373864620a656336653633376539616337303361333936313462623963643861646166
|
||||
3364
|
||||
ansible_password: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63363131623134643365366432393962613032383931613663353233356334316536326334333739
|
||||
3130663431363561373437353262313430623131363864350a393064636161613232633036303139
|
||||
65643166363565343562663937343866623035356639333635636432333363653463666433303035
|
||||
6134646432353330630a343839643163323733623265356261306661396332326465656561633734
|
||||
6231
|
||||
ansible_connection: ssh
|
||||
ansible_become_method: sudo
|
||||
ansible_become_pass: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63363131623134643365366432393962613032383931613663353233356334316536326334333739
|
||||
3130663431363561373437353262313430623131363864350a393064636161613232633036303139
|
||||
65643166363565343562663937343866623035356639333635636432333363653463666433303035
|
||||
6134646432353330630a343839643163323733623265356261306661396332326465656561633734
|
||||
6231
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
docker:
|
||||
hosts:
|
||||
192.168.0.76:
|
||||
vars:
|
||||
ansible_user: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
32323438633437386234366165646365303038656639396632313933396431376136343837393738
|
||||
6131653037623836383032613766653233656338303566330a653938333062363432643365316133
|
||||
61626164383063636362343362663133653964646139386635626365373564306238306566633930
|
||||
3139363666373864620a656336653633376539616337303361333936313462623963643861646166
|
||||
3364
|
||||
ansible_password: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63363131623134643365366432393962613032383931613663353233356334316536326334333739
|
||||
3130663431363561373437353262313430623131363864350a393064636161613232633036303139
|
||||
65643166363565343562663937343866623035356639333635636432333363653463666433303035
|
||||
6134646432353330630a343839643163323733623265356261306661396332326465656561633734
|
||||
6231
|
||||
ansible_connection: ssh
|
||||
ansible_become_method: sudo
|
||||
ansible_become_pass: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63363131623134643365366432393962613032383931613663353233356334316536326334333739
|
||||
3130663431363561373437353262313430623131363864350a393064636161613232633036303139
|
||||
65643166363565343562663937343866623035356639333635636432333363653463666433303035
|
||||
6134646432353330630a343839643163323733623265356261306661396332326465656561633734
|
||||
6231
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
mediaserver:
|
||||
hosts:
|
||||
192.168.0.76:
|
||||
vars:
|
||||
ansible_user: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
32323438633437386234366165646365303038656639396632313933396431376136343837393738
|
||||
6131653037623836383032613766653233656338303566330a653938333062363432643365316133
|
||||
61626164383063636362343362663133653964646139386635626365373564306238306566633930
|
||||
3139363666373864620a656336653633376539616337303361333936313462623963643861646166
|
||||
3364
|
||||
ansible_password: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63363131623134643365366432393962613032383931613663353233356334316536326334333739
|
||||
3130663431363561373437353262313430623131363864350a393064636161613232633036303139
|
||||
65643166363565343562663937343866623035356639333635636432333363653463666433303035
|
||||
6134646432353330630a343839643163323733623265356261306661396332326465656561633734
|
||||
6231
|
||||
ansible_connection: ssh
|
||||
ansible_become_method: sudo
|
||||
ansible_become_pass: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63363131623134643365366432393962613032383931613663353233356334316536326334333739
|
||||
3130663431363561373437353262313430623131363864350a393064636161613232633036303139
|
||||
65643166363565343562663937343866623035356639333635636432333363653463666433303035
|
||||
6134646432353330630a343839643163323733623265356261306661396332326465656561633734
|
||||
6231
|
||||
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()
|
48
playbook/docker/mediaserver/hydra.yml
Normal file
48
playbook/docker/mediaserver/hydra.yml
Normal file
@ -0,0 +1,48 @@
|
||||
---
|
||||
# https://github.com/linuxserver/docker-hydra2
|
||||
- name: Media Server
|
||||
become: yes
|
||||
hosts: linux
|
||||
vars_files:
|
||||
- vars.yml
|
||||
|
||||
tasks:
|
||||
- name: pip docker-py - absent
|
||||
pip:
|
||||
name: docker-py
|
||||
state: absent
|
||||
executable: pip3
|
||||
|
||||
- name: pip docker - present
|
||||
pip:
|
||||
name: docker
|
||||
state: present
|
||||
executable: pip3
|
||||
|
||||
- name: Hydra Network
|
||||
docker_network:
|
||||
name: "{{ network }}"
|
||||
|
||||
- name: stop hydra
|
||||
docker_container:
|
||||
name: hydra
|
||||
state: stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Make Hydra
|
||||
docker_container:
|
||||
name: hydra
|
||||
image: 'linuxserver/hydra2:latest'
|
||||
state: started
|
||||
env:
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
TZ=Europe/London
|
||||
ports:
|
||||
- 5076:5076
|
||||
volumes:
|
||||
#- "{{ hydra_config }}:/config"
|
||||
- "/docker/hydra:/config"
|
||||
- "{{ shared_downloads }}:/downloads"
|
||||
networks:
|
||||
- name: "{{ network }}"
|
134
playbook/docker/mediaserver/mediaserver.yml
Normal file
134
playbook/docker/mediaserver/mediaserver.yml
Normal file
@ -0,0 +1,134 @@
|
||||
|
||||
- name: Configure Media Server
|
||||
hosts: mediaserver
|
||||
become: yes
|
||||
vars:
|
||||
dockerFolder: "/docker"
|
||||
dockerMount: "/docker/config"
|
||||
dockerPlex: "/docker/plex"
|
||||
nfsAddress: 192.168.0.16
|
||||
dockerNetwork: mediaserver
|
||||
|
||||
tasks:
|
||||
- name: install docker
|
||||
import_role:
|
||||
name: geerlingguy.docker
|
||||
become: yes
|
||||
|
||||
- name: make docker folder location
|
||||
file:
|
||||
path: "{{ dockerFolder }}"
|
||||
state: directory
|
||||
|
||||
- name: make docker config path
|
||||
file:
|
||||
path: "{{ dockerMount }}"
|
||||
state: directory
|
||||
|
||||
- name: mount nfs to /docker/config
|
||||
mount:
|
||||
src: "{{ nfsAddress }}:/docker/"
|
||||
path: "{{ dockerMount }}"
|
||||
fstype: nfs
|
||||
boot: yes
|
||||
state: mounted
|
||||
|
||||
- name: make plex mount point
|
||||
file:
|
||||
path: "{{ dockerPlex }}"
|
||||
state: directory
|
||||
|
||||
- name: mount nfs to /docker/plex
|
||||
mount:
|
||||
src: "{{nfsAddress }}:/plex/"
|
||||
path: "{{ dockerPlex }}"
|
||||
fstype: nfs
|
||||
boot: yes
|
||||
state: mounted
|
||||
|
||||
- name: install docker pip package
|
||||
pip:
|
||||
name: docker
|
||||
state: present
|
||||
executable: pip3
|
||||
|
||||
- name: make docker network
|
||||
docker_network:
|
||||
name: "{{ dockerNetwork }}"
|
||||
|
||||
- name: stop hydra
|
||||
docker_container:
|
||||
name: hydra
|
||||
state: stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Make Hydra
|
||||
docker_container:
|
||||
name: hydra
|
||||
image: 'linuxserver/hydra2:latest'
|
||||
state: started
|
||||
env:
|
||||
#PUID=1000
|
||||
#PGID=1000
|
||||
PUID=0
|
||||
PGID=0
|
||||
TZ=Europe/London
|
||||
ports:
|
||||
- 5076:5076
|
||||
volumes:
|
||||
#- "{{ hydra_config }}:/config"
|
||||
- "{{ dockerMount }}/hydra:/config"
|
||||
- "/docker/downloads:/downloads"
|
||||
networks:
|
||||
- name: "{{ dockerNetwork }}"
|
||||
|
||||
- name: stop sonarr
|
||||
docker_container:
|
||||
name: sonarr
|
||||
state: stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: start sonarr
|
||||
docker_container:
|
||||
name: sonarr
|
||||
image: linuxserver/sonarr:latest
|
||||
state: started
|
||||
env:
|
||||
# Use 0 because this runs as root
|
||||
#PUID=1000
|
||||
#PGID=1000
|
||||
PUID=0
|
||||
PGID=0
|
||||
TZ=Europe/London
|
||||
UMASK_SET=022 #optional
|
||||
ports:
|
||||
- 8989:8989
|
||||
volumes:
|
||||
- "{{ dockerMount }}/sonarr/config:/config"
|
||||
- "/docker/sonarr/data:/tv"
|
||||
- "/docker/downloads:/downloads"
|
||||
networks:
|
||||
- name: "{{ dockerNetwork }}"
|
||||
|
||||
- name: stop nzb
|
||||
docker_container:
|
||||
name: nzbget
|
||||
state: stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Make Nzb
|
||||
docker_container:
|
||||
name: nzbget
|
||||
image: linuxserver/nzbget:latest
|
||||
state: started
|
||||
env:
|
||||
PUID=0
|
||||
PGID=0
|
||||
TZ=Europe/London
|
||||
ports:
|
||||
- 6789:6789
|
||||
volumes:
|
||||
- "{{ dockerMount }}/nzbget:/config"
|
||||
- "/docker/downloads:/downloads"
|
||||
networks:
|
||||
- name: "{{ dockerNetwork }}"
|
18
playbook/docker/mediaserver/mount.yml
Normal file
18
playbook/docker/mediaserver/mount.yml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: mount external nfs disks
|
||||
hosts: mediaserver
|
||||
vars_files:
|
||||
- vars.yml
|
||||
|
||||
tasks:
|
||||
- name: make mountpoint
|
||||
file:
|
||||
path: /docker/dockerconfig
|
||||
state: directory
|
||||
|
||||
- name: mount /docker to /docker/dockerconfig
|
||||
mount:
|
||||
path: 192.168.0.16:/docker
|
||||
src: /docker/dockerconfig
|
||||
boot: yes
|
||||
state: mounted
|
35
playbook/docker/mediaserver/nzbget.yml
Normal file
35
playbook/docker/mediaserver/nzbget.yml
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
- name: nzbget
|
||||
hosts: linux
|
||||
become: yes
|
||||
vars_files:
|
||||
- vars.yml
|
||||
|
||||
tasks:
|
||||
- name: pip docker
|
||||
pip:
|
||||
name: docker
|
||||
executable: pip3
|
||||
|
||||
- name: stop nzb
|
||||
docker_container:
|
||||
name: nzbget
|
||||
state: stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Make Nzb
|
||||
docker_container:
|
||||
name: nzbget
|
||||
image: linuxserver/nzbget:latest
|
||||
state: started
|
||||
env:
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
TZ=Europe/London
|
||||
ports:
|
||||
- 6789:6789
|
||||
volumes:
|
||||
- "/docker/config/nzbconfig:/config"
|
||||
- "/docker/nzbdownloads:/downloads"
|
||||
networks:
|
||||
- name: "{{ network }}"
|
37
playbook/docker/mediaserver/sonarr.yml
Normal file
37
playbook/docker/mediaserver/sonarr.yml
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
- name: sonarr
|
||||
hosts: linux
|
||||
become: yes
|
||||
vars_files:
|
||||
- vars.yml
|
||||
|
||||
tasks:
|
||||
- name: pip docker
|
||||
pip:
|
||||
name: docker
|
||||
|
||||
- name: stop sonarr
|
||||
docker_container:
|
||||
name: sonarr
|
||||
state: stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: start sonarr
|
||||
docker_container:
|
||||
name: sonarr
|
||||
image: linuxserver/sonarr:latest
|
||||
state: started
|
||||
env:
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
TZ=Europe/London
|
||||
UMASK_SET=022 #optional
|
||||
ports:
|
||||
- 8989:8989
|
||||
volumes:
|
||||
- "/docker/sonarr/config:/config"
|
||||
- "/docker/sonarr/data:/tv"
|
||||
- "/docker/nzbdownloads:/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,17 +0,0 @@
|
||||
|
||||
---
|
||||
|
||||
- name: enable
|
||||
hosts: linux
|
||||
|
||||
tasks:
|
||||
# https://galaxy.ansible.com/jnv/unattended-upgrades
|
||||
- name: unattended-upgrades
|
||||
become: true
|
||||
include_role:
|
||||
name: jnv.unattended-upgrades
|
||||
vars:
|
||||
#unattended_package_blacklist: []
|
||||
unattended_automatic_reboot: true
|
||||
|
||||
|
34
playbook/linux/common.yml
Normal file
34
playbook/linux/common.yml
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
# This is a common playbooks for all linux servers
|
||||
# Contains all the basics needed for servers to get started
|
||||
# Once this is installed and maintained look for server based roles like docker servers
|
||||
|
||||
- name: Install Linux Requirement
|
||||
hosts: linux-all
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: install packages
|
||||
apt:
|
||||
name: "{{ packages }}"
|
||||
state: present
|
||||
vars:
|
||||
packages:
|
||||
- python3
|
||||
- python3-pip
|
||||
- nfs-common
|
||||
- tree
|
||||
when: ansible_distribution == "Ubuntu"
|
||||
|
||||
- name: Install pip
|
||||
include_role:
|
||||
name: geerlingguy.pip
|
||||
|
||||
# https://galaxy.ansible.com/jnv/unattended-upgrades
|
||||
- name: unattended-upgrades
|
||||
become: true
|
||||
include_role:
|
||||
name: jnv.unattended-upgrades
|
||||
vars:
|
||||
#unattended_package_blacklist: []
|
||||
unattended_automatic_reboot: true
|
@ -1,18 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC3TCCAcWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDDAdTZW5z
|
||||
dUNBMB4XDTE5MDQyODE3NTMwMloXDTI0MDQyNjE3NTMwMlowITEOMAwGA1UEAwwF
|
||||
c2Vuc3UxDzANBgNVBAoMBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBAMBFLZ/mgAOdKJ2YUkqzjZHKsRyvNxixX9I3LWXJCMfFnWuUOLau5UaE
|
||||
rS6ZbtO1N4djsi6xSyBhPSu2hjPt9KgniTesaKZDwlLO2HLrOpUpmKPPpLxnBym9
|
||||
m/nXWaeuTLAnnNtP/wU4Jwvp1u9qMu5tIYdy+hTd5LJSQcfjgrt5ydHzLbwn9UyE
|
||||
2pcMawEgOaoywY9i6Ofhfsr5hwLkR3/3VS5PfJ2sVsO0Ks2vBW091BaQSwQAarpR
|
||||
ExMHmTrcHoHtWFI0RiFxZ+MoakL5380VSmzhAs8QPxYWYc3PLndhYt4pH6TLcCOF
|
||||
LpY8qk6S/acHuWHgdl+GIgyk5jKqnkECAwEAAaMvMC0wCQYDVR0TBAIwADALBgNV
|
||||
HQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADggEB
|
||||
AG/MiB8QHvJlGrF1Xa5UHs/ykFJj1n+JzeniC5p3nApnRmpgi9KNlDZqRXjotuww
|
||||
uvaDlsRpFp+X4NukUUR8aUUZpwYbIm/wgXJ376Su0nUmpFmCU2TrGkk/cMeqbAen
|
||||
OYe5WZxsmJnmmkwhHLybrvha/vsCTNV6GY2JcHNhI8R7Uvwna48ueg7/WBQ5oXqZ
|
||||
zdYXMaFD2ioBFaYZqVifWv+5d1av2VBveX1V5p7ZZ3LHsvNS8/eVWufu5I4mwJI9
|
||||
GRPakzY0emL9ZBbtsZtsNA7IA6w4l4WeQtu1DHPc2iYO+JwfpeUNVX65ANSicqjC
|
||||
ibyhYEZs3qI/rb3WPXy6l0I=
|
||||
-----END CERTIFICATE-----
|
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAwEUtn+aAA50onZhSSrONkcqxHK83GLFf0jctZckIx8Wda5Q4
|
||||
tq7lRoStLplu07U3h2OyLrFLIGE9K7aGM+30qCeJN6xopkPCUs7Ycus6lSmYo8+k
|
||||
vGcHKb2b+ddZp65MsCec20//BTgnC+nW72oy7m0hh3L6FN3kslJBx+OCu3nJ0fMt
|
||||
vCf1TITalwxrASA5qjLBj2Lo5+F+yvmHAuRHf/dVLk98naxWw7Qqza8FbT3UFpBL
|
||||
BABqulETEweZOtwege1YUjRGIXFn4yhqQvnfzRVKbOECzxA/FhZhzc8ud2Fi3ikf
|
||||
pMtwI4UuljyqTpL9pwe5YeB2X4YiDKTmMqqeQQIDAQABAoIBAFxnovLLa9DQ0jlT
|
||||
gJFIVAyydoaLqxYiASRdwmK9yIuCbRLL7KnXyncmwri3ouz6lhJqlrMcIDgSo7yD
|
||||
f2Irxb6fKbJpGO53eEgmAx7P8JrJoANygwDNH0MvTmw31G3jNhYfI6K/gpf2kcWG
|
||||
//aWep3eMxQO7SPkNMqC//xaWnVQ0FLigNQjyFlgQrIZ3L4x7qFxcrkvTUIODGio
|
||||
R6hs7fECwXZkvLB28//tiwLEuOHnWGkG64fDebXUBDHsFhY/ObtA9vJITGY2GlUi
|
||||
1KFt9ZJd1JdMoV7EH5IwnA5YUN1NOtb5bwRaCddCMFH2lWsjzV1hNTZ9MzNyFqIF
|
||||
eolkKKUCgYEA6xR0LR3/stMPOWvgdaiXACHsH2hLx7Yh1vOf97eBbdUgiqjeL7DW
|
||||
mUmXIBLOQwrKMWNX0+DAqeuY80ESBmQ5KhRR/Sws2FMXGcqgyNPdJYAruif8y4z9
|
||||
0fGdvES1Fe12lOzyfPJclJi6doglyTjoJS5KGXUz8womJH4eiWZd+98CgYEA0WFx
|
||||
SPttK8Oi9zKxh/6YzpvOaABm6pCUslg79smhPGdhj4M0sO1sS4KzOBBolcplT9e6
|
||||
T1awh7ML44dowIFuQ0FgySnz5ogZt6xnqGv6bbfSVbMNpU4B9O4tJ2z16uFOXDeM
|
||||
f0tS55fcbspJ1Dylc+ndyAurd5E/8z/2BnU6qd8CgYADs6bAryA/qKMsvE4kjCsU
|
||||
jXQyamoHEw8lW2DBfdpD6H9Cr7YP+jDm6QnAL4uf8qOMc4wGghuGkXcvHW8zOpDL
|
||||
4NYJrpBmN6i9dztg7jUlSgdmPwr0CZxVmgBp3osbdUnQvopy/T4H+P+2rh4qNQMy
|
||||
0q/IBthyk05WdMX2U+5W8QKBgFSBwqpVKBvYyyaAZFziKiSBiA47003q6skMia8y
|
||||
dAwgIaU9rH+YY/QaHWGMZdnHJZrTFBQ/heJPJoY/ucywsKMeeQTYFOO/nLmgMPou
|
||||
EpZD8fW63dARKwMDOmBGPv78zpazqNYbvatRhJuGs8OgcprVEjlSVHNewXPZJeA3
|
||||
YmT7AoGAJuMaSA6oZqn0uKJD0FDwIl4j0RfVhPJHe9Um1G1K2FpZ3DV705kcwx1t
|
||||
IUu9pHLFJubwpkQFiERX/6BRbjbp4oZhpPLcLRec5nXTT8LHoiCBMaQW2RtnDMeW
|
||||
XKt2xyhGFp0Drw4vWV0Nr8fJbuBbAqviZTQnBtj7ZJ41KRV1mU4=
|
||||
-----END RSA PRIVATE KEY-----
|
@ -1,17 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICxDCCAaygAwIBAgIJAPX7448uFrdyMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV
|
||||
BAMMB1NlbnN1Q0EwHhcNMTkwNDI4MTc1MjU3WhcNMjQwNDI2MTc1MjU3WjASMRAw
|
||||
DgYDVQQDDAdTZW5zdUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
sI4ptnAIEJISxDYMVZIi6vF6GcnzXDyXl4Et9m86QF9+Zyfe4zomGDnfp7wfhddS
|
||||
6asPHMxcgXi9itY6qr33lzdDL4SaMysS/VwWLBwhmdl2hEELPvUKHBF96iyfuq4A
|
||||
lsQ3lAXr/3uqXdODNo38hGaxrK2n1ocKFEKZrGlmrFDvfYKJz1cYlDh5u0ghjJGQ
|
||||
E/MCDeQzGNOjcbSbNUo5nMR8P6nzPcMDHjtA0OS4DXSijvjibHPhZ/NU9KgoTz9W
|
||||
oL8FoePlL6Zq6cwiEKCOUsqivIPbM3nGGNkPBHmSE0dnYXn0le+LK3rkNX60ZdwE
|
||||
fqisAIaHSVQWVlTw4J8xlQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQE
|
||||
AwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAp1MPCS8tKdUGrT07yHosw7+Gxc++/ylM
|
||||
cmS9GLiwAfU4VU4QEy97ipL4K8VLWbrGVvJSpgxAApLA0jX7R2UcYTYeTk9ikuto
|
||||
BeQRxcj6QdR8BKD4N7Qtje6jBVMJ6Ssky3Kj1XXcEQu4iZx9uZCX2yeCeozXaLtS
|
||||
+Tw3r9NjgIXGvhLCp64JTC+rL74S7cMwAIW5YBRy/K4uBdLKBcjYIi7VQnivsfGu
|
||||
J2+28+kfNw7nNWBdVWtBf6MoJQNEDvpx+HGRBCJoSlgw+GTRgbgCqEPJrXBdbamU
|
||||
SDJtCEdYonQqUCqqCI083ckx8c31YBg1COTZBQnWQiYVpcIfXG7j/A==
|
||||
-----END CERTIFICATE-----
|
@ -1,18 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC3TCCAcWgAwIBAgIBATANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDDAdTZW5z
|
||||
dUNBMB4XDTE5MDQyODE3NTI1OVoXDTI0MDQyNjE3NTI1OVowITEOMAwGA1UEAwwF
|
||||
c2Vuc3UxDzANBgNVBAoMBnNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALEltlZMg7u1rqFbnljmD+IeiVeRt0zzRiCEpjvQ4t+bBjT5onPAOxYI
|
||||
Q1d3MdPJqA+lyCRP/sXcEKa1l14UDj50WEruK0VqXKL+e2ETeJi4kJb8k8ansCAI
|
||||
Ask5Ok2d8bTSQLzJBCkjwvR5kfG49R5wfJFDSA3WLfTHq1myRibJIMgbFGB2UP3Q
|
||||
yyljZWn04IO72yWhK413CxwnwXKsIFT5/z0hVGZMr5wDWpfhBhtBi6uxqeKG3Zyy
|
||||
CV/f3yUcOL+A9yoxPu155TNYfvmz1rqarTeuOJJJU7TtAiHmue8OhkfRFanBBYj9
|
||||
hSOGPdLB9eKzoWsS8vLKLUTwaQwZ9IsCAwEAAaMvMC0wCQYDVR0TBAIwADALBgNV
|
||||
HQ8EBAMCBSAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQADggEB
|
||||
ABPZUxDIGJ6C8hu1aOj5sY/r8yphotSnPVkghBTGVJbjmGHSci+IGbHX6yemVYvH
|
||||
mQWKI8qBdroiIpCOpMVvmG6oUR4s+h/vdKuDoy/x3lRZjJDQiReAGKwwyeiG++wJ
|
||||
x6eSCDGqcIWvk72Zgd+OGym3JGrDpU7ofat+ncqtIunAOh7rhQlyRJ42wYZpWDIi
|
||||
Aass4yn16aYhF/PppUIsBYrWk1UUlKbXOF/Z7WOG4Hg6h5HwwtJZq/PGsSzJqd/O
|
||||
s6XI8Am1pU9PwLwWm9Vad44OhTNWGxsidboUCxNa7Yc7p5CkAqT+Z2Lf7RfvgmcX
|
||||
SUCwSN9REpYGV3k9l47eljY=
|
||||
-----END CERTIFICATE-----
|
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAsSW2VkyDu7WuoVueWOYP4h6JV5G3TPNGIISmO9Di35sGNPmi
|
||||
c8A7FghDV3cx08moD6XIJE/+xdwQprWXXhQOPnRYSu4rRWpcov57YRN4mLiQlvyT
|
||||
xqewIAgCyTk6TZ3xtNJAvMkEKSPC9HmR8bj1HnB8kUNIDdYt9MerWbJGJskgyBsU
|
||||
YHZQ/dDLKWNlafTgg7vbJaErjXcLHCfBcqwgVPn/PSFUZkyvnANal+EGG0GLq7Gp
|
||||
4obdnLIJX9/fJRw4v4D3KjE+7XnlM1h++bPWupqtN644kklTtO0CIea57w6GR9EV
|
||||
qcEFiP2FI4Y90sH14rOhaxLy8sotRPBpDBn0iwIDAQABAoIBAFtnsiXlZTO+E1V/
|
||||
CL2mOBvc1dExhvtVq6Gr0Hqc1fO68gDzrjc7wUElElpXToaRTv6D9DmIbVV6r7zV
|
||||
hj0s7Aydy9EeA4XV0+bmmJMGkPt8gF7oBPhEHkTo3UcnGEZkcQt0UaMXteXkZfvv
|
||||
nrazUQdb02rA5LT/Bsd/H5MwwbHQyipMXKQXpYyzALhoBUrXItc+aHfINHOELs0h
|
||||
UPSoFnNSsQo1VGSd/TCZJYYw2cpmeTqWO4sM6z8vYXJnNQTCb2saW+vywfQoYTJ7
|
||||
V6mSmX7EgYh512jNpNdzhQx8qN1hmWF/r5G9DC4QSnzVoN23fi4H+szB9CEfVlPy
|
||||
pGj6qUECgYEA1zwPaLjz9XgeZiHrLYDCFeNRYE4Noa9mFuuplYxmiIJGsBiUNHNJ
|
||||
bbMn8VpuBBptEUnSTCGJhAF39AGKfUHx+49hTKTUISmnTDOSHLeE1mKvZJWB3x4r
|
||||
3ezfsUVwV4BvidYQEv0FWuE+lniDmx2BVQk7vIiF5VjUxMmyqnB8cEUCgYEA0rLw
|
||||
LtSYod0VzFLs8NlMH9nhfQk7oSfyxqLVwpiAQVAtrI3xfQUaYP04BrV/XOI+YBcF
|
||||
Svg4Ou4tqcuGFFYtqNPAaGYfih7UzEY8Z6wH2rkyznCq7VQZexKKtTbPQCNSkJ5h
|
||||
fpNxfh4sXZSpYg/aIEr6OC8REuhcjRjhJBWJJo8CgYAsPN316j3KMBwfZc1Olu5N
|
||||
TWGGZ8SJfOGAyIMch7TzTcN1ojej6CYpc+87vhhqo3vTV9bvat020o5zCnYKdKll
|
||||
yPx4olAvWL5X/SmE2XtmDPZ7t/bvguYFQRBhASKr+Wvzapn3LSYSncUdbDuwgAn7
|
||||
DmDGyVCr6OwiXkpomaIZ+QKBgCZIpSOdNW6TwVYy6yKIGTDgYfxaJR+PJqm5BKYr
|
||||
F4LGksX7tJlGyBg/amKtr8qswTCsfiW1HGJ4zItBk8c2MW2vrBJMHAb4uymyyV78
|
||||
/yBa7kRcbHJbCZY3NEThBJ9ey63DWWuqVsDXsq/+RxiuUK/1b6mtw6hv2AE7OA1a
|
||||
bGU5AoGBANL+ssYI1JH1TFRwI8iTc/no2Loy2jZ2NGyZbU/gc3NhhVERNgtK8nmM
|
||||
dcYrgmewKKS20+AqqbM7zITYdJea6RTKU6ELJul2iKMDSwA65cEwueqAT6WY7x57
|
||||
z0fBzoaLRQp11SSuuPz9p0a096XGygQP1o2SabZCwY4b3+vtkbJM
|
||||
-----END RSA PRIVATE KEY-----
|
@ -1,12 +0,0 @@
|
||||
|
||||
- name: Deploy OwnCloud
|
||||
hosts: linux
|
||||
become_method: sudo
|
||||
|
||||
tasks:
|
||||
- name: Check if docker is installed.
|
||||
apt:
|
||||
name: docker
|
||||
state: present
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
deb https://artifacts.elastic.co/packages/7.x/apt stable main
|
@ -1,40 +0,0 @@
|
||||
---
|
||||
# This will install all the client parts needed for elastic to monitor client computers
|
||||
|
||||
- name: Install elastic client programs
|
||||
hosts: elasticClients
|
||||
vars:
|
||||
kibana_host: '192.168.0.173:5601'
|
||||
elasticsearch_hosts: '["192.168.0.173:9200"]'
|
||||
|
||||
tasks:
|
||||
- name: Install elastic repo
|
||||
include: install-repo.yml
|
||||
|
||||
- name: Install elastic heartbeat
|
||||
become: true
|
||||
apt:
|
||||
name: heartbeat-elastic
|
||||
|
||||
- name: Update Heatbeat config
|
||||
become: true
|
||||
template:
|
||||
src: heartbeat.j2
|
||||
dest: /etc/heartbeat/heartbeat.yml
|
||||
|
||||
- name: Configure elastic heartbeat
|
||||
include: config-heartbeat.yml
|
||||
|
||||
- name: Install elastic metricbeat
|
||||
become: true
|
||||
apt:
|
||||
name: metricbeat
|
||||
|
||||
- name: Update Metricbeat config
|
||||
become: true
|
||||
template:
|
||||
src: metricbeat.j2
|
||||
dest: /etc/metricbeat/metricbeat.yml
|
||||
|
||||
- name: Configure elastic metricbeat
|
||||
include: config-metricbeat.yml
|
@ -1,29 +0,0 @@
|
||||
---
|
||||
|
||||
- name: Install Elastic GPG Key
|
||||
become: true
|
||||
apt_key:
|
||||
url: "https://artifacts.elastic.co/GPG-KEY-elasticsearch"
|
||||
state: present
|
||||
id: 46095ACC8548582C1A2699A9D27D666CD88E42B4
|
||||
|
||||
- name: Install apt-transport-https
|
||||
become: true
|
||||
apt:
|
||||
name: apt-transport-https
|
||||
|
||||
- name: Add Elastic Repo
|
||||
become: true
|
||||
copy:
|
||||
dest: '/etc/apt/sources.list.d/elastic-7.x.list'
|
||||
content: "deb https://artifacts.elastic.co/packages/7.x/apt stable main"
|
||||
# copy:
|
||||
#src: elastic-7.x.list
|
||||
# dest: /etc/apt/sources.list.d/
|
||||
# backup: yes
|
||||
|
||||
- name: Update Packages
|
||||
become: true
|
||||
apt:
|
||||
update_cache: true
|
||||
|
@ -1,14 +0,0 @@
|
||||
|
||||
- name: Install Filebeat
|
||||
hosts: elasticClients
|
||||
|
||||
tasks:
|
||||
- name: Install Filebeat
|
||||
include_role:
|
||||
name: luther38.filebeat
|
||||
vars:
|
||||
kibana_host: 172.20.0.142:5601
|
||||
elasticsearch_hosts: "'172.20.0.142:9200'"
|
||||
systemd_enabled: true
|
||||
systemd_restart: true
|
||||
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
|
||||
- name: Install Metricbeat
|
||||
hosts: elasticClients
|
||||
|
||||
tasks:
|
||||
- name: Install Metricbeat
|
||||
become: true
|
||||
include_role:
|
||||
name: luther38.metricbeat
|
||||
vars:
|
||||
kibana_host: 172.20.0.142
|
||||
elasticsearch_hosts: '["172.20.0.142:9200"]'
|
||||
systemd_enable_service: true
|
||||
systemd_restart_service: true
|
||||
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
|
||||
- name: Install WinLogBeat
|
||||
hosts: windows
|
||||
|
||||
tasks:
|
||||
- name: Install WinLogBeat
|
||||
become: true
|
||||
include_role:
|
||||
name: luther38.winlogbeat
|
||||
vars:
|
||||
version: 7.0.0
|
||||
kibana_host: 172.20.0.142
|
||||
elasticsearch_hosts: '["172.20.0.142:9200"]'
|
||||
|
||||
|
@ -1,62 +0,0 @@
|
||||
---
|
||||
# This will install all elastic services for a elastic server
|
||||
# ElasticSearch
|
||||
# Kibana
|
||||
|
||||
- name: Install Elastic server programs
|
||||
hosts: elastic
|
||||
vars:
|
||||
es_cluster_name: 'logging-dev'
|
||||
es_node_name: 'dev-data-01'
|
||||
es_node_master: 'true'
|
||||
es_node_data: 'true'
|
||||
es_path_data: '/var/lib/elasticsearch'
|
||||
es_path_logs: '/var/log/elasticsearch'
|
||||
es_http_port: '9200'
|
||||
es_transport_host: 'localhost'
|
||||
es_transport_port: '9300'
|
||||
k_server_port: 5601
|
||||
k_elasticsearch_hosts: 'http://192.168.0.173:9200'
|
||||
|
||||
tasks:
|
||||
- name: Install Requrements
|
||||
include: install-repo.yml
|
||||
|
||||
- name: Install ElasticSearch from apt
|
||||
become: true
|
||||
apt:
|
||||
name: elasticsearch
|
||||
|
||||
- name: Update ElasticSearch config
|
||||
become: true
|
||||
template:
|
||||
src: elasticsearch.j2
|
||||
dest: /etc/elasticsearch/elasticsearch.yml
|
||||
|
||||
- name: Configure ElasticSearch
|
||||
include: config-elasticsearch.yml
|
||||
|
||||
- name: Install Kibana from apt
|
||||
become: true
|
||||
apt:
|
||||
name: kibana
|
||||
|
||||
- name: Configure Kibana
|
||||
become: true
|
||||
template:
|
||||
src: kibana.j2
|
||||
dest: /etc/kibana/kibana.yml
|
||||
|
||||
- name: Configure Kibana
|
||||
include: config-kibana.yml
|
||||
|
||||
- name: Install Heartbeat
|
||||
become: true
|
||||
apt:
|
||||
name: heartbeat
|
||||
|
||||
#- name: Install Logstash
|
||||
#become: true
|
||||
#apt:
|
||||
#name: logstash
|
||||
|
@ -1,27 +0,0 @@
|
||||
---
|
||||
# This will install all the client parts needed for elastic to monitor client computers
|
||||
|
||||
- name: Install elastic client programs
|
||||
hosts: windows
|
||||
vars:
|
||||
elastic_version: '7.0.0'
|
||||
url_heartbeat: 'https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-{{elastic_version}}-windows-x86_64.zip'
|
||||
url_metricbeat: 'https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-7.0.0-windows-x86_64.zip'
|
||||
url_winlogbeat: 'https://artifacts.elastic.co/downloads/beats/winlogbeat/winlogbeat-7.0.0-windows-x86_64.zip'
|
||||
temp: 'c:\temp\'
|
||||
program_files: 'c:\program files\'
|
||||
kibana_host: '192.168.0.173:5601'
|
||||
elasticsearch_hosts: '["192.168.0.173:9200"]'
|
||||
|
||||
|
||||
tasks:
|
||||
- name: make temp folder
|
||||
win_file:
|
||||
path: c:\temp\
|
||||
state: directory
|
||||
|
||||
- name: Install Metricbeat
|
||||
include: config-win-metricbeat.yml
|
||||
|
||||
- name: Install WinLogbeat
|
||||
include: config-winlogbeat.yml
|
@ -1,35 +0,0 @@
|
||||
|
||||
- name: testing elastic role
|
||||
hosts: elastic
|
||||
|
||||
tasks:
|
||||
- name: install/Update Java
|
||||
become: true
|
||||
import_role:
|
||||
name: geerlingguy.java
|
||||
|
||||
- name: install elasticsearch
|
||||
become: true
|
||||
import_role:
|
||||
name: elasticsearch
|
||||
vars:
|
||||
cluster_name: "loggin-dev"
|
||||
ufw_http_port: true
|
||||
ufw_transport_port: true
|
||||
systemd_enabled: true
|
||||
systemd_restart: true
|
||||
node_name: "{{ ansible_hostname }}"
|
||||
discovery_seed_hosts: "'127.0.0.1', '172.20.0.142', '192.168.0.173'"
|
||||
cluster_initial_master_nodes: " '172.20.0.142', '192.168.0.173' "
|
||||
|
||||
- name: install kibana
|
||||
become: true
|
||||
import_role:
|
||||
name: kibana
|
||||
vars:
|
||||
server_port: 5601
|
||||
ufw_server_port: true
|
||||
server_host: "{{ ansible_default_ipv4.address }}"
|
||||
server_name: "{{ ansible_hostname }}"
|
||||
elasticsearch_hosts: " 'http://localhost:9200', 'http://dm-nagios.local:9200', 'http://172.20.0.142:9200' "
|
||||
|
@ -32,12 +32,10 @@
|
||||
|
||||
- name: pip remove docker
|
||||
pip:
|
||||
name: docker
|
||||
name: docker-py
|
||||
state: absent
|
||||
executable: pip
|
||||
|
||||
|
||||
|
||||
roles:
|
||||
#- geerlingguy.repo-epel
|
||||
- geerlingguy.git
|
||||
|
@ -1,34 +0,0 @@
|
||||
|
||||
- name: Install PowerShell Core
|
||||
hosts: linux
|
||||
#debugger: always
|
||||
|
||||
tasks:
|
||||
- name: Check if PowerShell is installed
|
||||
failed_when: "'Failed' PowerShell is already installed."
|
||||
apt:
|
||||
name: powershell
|
||||
|
||||
- name: Install Microsoft GPG Key
|
||||
get_url:
|
||||
url: https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
|
||||
dest: /tmp/
|
||||
|
||||
- name: Register GPG Key
|
||||
become: true
|
||||
become_method: sudo
|
||||
apt: deb="/tmp/packages-microsoft-prod.deb"
|
||||
#command: dpkg -i ~/packages-microsoft-prod.deb
|
||||
|
||||
- name: Update repos and Install PowerShell Core
|
||||
become: true
|
||||
become_method: sudo
|
||||
apt:
|
||||
name: powershell
|
||||
update_cache: yes
|
||||
state: present
|
||||
|
||||
- name: Remove Extra files
|
||||
file:
|
||||
state: absent
|
||||
path: /tmp/packages-microsoft-prod.deb
|
@ -1,19 +0,0 @@
|
||||
|
||||
- name: testing sensu
|
||||
hosts: linux
|
||||
|
||||
tasks:
|
||||
- name: install sensu server
|
||||
become: true
|
||||
import_role:
|
||||
name: sensu.sensu
|
||||
vars:
|
||||
# Sever vars
|
||||
sensu_deploy_redis_server: true
|
||||
sensu_deploy_rabbitmq_server: true
|
||||
sensu_master: true
|
||||
#sensu_include_plugins: true
|
||||
sensu_include_dashboard: true
|
||||
# Client Vars
|
||||
#sensu_client: true
|
||||
|
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
|
||||
- name: remove cask - dotnet-sdk
|
||||
become: true
|
||||
homebrew_cask:
|
||||
name: dotnet-sdk
|
||||
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
|
30
test.yaml
30
test.yaml
@ -1,30 +0,0 @@
|
||||
---
|
||||
all:
|
||||
hosts:
|
||||
dmi-dev01:
|
||||
children:
|
||||
linux:
|
||||
hosts:
|
||||
172.20.0.142:
|
||||
vars:
|
||||
ansible_user: ansible
|
||||
ansible_connection: ssh
|
||||
ansible_password:
|
||||
ansible_become_method: sudo
|
||||
ansible_become_pass:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
windows:
|
||||
hosts:
|
||||
dev01:
|
||||
vars:
|
||||
ansible_user: ansible
|
||||
ansible_password:
|
||||
ansible_connection: winrm
|
||||
ansible_port: 5985
|
||||
ansible_winrm_scheme: http
|
||||
ansible_winrm_transport: ntlm
|
||||
ansible_winrm_server_cert_validation: ignore
|
||||
osx:
|
||||
hosts:
|
||||
127.0.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user