Initial Commit
This commit is contained in:
commit
1cdd5726c2
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
collections/ansible_collections
|
||||||
|
__old
|
||||||
|
facts.d
|
26
ansible.cfg
Normal file
26
ansible.cfg
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = hosts
|
||||||
|
roles_path = roles
|
||||||
|
collections_path = collections
|
||||||
|
remote_tmp = /tmp/.ansible-${USER}/tmp
|
||||||
|
gathering = smart
|
||||||
|
gather_timeout = 300
|
||||||
|
fact_path = facts.d
|
||||||
|
fact_caching = jsonfile
|
||||||
|
fact_caching_connection = facts.d
|
||||||
|
fact_caching_timeout = 300
|
||||||
|
retry_files_enabled = False
|
||||||
|
forks = 40
|
||||||
|
timeout = 30
|
||||||
|
host_key_checking = False
|
||||||
|
display_skipped_hosts = False
|
||||||
|
bin_ansible_callbacks = True
|
||||||
|
callback_whitelist = ansible.posix.profile_tasks, ansible.posix.timer
|
||||||
|
deprecation_warnings = False
|
||||||
|
command_warnings = False
|
||||||
|
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
pipelining = True
|
||||||
|
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey
|
||||||
|
|
0
collections/.keep
Normal file
0
collections/.keep
Normal file
5
collections/requirements.yml
Normal file
5
collections/requirements.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: ansible.posix
|
||||||
|
- name: community.general
|
||||||
|
|
23
csv_inventory_example.yml
Normal file
23
csv_inventory_example.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
- name: CSV Inventory Creation
|
||||||
|
hosts: all
|
||||||
|
become: no
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
|
||||||
|
vars_files:
|
||||||
|
- vars/defaults.yml
|
||||||
|
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- import_tasks: tasks/register_csv.yml
|
||||||
|
- import_tasks: tasks/fetch_inv_list.yml
|
||||||
|
- import_tasks: tasks/create_inv.yml
|
||||||
|
- import_tasks: tasks/fetch_inv_group_list.yml
|
||||||
|
- import_tasks: tasks/create_inv_group.yml
|
||||||
|
- import_tasks: tasks/fetch_host_list.yml
|
||||||
|
- import_tasks: tasks/debug_inv_host.yml
|
||||||
|
- import_tasks: tasks/add_inv_host.yml
|
||||||
|
- import_tasks: tasks/update_inv_host.yml
|
||||||
|
|
||||||
|
...
|
16
files/sample_inventory_1.csv
Normal file
16
files/sample_inventory_1.csv
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
inventory_hostname,inventory_name,ansible_host,macaddress,tower_group
|
||||||
|
hamlin-brenda.etsbv.internal,server000.etsbv.internal,10.14.200.90,02:16:3e:56:a0:f6,eeny
|
||||||
|
hamlin-brenda.etsbv.internal,server000.etsbv.internal,10.14.200.90,02:16:3e:56:a0:f6,prod
|
||||||
|
sicilian-michael.etsbv.internal,server001.etsbv.internal,10.183.84.9,02:16:3e:27:9c:64,meeny
|
||||||
|
sicilian-michael.etsbv.internal,server001.etsbv.internal,10.183.84.9,02:16:3e:27:9c:64,prod
|
||||||
|
oldham-ethel.etsbv.internal,server002.etsbv.internal,10.175.134.46,02:16:3e:6b:96:56,miney
|
||||||
|
oldham-ethel.etsbv.internal,server002.etsbv.internal,10.175.134.46,02:16:3e:6b:96:56,prod
|
||||||
|
maynard-david.etsbv.internal,server003.etsbv.internal,10.223.68.138,02:16:3e:31:48:7d,moe
|
||||||
|
maynard-david.etsbv.internal,server003.etsbv.internal,10.223.68.138,02:16:3e:31:48:7d,prod
|
||||||
|
creed-laura.etsbv.internal,server0019.etsbv.internal,10.104.244.30,02:16:3e:72:81:45,tiger
|
||||||
|
creed-laura.etsbv.internal,server0019.etsbv.internal,10.104.244.30,02:16:3e:72:81:45,prod
|
||||||
|
doe-john.etsbv.internal,server23421.etsbv.internal,10.87.6.244,aa:f3:e7:66:11:45,whacky
|
||||||
|
doe-john.etsbv.internal,server23421.etsbv.internal,10.87.6.244,aa:f3:e7:66:11:45,tacky
|
||||||
|
doe-john.etsbv.internal,server23421.etsbv.internal,10.87.6.244,aa:f3:e7:66:11:45,lacky
|
||||||
|
doe-john.etsbv.internal,server23421.etsbv.internal,10.87.6.244,aa:f3:e7:66:11:45,hacky
|
||||||
|
doe-john.etsbv.internal,server23421.etsbv.internal,10.87.6.244,aa:f3:e7:66:11:45,backy
|
|
1001
files/sample_inventory_2.csv
Normal file
1001
files/sample_inventory_2.csv
Normal file
File diff suppressed because it is too large
Load Diff
33
tasks/add_inv_host.yml
Normal file
33
tasks/add_inv_host.yml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- name: Add hosts from CSV to Tower groups
|
||||||
|
uri:
|
||||||
|
method : POST
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/groups/\
|
||||||
|
{{ r_inv_group_list | selectattr('name', '==', item.tower_group) | map(attribute='id') | flatten | join(',') }}\
|
||||||
|
/hosts/"
|
||||||
|
status_code :
|
||||||
|
- 200
|
||||||
|
- 201
|
||||||
|
- 204
|
||||||
|
headers:
|
||||||
|
Content-type : application/json
|
||||||
|
body:
|
||||||
|
name : "{{ item.inventory_hostname }}"
|
||||||
|
description : "{{ item.inventory_name }}"
|
||||||
|
inventory : "{{ r_inv_id.id | default(r_inventory.json.id) }}"
|
||||||
|
body_format : json
|
||||||
|
return_content : no
|
||||||
|
validate_certs : no
|
||||||
|
ignore_errors : yes
|
||||||
|
register : r_inventory_host
|
||||||
|
loop : "{{ r_csv_hosts }}"
|
||||||
|
loop_control :
|
||||||
|
label : "{{ item.inventory_hostname }}"
|
||||||
|
when :
|
||||||
|
- r_twr_host_list[item.inventory_hostname] is not defined
|
||||||
|
|
||||||
|
|
||||||
|
...
|
26
tasks/create_inv.yml
Normal file
26
tasks/create_inv.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
- name: Create inventory in Tower
|
||||||
|
uri:
|
||||||
|
method : POST
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/inventories/"
|
||||||
|
status_code :
|
||||||
|
- 200
|
||||||
|
- 201
|
||||||
|
headers:
|
||||||
|
Content-type : application/json
|
||||||
|
body:
|
||||||
|
name : "{{ __inventory }}"
|
||||||
|
organization : "{{ __organization }}"
|
||||||
|
body_format : json
|
||||||
|
return_content : no
|
||||||
|
validate_certs : no
|
||||||
|
ignore_errors : yes
|
||||||
|
register : r_inventory
|
||||||
|
when :
|
||||||
|
- __inventory not in r_inventory_list
|
||||||
|
|
||||||
|
|
||||||
|
...
|
46
tasks/create_inv_group.yml
Normal file
46
tasks/create_inv_group.yml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- name: Convert CSV groups into a list
|
||||||
|
set_fact:
|
||||||
|
r_inv_group_consolidate: |
|
||||||
|
[
|
||||||
|
{% for csv_host in r_csv_hosts %}
|
||||||
|
"{{ csv_host.tower_group }}",
|
||||||
|
{% endfor %}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
- name: Create inventory group in Tower
|
||||||
|
uri:
|
||||||
|
method : POST
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/groups/"
|
||||||
|
status_code :
|
||||||
|
- 200
|
||||||
|
- 201
|
||||||
|
headers:
|
||||||
|
Content-type : application/json
|
||||||
|
body:
|
||||||
|
name : "{{ lv_tower_group }}"
|
||||||
|
inventory : "{{ r_inv_id.id | default(r_inventory.json.id) }}"
|
||||||
|
body_format : json
|
||||||
|
return_content : no
|
||||||
|
validate_certs : no
|
||||||
|
ignore_errors : yes
|
||||||
|
register : r_inv_group
|
||||||
|
loop : "{{ r_inv_group_consolidate | unique }}"
|
||||||
|
loop_control :
|
||||||
|
loop_var : lv_tower_group
|
||||||
|
label : "{{ lv_tower_group }}"
|
||||||
|
when :
|
||||||
|
- "r_inv_group_list | selectattr('name', '==', lv_tower_group) | map(attribute='id') | flatten | length < 1"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Re-fetch inventory group info from Tower
|
||||||
|
import_tasks : tasks/fetch_inv_group_list.yml
|
||||||
|
when :
|
||||||
|
- r_inv_group.results | rejectattr('skipped', 'defined')
|
||||||
|
|
||||||
|
|
||||||
|
...
|
32
tasks/debug_inv_host.yml
Normal file
32
tasks/debug_inv_host.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
- name: Debug Information
|
||||||
|
block:
|
||||||
|
- name: Debug r_twr_host_list
|
||||||
|
debug:
|
||||||
|
var: r_twr_host_list
|
||||||
|
|
||||||
|
|
||||||
|
- name: Debug add host to tower if not exist
|
||||||
|
debug:
|
||||||
|
msg: "[NOT_EXIST] adding {{ item.inventory_hostname }} to tower :: group: {{ item.tower_group }}"
|
||||||
|
loop: "{{ r_csv_hosts }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.inventory_hostname }}"
|
||||||
|
when:
|
||||||
|
- r_twr_host_list[item.inventory_hostname] is not defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Debug add host to tower, but only if host is not in correct groups
|
||||||
|
debug:
|
||||||
|
msg: "[UPDATE] adding {{ item.inventory_hostname }} to tower group {{ item.tower_group }}"
|
||||||
|
loop: "{{ r_csv_hosts }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.inventory_hostname }}"
|
||||||
|
when:
|
||||||
|
- r_twr_host_list[item.inventory_hostname] is defined
|
||||||
|
- r_twr_host_list[item.inventory_hostname].groups[item.tower_group] is not defined
|
||||||
|
when:
|
||||||
|
- __show_debug_msgs | bool
|
||||||
|
|
||||||
|
|
||||||
|
...
|
21
tasks/fetch_host_list.yml
Normal file
21
tasks/fetch_host_list.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch list of inventory hosts from Tower
|
||||||
|
uri:
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/inventories/\
|
||||||
|
{{ r_inv_id.id | default(r_inventory.json.id) }}/hosts/\
|
||||||
|
?page_size={{ __api_results | default('20') }}"
|
||||||
|
validate_certs : no
|
||||||
|
return_content : no
|
||||||
|
body_format : json
|
||||||
|
register : r_get_inv_host_list
|
||||||
|
|
||||||
|
|
||||||
|
- name: Register inventory host list
|
||||||
|
set_fact:
|
||||||
|
r_twr_host_list: "{{ lookup('template', 'templates/host_list_w_group.j2') }}"
|
||||||
|
|
||||||
|
|
||||||
|
...
|
20
tasks/fetch_inv_group_list.yml
Normal file
20
tasks/fetch_inv_group_list.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch list of inventory groups from Tower
|
||||||
|
uri:
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/inventories/\
|
||||||
|
{{ r_inv_id.id | default(r_inventory.json.id) }}/groups/"
|
||||||
|
validate_certs : no
|
||||||
|
return_content : no
|
||||||
|
body_format : json
|
||||||
|
register : r_get_inv_group_list
|
||||||
|
|
||||||
|
|
||||||
|
- name: Register inventory group list
|
||||||
|
set_fact:
|
||||||
|
r_inv_group_list: "{{ lookup('template', 'templates/inv_group_list.j2') }}"
|
||||||
|
|
||||||
|
|
||||||
|
...
|
30
tasks/fetch_inv_list.yml
Normal file
30
tasks/fetch_inv_list.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch list of inventories from Tower
|
||||||
|
uri:
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/inventories/"
|
||||||
|
validate_certs : no
|
||||||
|
return_content : no
|
||||||
|
body_format : json
|
||||||
|
register : r_get_inv_list
|
||||||
|
|
||||||
|
|
||||||
|
- name: Build inventory list from Tower results
|
||||||
|
set_fact:
|
||||||
|
r_inventory_list : "{{ r_inventory_list | default([]) + [item.name] }}"
|
||||||
|
loop : "{{ r_get_inv_list.json.results }}"
|
||||||
|
loop_control :
|
||||||
|
label : "{{ item.name }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Register inventory ID if available
|
||||||
|
set_fact:
|
||||||
|
r_inv_id : "{{ lookup('template', 'templates/get_inventory_id.j2') }}"
|
||||||
|
when :
|
||||||
|
- r_inventory_list is defined
|
||||||
|
- __inventory in r_inventory_list
|
||||||
|
|
||||||
|
|
||||||
|
...
|
7
tasks/register_csv.yml
Normal file
7
tasks/register_csv.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
- name: Register contents of CSV
|
||||||
|
set_fact:
|
||||||
|
r_csv_hosts: "{{ lookup('template', 'templates/csv_inventory.j2') }}"
|
||||||
|
|
||||||
|
|
||||||
|
...
|
34
tasks/update_inv_host.yml
Normal file
34
tasks/update_inv_host.yml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
- name: Update existing host and group membership
|
||||||
|
uri:
|
||||||
|
method : POST
|
||||||
|
force_basic_auth : yes
|
||||||
|
url_username : "{{ __tower_user}}"
|
||||||
|
url_password : "{{ __tower_pass}}"
|
||||||
|
url : "{{ __tower_url }}/api/v2/groups/\
|
||||||
|
{{ r_inv_group_list | selectattr('name', '==', item.tower_group) | map(attribute='id') | flatten | join(',') }}\
|
||||||
|
/hosts/"
|
||||||
|
status_code :
|
||||||
|
- 200
|
||||||
|
- 201
|
||||||
|
- 204
|
||||||
|
headers:
|
||||||
|
Content-type : application/json
|
||||||
|
body:
|
||||||
|
name : "{{ item.inventory_hostname }}"
|
||||||
|
description : "{{ item.inventory_name }}"
|
||||||
|
inventory : "{{ r_inv_id.id | default(r_inventory.json.id) }}"
|
||||||
|
body_format : json
|
||||||
|
return_content : no
|
||||||
|
validate_certs : no
|
||||||
|
ignore_errors : yes
|
||||||
|
register : r_inventory_host
|
||||||
|
loop : "{{ r_csv_hosts }}"
|
||||||
|
loop_control :
|
||||||
|
label : "{{ item.inventory_hostname }}"
|
||||||
|
when :
|
||||||
|
- r_twr_host_list[item.inventory_hostname] is defined
|
||||||
|
- r_twr_host_list[item.inventory_hostname].groups[item.tower_group] is not defined
|
||||||
|
|
||||||
|
|
||||||
|
...
|
15
templates/csv_inventory.j2
Normal file
15
templates/csv_inventory.j2
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[
|
||||||
|
{% for item in __csv_inventory.split("\n") %}
|
||||||
|
{% if loop.index != 1 %}
|
||||||
|
{% set list = item.split(",") %}
|
||||||
|
{
|
||||||
|
"{{ __csv_fields[0]}}" : "{{ list[0]|trim() }}",
|
||||||
|
"{{ __csv_fields[1]}}" : "{{ list[1]|trim() }}",
|
||||||
|
"{{ __csv_fields[2]}}" : "{{ list[2]|trim() }}",
|
||||||
|
"{{ __csv_fields[3]}}" : "{{ list[3]|trim() }}",
|
||||||
|
"{{ __csv_fields[4]}}" : "{{ list[4]|trim() }}",
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
]
|
9
templates/get_inventory_id.j2
Normal file
9
templates/get_inventory_id.j2
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{% for inventory_item in r_get_inv_list.json.results %}
|
||||||
|
{% if inventory_item.name == __inventory %}
|
||||||
|
{
|
||||||
|
"name" : "{{ inventory_item.name }}",
|
||||||
|
"id" : "{{ inventory_item.id }}",
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
11
templates/host_list_w_group.j2
Normal file
11
templates/host_list_w_group.j2
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
{% for inv_host in r_get_inv_host_list.json.results %}
|
||||||
|
"{{ inv_host.name }}": {
|
||||||
|
"groups" : {
|
||||||
|
{% for twr_groups in inv_host.summary_fields.groups.results %}
|
||||||
|
"{{ twr_groups.name }}": "{{ twr_groups.id }}",
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
8
templates/inv_group_list.j2
Normal file
8
templates/inv_group_list.j2
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{% for inv_group in r_get_inv_group_list.json.results %}
|
||||||
|
{
|
||||||
|
"id" : "{{ inv_group.id }}",
|
||||||
|
"name" : "{{ inv_group.name }}"
|
||||||
|
},
|
||||||
|
{% endfor %}
|
||||||
|
]
|
50
vars/defaults.yml
Normal file
50
vars/defaults.yml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
__tower_url : https://10.1.1.71
|
||||||
|
__tower_user : admin
|
||||||
|
__tower_pass : redhat
|
||||||
|
|
||||||
|
|
||||||
|
# Organization in Tower for inventory
|
||||||
|
# (must exist in tower)
|
||||||
|
__organization : 1
|
||||||
|
|
||||||
|
|
||||||
|
# Inventory name
|
||||||
|
# (will create if it doesnt exist in tower)
|
||||||
|
__inventory : "CSV-Inventory"
|
||||||
|
|
||||||
|
|
||||||
|
# Inventory file in csv formay to load
|
||||||
|
__csv_file : "sample_inventory_1.csv"
|
||||||
|
__csv_inventory : "{{ lookup('file', 'files/' + __csv_file) }}"
|
||||||
|
|
||||||
|
|
||||||
|
# In order to support results of this size
|
||||||
|
# /etc/tower/settings.py or /etc/tower/conf.d/custom.py
|
||||||
|
# need to be modified to include: MAX_PAGE_SIZE=XXXX
|
||||||
|
# and `ansible-tower-service restart` executed.
|
||||||
|
__api_results : 5000
|
||||||
|
|
||||||
|
|
||||||
|
# This should match the fields in your CSV
|
||||||
|
#
|
||||||
|
# NOTE:
|
||||||
|
# The code will need to be updated to reflect changes
|
||||||
|
# made here
|
||||||
|
__csv_fields:
|
||||||
|
- inventory_name
|
||||||
|
- inventory_hostname
|
||||||
|
- ansible_host
|
||||||
|
- mac_address
|
||||||
|
- tower_group
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize r_inventory_list list
|
||||||
|
r_inventory_list: []
|
||||||
|
|
||||||
|
|
||||||
|
# Show debugging messages
|
||||||
|
__show_debug_msgs: no
|
||||||
|
|
||||||
|
|
||||||
|
...
|
Loading…
x
Reference in New Issue
Block a user