forked from saratov/infra
d89c7ab77e
firts we check that the VM has already get some IP address and if so we just deploy as usual. If VM have no IP address on any interface we throw all interfaces except first (eth0) to the `empty vlan` that have no DHCP server enabled. VLAD ID defined in environment variable. After network configuration inside VM we restore propper VLAN IDs on all interfaces. This approach should help in situations when DHCP available on more than one interfaces and those interfaces configured as dhcp-clients, thus more than one default gw will be configured with some metrics and all traffic will be routed to the right one or will be not.
130 lines
3.6 KiB
Python
130 lines
3.6 KiB
Python
#!/usr/bin/env python
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
from ansible.errors import AnsibleError
|
|
from ansible.plugins.lookup import LookupBase
|
|
from ansible.utils.listify import listify_lookup_plugin_terms
|
|
import collections
|
|
import re
|
|
import ipaddress
|
|
|
|
try:
|
|
import jmespath
|
|
HAS_LIB = True
|
|
except ImportError:
|
|
HAS_LIB = False
|
|
|
|
def dict_merge(dct, merge_dct):
|
|
""" Recursive dict merge. Inspired by :meth:``dict.update()``, instead of
|
|
updating only top-level keys, dict_merge recurses down into dicts nested
|
|
to an arbitrary depth, updating keys. The ``merge_dct`` is merged into
|
|
``dct``.
|
|
:param dct: dict onto which the merge is executed
|
|
:param merge_dct: dct merged into dct
|
|
:return: None
|
|
"""
|
|
for k, v in merge_dct.iteritems():
|
|
if (k in dct and isinstance(dct[k], dict)
|
|
and isinstance(merge_dct[k], collections.Mapping)):
|
|
dict_merge(dct[k], merge_dct[k])
|
|
else:
|
|
dct[k] = merge_dct[k]
|
|
|
|
|
|
def dict_inject(data, path, obj):
|
|
p = path.split('/')
|
|
p.remove('')
|
|
p.reverse()
|
|
c = obj
|
|
for n in p:
|
|
c = {n: c}
|
|
z = data.copy()
|
|
dict_merge(z, c)
|
|
return z
|
|
|
|
|
|
def to_nics_dict(src):
|
|
nics = {}
|
|
lo_pat = re.compile("^lo[0-9]{0,2}$")
|
|
for n in src:
|
|
if not lo_pat.match(n['name']):
|
|
addrs = []
|
|
if "ip-addresses" in n:
|
|
for a in n['ip-addresses']:
|
|
if a['ip-address-type'] != "ipv6":
|
|
addrs.append(u'%s/%s' % (a['ip-address'], a['prefix']))
|
|
nics[n['name']] = {"mac": n['hardware-address'],
|
|
"addrs": addrs}
|
|
return nics
|
|
|
|
def to_proxmox_net(src, vlan=None):
|
|
out = {}
|
|
ks = ['virtio', 'bridge', 'tag']
|
|
for k,v in src.items():
|
|
if k != 'eth0' and vlan:
|
|
v['tag'] = vlan
|
|
|
|
k = k.replace('eth','net')
|
|
[ v.pop(x, None) for x in set(v.keys()).difference(ks) ]
|
|
v.pop('ipv4', None) # remove unused key
|
|
if 'virtio' not in v.items():
|
|
res = "virtio,"
|
|
else:
|
|
res = ""
|
|
res = res + ','.join(map(lambda x:str('='.join(map(str,x))), v.items()))
|
|
out[k] = res
|
|
return out
|
|
|
|
def gen_nics_addrs(node, num):
|
|
res = node.copy()
|
|
for k, v in res['net'].items():
|
|
for i, a in enumerate(res['net'][k]['ipv4']):
|
|
interface = ipaddress.ip_interface(a)
|
|
addr = interface.ip + int(num)
|
|
cidr = interface.network.prefixlen
|
|
res['net'][k]['ipv4'][i] = '%s/%s' % (addr, cidr)
|
|
return res
|
|
|
|
def list_to_dict(src):
|
|
res = {}
|
|
for a in src:
|
|
k = list(a.keys())[0]
|
|
res[k] = a[k]
|
|
return res
|
|
|
|
def get_steps(node, steps_list):
|
|
res = []
|
|
for idx, ss in enumerate(steps_list):
|
|
for a in ss:
|
|
if node in a['binds']:
|
|
res.append("step%s" % idx)
|
|
return res
|
|
|
|
def filter_dict(src, pred):
|
|
p = eval(pred)
|
|
return { k: v for k, v in src.iteritems() if p(v)}
|
|
|
|
def format2(what, fmt):
|
|
return fmt % what
|
|
|
|
def domain2dn(domain):
|
|
return ','.join('DC=%s' % s for s in domain.split('.'))
|
|
|
|
class FilterModule(object):
|
|
''' Query filter '''
|
|
def filters(self):
|
|
return {
|
|
'dict_merge': dict_merge,
|
|
'dict_inject': dict_inject,
|
|
'to_nics_dict': to_nics_dict,
|
|
'to_proxmox_net': to_proxmox_net,
|
|
'gen_nics_addrs': gen_nics_addrs,
|
|
'list_to_dict': list_to_dict,
|
|
'get_steps': get_steps,
|
|
'filter_dict': filter_dict,
|
|
'format2': format2,
|
|
'domain2dn': domain2dn
|
|
}
|