Merge pull request #8 from luther38/doc-update

Doc update
This commit is contained in:
James Tombleson 2019-11-04 18:06:03 -08:00 committed by GitHub
commit 23ee532279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1517 additions and 4744 deletions

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"cSpell.ignoreWords": [
"ansible",
"okta",
"specialcounsel",
"vault"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -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
View File

@ -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
View File

@ -0,0 +1,2 @@
# Playbooks

40
docs/readme.md Normal file
View 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.

View File

@ -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
View 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
View 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
View 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()

View 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 }}"

View 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 }}"

View 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

View 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 }}"

View 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 }}"

View 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

View File

@ -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
View 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

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -1,12 +0,0 @@
- name: Deploy OwnCloud
hosts: linux
become_method: sudo
tasks:
- name: Check if docker is installed.
apt:
name: docker
state: present

View File

@ -1 +0,0 @@
deb https://artifacts.elastic.co/packages/7.x/apt stable main

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"]'

View File

@ -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

View File

@ -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

View File

@ -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' "

View File

@ -32,12 +32,10 @@
- name: pip remove docker
pip:
name: docker
name: docker-py
state: absent
executable: pip
roles:
#- geerlingguy.repo-epel
- geerlingguy.git

View File

@ -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

View File

@ -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

View 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

View 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 }}"

View 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 }}"

View 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

View 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

View 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

View 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.

View File

@ -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

View File

@ -0,0 +1,12 @@
---
organization: ''
api_key: ''
first_name: ''
last_name: ''
email: ''
login: ''
status: ''
add_groups:
remove_groups:

View 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

View File

@ -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