Skip to content

Commit 8e8da8d

Browse files
committed
Initial draft commit
1 parent e97e494 commit 8e8da8d

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Make coding more python3-ish, this is required for contributions to Ansible
4+
from __future__ import (absolute_import, division, print_function)
5+
__metaclass__ = type
6+
7+
from ansible.plugins.action import ActionBase
8+
from datetime import datetime
9+
from ansible.utils.vars import merge_hash
10+
11+
12+
13+
def get_sub_hierarchy(hierarchy, name, groups, parent=None):
14+
# Traverses a nested dictionary in search of a specific key (name)
15+
# If found, returns sub-dictionary as value for key of name "name"
16+
# If recursion was needed, result will be a dict with key equal to own parent key
17+
# E.g.
18+
# dict={ "master": { "europe": { "germany": {
19+
# "berlin": None,
20+
# "nuremberg": None
21+
# },
22+
# "france": {
23+
# "paris": None
24+
# },
25+
# },
26+
# "usa": None
27+
# }
28+
# }
29+
# Name="master" -> Returned: {'master': {'europe': {'germany': {'berlin': None, 'nuremberg': None}, 'france': {'paris': None}}, 'usa': None}}
30+
# Name="germany" -> Returned: {'europe': {'germany': {'berlin': None, 'nuremberg': None}}}
31+
32+
33+
top_level_keys = list(hierarchy.keys())
34+
35+
# Check if inventory name or any group name matches top level keys of dictionary
36+
for possible_name in [name] + groups:
37+
if possible_name in top_level_keys:
38+
name = possible_name
39+
40+
# If name is toplevel key, e.g. master
41+
if name in top_level_keys:
42+
if parent:
43+
# Only return the relevant sub-tree of the hierarchy
44+
hierarchy = {parent: {name: hierarchy[name]}}
45+
return hierarchy
46+
47+
# If name is subkey of toplevel key
48+
for top_level_key in top_level_keys:
49+
sub_hierarchy = hierarchy[top_level_key]
50+
if isinstance(sub_hierarchy, dict):
51+
new_hierarchy = get_sub_hierarchy(sub_hierarchy, name, groups, top_level_key)
52+
if new_hierarchy:
53+
return new_hierarchy
54+
55+
# Return empty dict if name not found anywhere within hierarchy
56+
return dict()
57+
58+
59+
60+
def get_best_host_attr(inventory, name):
61+
for host_option in [
62+
"ansible_fqdn",
63+
"ansible_hostname",
64+
"inventory_hostname",
65+
]:
66+
if host_option in inventory["hostvars"][name]:
67+
return inventory["hostvars"][name][host_option]
68+
# Return inventory hostname by default
69+
return name
70+
71+
72+
73+
def get_endpoints_from_zones(zones, name, inventory):
74+
# Return emtpy list if no zones are given
75+
if not zones:
76+
return list()
77+
78+
endpoints = list()
79+
80+
own_zone = [zone for zone in zones if name in zone["endpoints"]][0]
81+
own_zone_name = own_zone["name"]
82+
own_parent_zone_name = own_zone["parent"] if "parent" in own_zone else None
83+
84+
for zone in zones:
85+
for endpoint_name in zone["endpoints"]:
86+
endpoint = dict()
87+
endpoint["name"] = endpoint_name
88+
89+
# If own parent
90+
if zone["name"] == own_parent_zone_name:
91+
# If connection to own parent
92+
endpoint["host"] = get_best_host_attr(inventory, endpoint_name)
93+
elif zone["name"] == own_zone_name and endpoint_name != name:
94+
# If connection to HA partner
95+
endpoint["host"] = get_best_host_attr(inventory, endpoint_name)
96+
elif "parent" in zone and zone["parent"] == own_zone_name:
97+
# If connection to direct children
98+
endpoint["host"] = get_best_host_attr(inventory, endpoint_name)
99+
100+
endpoints.append(endpoint)
101+
102+
return endpoints
103+
104+
105+
106+
def get_zones_from_hierarchy(hierarchy, groups, parent=None):
107+
if not hierarchy:
108+
return list()
109+
110+
zone_list = list()
111+
zone_name = list(hierarchy.keys())[0]
112+
113+
this_zone = dict()
114+
this_zone["name"] = zone_name
115+
116+
if parent:
117+
this_zone["parent"] = parent
118+
119+
120+
# get_endpoints(name, inventory, groups)
121+
endpoints = list()
122+
if zone_name in groups:
123+
for host in groups[zone_name]:
124+
endpoints.append(host)
125+
else:
126+
endpoints.append(zone_name)
127+
128+
this_zone["endpoints"] = endpoints
129+
zone_list.append(this_zone)
130+
131+
132+
if isinstance(hierarchy[zone_name], dict):
133+
for key, value in hierarchy[zone_name].items():
134+
# Recursion step: combine current list (single zone) with each child zone
135+
zone_list += get_zones_from_hierarchy({key: value}, groups, parent=zone_name)
136+
137+
return zone_list
138+
139+
140+
141+
class ActionModule(ActionBase):
142+
def run(self, tmp=None, task_vars=None):
143+
result = super(ActionModule, self).run(tmp, task_vars)
144+
del tmp
145+
146+
module_args = self._task.args.copy()
147+
#module_return = self._execute_module(
148+
# module_name="setup",
149+
# module_args=module_args,
150+
# task_vars=task_vars, tmp=tmp
151+
#)
152+
153+
#### Variables needed for processing
154+
hierarchy = merge_hash(module_args.pop("hierarchy", False), dict())
155+
ansible_inventory_hostname = task_vars["inventory_hostname"]
156+
ansible_groups = task_vars["groups"]
157+
ansible_host_groups = list(task_vars["group_names"])
158+
159+
if "all" in ansible_host_groups:
160+
ansible_host_groups.remove("all")
161+
if "ungrouped" in ansible_host_groups:
162+
ansible_host_groups.remove("ungrouped")
163+
164+
165+
# Get sub portion of the given hierarchy starting at own parent, or self if no parent
166+
sub_hierarchy = get_sub_hierarchy(hierarchy, ansible_inventory_hostname, ansible_host_groups)
167+
168+
# Get all zones this node needs to know (parent and all (sub-)children)
169+
icinga2_zones = get_zones_from_hierarchy(sub_hierarchy, ansible_groups)
170+
171+
# Get all endpoints for each known zone
172+
icinga2_endpoints = get_endpoints_from_zones(icinga2_zones, ansible_inventory_hostname, task_vars)
173+
174+
# TO BE DONE: Global zones
175+
# get them from another input instead of hierarchy (e.g. global_zones: ['director-global'])
176+
# ...
177+
178+
# Return results
179+
result["icinga2_zones"] = icinga2_zones
180+
result["icinga2_endpoints"] = icinga2_endpoints
181+
182+
return result

0 commit comments

Comments
 (0)