├── example.xlsx
├── example_with_formula.xlsx
├── .idea
├── vcs.xml
├── misc.xml
├── modules.xml
├── xlstofacts.iml
└── workspace.xml
├── README.md
└── xls_to_facts.py
/example.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mamullen13316/ansible_xls_to_facts/HEAD/example.xlsx
--------------------------------------------------------------------------------
/example_with_formula.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mamullen13316/ansible_xls_to_facts/HEAD/example_with_formula.xlsx
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/xlstofacts.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Ansible module which imports an Excel spreadsheet to Ansible facts.
2 |
3 | Each sheet is represented by "spreadsheet_{sheet_name}" in Ansible. The column headers of each row in the sheet are converted to variable names, and values are populated for each row.
4 |
5 | Copy to the library path as specified in your ansible.cfg file.
6 |
7 | Requires the openpyxl Python module on the Ansible host.
8 | - Default behavior is set for [*data_only*](https://openpyxl.readthedocs.io/en/stable/changes.html#id485) to allow extracting values only from formulae
9 |
10 | Install with PIP:
11 |
12 | sudo pip install openpyxl
13 |
--------------------------------------------------------------------------------
/xls_to_facts.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | """
4 | Copyright (c) 2016 World Wide Technology, Inc.
5 | All rights reserved.
6 |
7 | Revision history:
8 | 7 Apr 2016 | 1.0 - initial release
9 |
10 |
11 | """
12 |
13 | DOCUMENTATION = '''
14 | ---
15 | module: xls_to_facts.py
16 | author: Matt Mullen, World Wide Technology
17 | version_added: "1.0"
18 | short_description: Read an Excel .xlsx file and output Ansible facts
19 | description:
20 | - Read the XLS file specified and output Ansible facts in the form of a list with each
21 | element in the list as a dictionary using the column header as the key and the contents
22 | of the cell as the value. A dictionary is created for each sheet, in the format spreadsheet_SheetName.
23 |
24 | requirements:
25 | - The openpyxl Python module must be installed on the Ansible host. This can be installed using pip:
26 | sudo pip install openpyxl
27 |
28 | options:
29 | src:
30 | description:
31 | - The name of the Excel spreadsheet
32 | required: true
33 |
34 |
35 | '''
36 |
37 | EXAMPLES = '''
38 |
39 | Running the module from the command line:
40 |
41 | ansible localhost -m xls_to_facts -a src="example.xlsx" -M ~/ansible/library
42 |
43 | localhost | SUCCESS => {
44 | "ansible_facts": {
45 | "spreadsheet_Sheet1": [
46 | {
47 | "Hostname": "Switch-1",
48 | "Mgmt_ip": "10.0.0.1"
49 | },
50 | {
51 | "Hostname": "Switch-2",
52 | "Mgmt_ip": "10.0.0.2"
53 | },
54 | {
55 | "Hostname": "Switch-3",
56 | "Mgmt_ip": "10.0.0.3"
57 | }
58 | ],
59 | "spreadsheet_Sheet2": [
60 | {
61 | "Description": "To Spine-1",
62 | "Interface": "Ethernet1/1",
63 | "Interface_IP": "192.168.100.1/30"
64 | },
65 | {
66 | "Description": "To Spine-2",
67 | "Interface": "Ethernet1/2",
68 | "Interface_IP": "192.168.100.5/30"
69 | }
70 | ]
71 | },
72 | "changed": false
73 |
74 | In a role configuration, given a group and host entry:
75 |
76 | [access_switch]
77 | 10.0.0.1 ansible_connection=local ansible_ssh_user=ansible_local_user hostname=Switch-1
78 | #
79 |
80 | $ cat xls_to_facts.yml
81 | ---
82 | - name: Test Role to import facts from Excel
83 | hosts: access_switch
84 |
85 | roles:
86 | - {role: xls_to_facts, debug: on}
87 |
88 |
89 | $ ansible-playbook xls_to_facts.yml --ask-vault
90 |
91 | '''
92 | import openpyxl
93 |
94 | # ---------------------------------------------------------------------------
95 | # read_xls_dict
96 | # ---------------------------------------------------------------------------
97 |
98 | def read_xls_dict(input_file):
99 | "Read the XLS file and return as Ansible facts"
100 | result = {"ansible_facts":{}}
101 | spreadsheet = {}
102 | try:
103 | wb = openpyxl.load_workbook(input_file, data_only=True)
104 | for sheet in wb.get_sheet_names():
105 | ansible_sheet_name = 'spreadsheet_' + sheet
106 | spreadsheet[ansible_sheet_name] = []
107 | current_sheet = wb.get_sheet_by_name(sheet)
108 | dict_keys = []
109 | for c in range(1,current_sheet.max_column + 1):
110 | dict_keys.append(current_sheet.cell(row=1,column=c).value)
111 | for r in range (2,current_sheet.max_row + 1):
112 | temp_dict = {}
113 | for c in range(1,current_sheet.max_column + 1):
114 | temp_dict[dict_keys[c-1]] = current_sheet.cell(row=r,column=c).value
115 | spreadsheet[ansible_sheet_name].append(temp_dict)
116 | except IOError:
117 | return (1, "IOError on input file:%s" % input_file)
118 |
119 | result["ansible_facts"] = spreadsheet
120 | return (0, result)
121 |
122 | # ---------------------------------------------------------------------------
123 | # MAIN
124 | # ---------------------------------------------------------------------------
125 |
126 | def main():
127 | " "
128 | module = AnsibleModule(argument_spec = dict(
129 | src = dict(required=True)
130 | ),
131 | add_file_common_args=True)
132 |
133 | code, response = read_xls_dict(module.params["src"])
134 | if code == 1:
135 | module.fail_json(msg=response)
136 | else:
137 | module.exit_json(**response)
138 |
139 | return code
140 |
141 |
142 | from ansible.module_utils.basic import *
143 | main()
144 | #
145 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | 1547608640677
101 |
102 |
103 | 1547608640677
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------