~openstack-charmers-next/charms/wily/lxd/trunk

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/network/ip.py

  • Committer: James Page
  • Date: 2016-02-25 16:35:49 UTC
  • mfrom: (50.1.1 trunk)
  • Revision ID: james.page@ubuntu.com-20160225163549-9owa4y2x6hbj3ysa
Resync helpers

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
from functools import partial
24
24
 
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 (
28
28
    log,
29
29
    WARNING,
32
32
try:
33
33
    import netifaces
34
34
except ImportError:
35
 
    apt_install('python-netifaces')
 
35
    apt_update(fatal=True)
 
36
    apt_install('python-netifaces', fatal=True)
36
37
    import netifaces
37
38
 
38
39
try:
39
40
    import netaddr
40
41
except ImportError:
41
 
    apt_install('python-netaddr')
 
42
    apt_update(fatal=True)
 
43
    apt_install('python-netaddr', fatal=True)
42
44
    import netaddr
43
45
 
44
46
 
51
53
 
52
54
 
53
55
def no_ip_found_error_out(network):
54
 
    errmsg = ("No IP address found in network: %s" % network)
 
56
    errmsg = ("No IP address found in network(s): %s" % network)
55
57
    raise ValueError(errmsg)
56
58
 
57
59
 
59
61
    """Get an IPv4 or IPv6 address within the network from the host.
60
62
 
61
63
    :param network (str): CIDR presentation format. For example,
62
 
        '192.168.1.0/24'.
 
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).
73
75
        else:
74
76
            return None
75
77
 
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))
84
 
            if cidr in network:
85
 
                return str(cidr.ip)
 
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))
 
88
                if cidr in network:
 
89
                    return str(cidr.ip)
86
90
 
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
 
                                                        addr['netmask']))
92
 
                    if cidr in network:
93
 
                        return str(cidr.ip)
 
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
                                                            addr['netmask']))
 
96
                        if cidr in network:
 
97
                            return str(cidr.ip)
94
98
 
95
99
    if fallback is not None:
96
100
        return fallback
452
456
            return result
453
457
    else:
454
458
        return result.split('.')[0]
 
459
 
 
460
 
 
461
def port_has_listener(address, port):
 
462
    """
 
463
    Returns True if the address:port is open and being listened to,
 
464
    else False.
 
465
 
 
466
    @param address: an IP address or hostname
 
467
    @param port: integer port
 
468
 
 
469
    Note calls 'zc' via a subprocess shell
 
470
    """
 
471
    cmd = ['nc', '-z', address, str(port)]
 
472
    result = subprocess.call(cmd)
 
473
    return not(bool(result))