23
23
from functools import partial
25
25
from charmhelpers.core.hookenv import unit_get
26
from charmhelpers.fetch import apt_install
26
from charmhelpers.fetch import apt_install, apt_update
27
27
from charmhelpers.core.hookenv import (
34
34
except ImportError:
35
apt_install('python-netifaces')
35
apt_update(fatal=True)
36
apt_install('python-netifaces', fatal=True)
40
41
except ImportError:
41
apt_install('python-netaddr')
42
apt_update(fatal=True)
43
apt_install('python-netaddr', fatal=True)
59
61
"""Get an IPv4 or IPv6 address within the network from the host.
61
63
:param network (str): CIDR presentation format. For example,
64
'192.168.1.0/24'. Supports multiple networks as a space-delimited list.
63
65
:param fallback (str): If no address is found, return fallback.
64
66
:param fatal (boolean): If no address is found, fallback is not
65
67
set and fatal is True then exit(1).
76
_validate_cidr(network)
77
network = netaddr.IPNetwork(network)
78
for iface in netifaces.interfaces():
79
addresses = netifaces.ifaddresses(iface)
80
if network.version == 4 and netifaces.AF_INET in addresses:
81
addr = addresses[netifaces.AF_INET][0]['addr']
82
netmask = addresses[netifaces.AF_INET][0]['netmask']
83
cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
78
networks = network.split() or [network]
79
for network in networks:
80
_validate_cidr(network)
81
network = netaddr.IPNetwork(network)
82
for iface in netifaces.interfaces():
83
addresses = netifaces.ifaddresses(iface)
84
if network.version == 4 and netifaces.AF_INET in addresses:
85
addr = addresses[netifaces.AF_INET][0]['addr']
86
netmask = addresses[netifaces.AF_INET][0]['netmask']
87
cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
87
if network.version == 6 and netifaces.AF_INET6 in addresses:
88
for addr in addresses[netifaces.AF_INET6]:
89
if not addr['addr'].startswith('fe80'):
90
cidr = netaddr.IPNetwork("%s/%s" % (addr['addr'],
91
if network.version == 6 and netifaces.AF_INET6 in addresses:
92
for addr in addresses[netifaces.AF_INET6]:
93
if not addr['addr'].startswith('fe80'):
94
cidr = netaddr.IPNetwork("%s/%s" % (addr['addr'],
95
99
if fallback is not None:
187
191
get_netmask_for_address = partial(_get_for_address, key='netmask')
194
def resolve_network_cidr(ip_address):
196
Resolves the full address cidr of an ip_address based on
197
configured network interfaces
199
netmask = get_netmask_for_address(ip_address)
200
return str(netaddr.IPNetwork("%s/%s" % (ip_address, netmask)).cidr)
190
203
def format_ipv6_addr(address):
191
204
"""If address is IPv6, wrap it in '[]' otherwise return None.
450
467
return result.split('.')[0]
470
def port_has_listener(address, port):
472
Returns True if the address:port is open and being listened to,
475
@param address: an IP address or hostname
476
@param port: integer port
478
Note calls 'zc' via a subprocess shell
480
cmd = ['nc', '-z', address, str(port)]
481
result = subprocess.call(cmd)
482
return not(bool(result))