~corey.bryant/charms/trusty/ceph/charm-proof-next

« back to all changes in this revision

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

  • Committer: Edward Hope-Morley
  • Date: 2014-11-25 18:29:07 UTC
  • mfrom: (85.2.4 ceph)
  • Revision ID: edward.hope-morley@canonical.com-20141125182907-oyi0vts2tw6o0a5p
[niedbalski,r=hopem]

Adds sysctl config option to allow dict of
sysctl key/val pairs to be set on ceph nodes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
import glob
2
2
import re
3
3
import subprocess
4
 
import sys
5
4
 
6
5
from functools import partial
7
6
 
33
32
                         network)
34
33
 
35
34
 
 
35
def no_ip_found_error_out(network):
 
36
    errmsg = ("No IP address found in network: %s" % network)
 
37
    raise ValueError(errmsg)
 
38
 
 
39
 
36
40
def get_address_in_network(network, fallback=None, fatal=False):
37
 
    """
38
 
    Get an IPv4 or IPv6 address within the network from the host.
 
41
    """Get an IPv4 or IPv6 address within the network from the host.
39
42
 
40
43
    :param network (str): CIDR presentation format. For example,
41
44
        '192.168.1.0/24'.
42
45
    :param fallback (str): If no address is found, return fallback.
43
46
    :param fatal (boolean): If no address is found, fallback is not
44
47
        set and fatal is True then exit(1).
45
 
 
46
48
    """
47
 
 
48
 
    def not_found_error_out():
49
 
        log("No IP address found in network: %s" % network,
50
 
            level=ERROR)
51
 
        sys.exit(1)
52
 
 
53
49
    if network is None:
54
50
        if fallback is not None:
55
51
            return fallback
 
52
 
 
53
        if fatal:
 
54
            no_ip_found_error_out(network)
56
55
        else:
57
 
            if fatal:
58
 
                not_found_error_out()
59
 
            else:
60
 
                return None
 
56
            return None
61
57
 
62
58
    _validate_cidr(network)
63
59
    network = netaddr.IPNetwork(network)
69
65
            cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
70
66
            if cidr in network:
71
67
                return str(cidr.ip)
 
68
 
72
69
        if network.version == 6 and netifaces.AF_INET6 in addresses:
73
70
            for addr in addresses[netifaces.AF_INET6]:
74
71
                if not addr['addr'].startswith('fe80'):
81
78
        return fallback
82
79
 
83
80
    if fatal:
84
 
        not_found_error_out()
 
81
        no_ip_found_error_out(network)
85
82
 
86
83
    return None
87
84
 
88
85
 
89
86
def is_ipv6(address):
90
 
    '''Determine whether provided address is IPv6 or not'''
 
87
    """Determine whether provided address is IPv6 or not."""
91
88
    try:
92
89
        address = netaddr.IPAddress(address)
93
90
    except netaddr.AddrFormatError:
94
91
        # probably a hostname - so not an address at all!
95
92
        return False
96
 
    else:
97
 
        return address.version == 6
 
93
 
 
94
    return address.version == 6
98
95
 
99
96
 
100
97
def is_address_in_network(network, address):
112
109
    except (netaddr.core.AddrFormatError, ValueError):
113
110
        raise ValueError("Network (%s) is not in CIDR presentation format" %
114
111
                         network)
 
112
 
115
113
    try:
116
114
        address = netaddr.IPAddress(address)
117
115
    except (netaddr.core.AddrFormatError, ValueError):
118
116
        raise ValueError("Address (%s) is not in correct presentation format" %
119
117
                         address)
 
118
 
120
119
    if address in network:
121
120
        return True
122
121
    else:
146
145
                    return iface
147
146
                else:
148
147
                    return addresses[netifaces.AF_INET][0][key]
 
148
 
149
149
        if address.version == 6 and netifaces.AF_INET6 in addresses:
150
150
            for addr in addresses[netifaces.AF_INET6]:
151
151
                if not addr['addr'].startswith('fe80'):
159
159
                            return str(cidr).split('/')[1]
160
160
                        else:
161
161
                            return addr[key]
 
162
 
162
163
    return None
163
164
 
164
165
 
165
166
get_iface_for_address = partial(_get_for_address, key='iface')
166
167
 
 
168
 
167
169
get_netmask_for_address = partial(_get_for_address, key='netmask')
168
170
 
169
171
 
170
172
def format_ipv6_addr(address):
171
 
    """
172
 
    IPv6 needs to be wrapped with [] in url link to parse correctly.
 
173
    """If address is IPv6, wrap it in '[]' otherwise return None.
 
174
 
 
175
    This is required by most configuration files when specifying IPv6
 
176
    addresses.
173
177
    """
174
178
    if is_ipv6(address):
 
179
<<<<<<< TREE
 
180
        return "[%s]" % address
 
181
=======
175
182
        address = "[%s]" % address
176
183
    else:
177
184
        address = None
 
185
>>>>>>> MERGE-SOURCE
178
186
 
179
 
    return address
 
187
    return None
180
188
 
181
189
 
182
190
def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False,
183
191
                   fatal=True, exc_list=None):
184
 
    """
185
 
    Return the assigned IP address for a given interface, if any, or [].
186
 
    """
 
192
    """Return the assigned IP address for a given interface, if any."""
187
193
    # Extract nic if passed /dev/ethX
188
194
    if '/' in iface:
189
195
        iface = iface.split('/')[-1]
 
196
 
190
197
    if not exc_list:
191
198
        exc_list = []
 
199
 
192
200
    try:
193
201
        inet_num = getattr(netifaces, inet_type)
194
202
    except AttributeError:
195
 
        raise Exception('Unknown inet type ' + str(inet_type))
 
203
        raise Exception("Unknown inet type '%s'" % str(inet_type))
196
204
 
197
205
    interfaces = netifaces.interfaces()
198
206
    if inc_aliases:
200
208
        for _iface in interfaces:
201
209
            if iface == _iface or _iface.split(':')[0] == iface:
202
210
                ifaces.append(_iface)
 
211
 
203
212
        if fatal and not ifaces:
204
213
            raise Exception("Invalid interface '%s'" % iface)
 
214
 
205
215
        ifaces.sort()
206
216
    else:
207
217
        if iface not in interfaces:
208
218
            if fatal:
209
 
                raise Exception("%s not found " % (iface))
 
219
                raise Exception("Interface '%s' not found " % (iface))
210
220
            else:
211
221
                return []
 
222
 
212
223
        else:
213
224
            ifaces = [iface]
214
225
 
219
230
            for entry in net_info[inet_num]:
220
231
                if 'addr' in entry and entry['addr'] not in exc_list:
221
232
                    addresses.append(entry['addr'])
 
233
 
222
234
    if fatal and not addresses:
223
235
        raise Exception("Interface '%s' doesn't have any %s addresses." %
224
236
                        (iface, inet_type))
225
 
    return addresses
 
237
 
 
238
    return sorted(addresses)
 
239
 
226
240
 
227
241
get_ipv4_addr = partial(get_iface_addr, inet_type='AF_INET')
228
242
 
239
253
                raw = re.match(ll_key, _addr)
240
254
                if raw:
241
255
                    _addr = raw.group(1)
 
256
 
242
257
                if _addr == addr:
243
258
                    log("Address '%s' is configured on iface '%s'" %
244
259
                        (addr, iface))
249
264
 
250
265
 
251
266
def sniff_iface(f):
252
 
    """If no iface provided, inject net iface inferred from unit private
253
 
    address.
 
267
    """Ensure decorated function is called with a value for iface.
 
268
 
 
269
    If no iface provided, inject net iface inferred from unit private address.
254
270
    """
255
271
    def iface_sniffer(*args, **kwargs):
256
272
        if not kwargs.get('iface', None):
293
309
        if global_addrs:
294
310
            # Make sure any found global addresses are not temporary
295
311
            cmd = ['ip', 'addr', 'show', iface]
296
 
            out = subprocess.check_output(cmd)
 
312
            out = subprocess.check_output(cmd).decode('UTF-8')
297
313
            if dynamic_only:
298
314
                key = re.compile("inet6 (.+)/[0-9]+ scope global dynamic.*")
299
315
            else:
315
331
                return addrs
316
332
 
317
333
    if fatal:
318
 
        raise Exception("Interface '%s' doesn't have a scope global "
 
334
        raise Exception("Interface '%s' does not have a scope global "
319
335
                        "non-temporary ipv6 address." % iface)
320
336
 
321
337
    return []
322
338
 
323
339
 
324
340
def get_bridges(vnic_dir='/sys/devices/virtual/net'):
325
 
    """
326
 
    Return a list of bridges on the system or []
327
 
    """
328
 
    b_rgex = vnic_dir + '/*/bridge'
329
 
    return [x.replace(vnic_dir, '').split('/')[1] for x in glob.glob(b_rgex)]
 
341
    """Return a list of bridges on the system."""
 
342
    b_regex = "%s/*/bridge" % vnic_dir
 
343
    return [x.replace(vnic_dir, '').split('/')[1] for x in glob.glob(b_regex)]
330
344
 
331
345
 
332
346
def get_bridge_nics(bridge, vnic_dir='/sys/devices/virtual/net'):
333
 
    """
334
 
    Return a list of nics comprising a given bridge on the system or []
335
 
    """
336
 
    brif_rgex = "%s/%s/brif/*" % (vnic_dir, bridge)
337
 
    return [x.split('/')[-1] for x in glob.glob(brif_rgex)]
 
347
    """Return a list of nics comprising a given bridge on the system."""
 
348
    brif_regex = "%s/%s/brif/*" % (vnic_dir, bridge)
 
349
    return [x.split('/')[-1] for x in glob.glob(brif_regex)]
338
350
 
339
351
 
340
352
def is_bridge_member(nic):
341
 
    """
342
 
    Check if a given nic is a member of a bridge
343
 
    """
 
353
    """Check if a given nic is a member of a bridge."""
344
354
    for bridge in get_bridges():
345
355
        if nic in get_bridge_nics(bridge):
346
356
            return True
 
357
 
347
358
    return False