Skip to content

Instantly share code, notes, and snippets.

@riccardomurri
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riccardomurri/8719567 to your computer and use it in GitHub Desktop.
Save riccardomurri/8719567 to your computer and use it in GitHub Desktop.
CFEngine module for generating contexts and variables based on the output of `ip addr show`.
#! /usr/bin/env python
#
"""
CFEngine module to define contexts and variables based on output
of the `ip addr show` command.
- For each IPv4 or IPv6 address found on an interface, a class
`ip_ipv4_A_B_C_D` or `ip_ipv6_AAAA_BBBB_..._HHHH` is defined (like
what CFEngine normally does, but including aliases and VLAN-tagged
interfaces).
- For each *network* attached to an interface, a corresponding class
`ip_ipv4_net_A_...` and `ip_ipv6_AAAA_...` is generated. Note that
the "local address" part of the network, i.e., any bits after the
prefix len, is zeroed out.
- For each ethernet MAC address, a class `ip_mac_AA_BB_..._FF` is defined.
- For each interface, a class `ip_net_iface_NAME` is defined.
- For each interface feature (e.g., "up", "broadcast"), a class
`ip_net_iface_NAME_FEATURE` is defined.
- Finally, the entire information extracted from `ip show addr` is set
into CFEngine variables:
* ``net_iface[NAME][state]`` one of the keywords ``UP``, ``DOWN``, ``UNKNOWN``
* ``net_iface[NAME][mtu]`` the value of the MTU in bytes
* ``net_iface[NAME][ipv4]`` an slist of all the addresses on the interface (or its aliases)
* ``net_iface[NAME][ipv6]`` an slist of all the IPv6 addresses on the interface
Note that Linux interface names `eth0.1` (interface eth0 with packets
tagged for VLAN 1) and `eth0:1` (IPv4 alias address on `eth0`) would
canonicalize to the same string `eth0_1`. o avoid the clash, this
module thus translates the first one as `eth0_vlan1` and the second as
`eth0_alias1`.
This should be retired when CFEngine bugs #3976 and #3420 are solved.
"""
#
# Copyright (C) 2014 GC3, University of Zurich. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
import optparse
import re
import subprocess
import sys
## aux functions
NONCANONICAL_RE = re.compile('[^0-9a-z_]', re.I)
def canonify(s):
"""Return copy of string `s` with all non-alphanumeric characters replaced by ``_``."""
# see: http://stackoverflow.com/questions/10017147/python-replace-characters-in-string
return NONCANONICAL_RE.sub('_', s[:])
def parse_ipv4_addr(spec):
"""
Parse an IPv4 address.
The `spec` string must contain an IPv4 address in dot-quad form
A.B.C.D, plus an optional '/N' CIDR prefix length. If the CIDR
prefix is omitted, '/32' is assumed.
Return a tuple `(addr, pfxlen)`, where:
* `addr` is a 32-bit integer encoding the dot-quad;
* `pfxlen` is the integer value corresponding to the CIDR prefix length.
Examples::
>>> parse_ipv4_addr('127.0.0.1')
(2130706433, 32)
>>> parse_ipv4_addr('192.168.0.2/16')
(3232235522, 16)
"""
if '/' in spec:
addr, pfx_ = spec.split('/')
pfx = int(pfx_)
else:
addr = spec
pfx = 32
vs = addr.split('.')
assert len(vs) == 4, ("BUG: expected list `vs` with 4 components, got %r instead" % vs)
a, b, c, d = [ int(v) for v in vs ]
return (a*(2**24) + b*(2**16) + c*(2**8) + d, pfx)
def parse_ipv6_addr(spec):
"""
Parse an IPv6 address.
The `spec` string must contain an IPv6 address in standard
colon-separated form, plus an optional '/N' CIDR prefix length.
If the CIDR prefix is omitted, '/128' is assumed.
Return a tuple `(addr, pfxlen)`, where:
* `addr` is a long (128-bit) integer encoding the address;
* `pfxlen` is the integer value corresponding to the CIDR prefix length.
Examples::
>>> parse_ipv6_addr('::1')
(1L, 128)
>>> a1, p = parse_ipv6_addr('fe80::1/16')
>>> a2 = int('fe80', 16) * 2**(16*7) + 1
>>> a1 == a2
True
>>> p == 16
True
"""
if '/' in spec:
addr, pfx_ = spec.split('/')
pfx = int(pfx_)
else:
addr = spec
pfx = 128
parts = addr.split(':')
if '' in parts:
# address spec contains a '::' abbreviation
if spec.startswith('::'):
parts[0:2] = ['0' for _ in range(8 - len(parts) + 2)]
else:
i = parts.index('')
# splice in the missing 0's
parts[i:i+1] = ['0' for _ in range(8 - len(parts) + 1)]
# address is formed by 8x 16-bit components
assert len(parts) == 8, ("BUG: expected list `parts` with 8 components, got %r instead" % parts)
iaddr = 0
exp = 1
for p in reversed(parts):
iaddr += int(p, 16) * exp
exp *= 2**16
return (iaddr, pfx)
def _add_ip_address(kind, parser, data, iface, spec):
"""
Ensure that `data[iface]` has a `kind` entry, and that the IP
address extracted from `spec` is part of it.
"""
if iface not in data:
data[iface] = dict()
if kind not in data[iface]:
data[iface][kind] = set()
data[iface][kind].add(parser(spec))
def add_ipv4_address(data, iface, spec):
"""Shortcut for recurrent code."""
_add_ip_address('ipv4', parse_ipv4_addr, data, iface, spec)
def add_ipv6_address(data, iface, spec):
"""Shortcut for recurrent code."""
_add_ip_address('ipv6', parse_ipv6_addr, data, iface, spec)
def fmt_ipv4_addr(addr):
"""Return a string representing the 32-bit integer `addr` in dot-quad notation."""
parts = _break_ip_addr(32, 8, '%d', addr)
return str.join('.', parts)
def fmt_ipv6_addr(addr):
"""
Return a string representing the 128-bit integer `addr` in colon-separated IPv6 notation.
No attempt is made at shortening sequences of 0's::
>>> fmt_ipv6_addr(1)
'0000:0000:0000:0000:0000:0000:0000:0001'
"""
parts = _break_ip_addr(128, 16, '%04x', addr)
return str.join(':', parts)
def _ip_net_class(lineprefix, addr, addrwidth, netpfx, formatter):
mask = ~ (2**(addrwidth - netpfx) - 1)
netaddr = addr & mask
return formatter(netaddr)
def ipv4_net_class(lineprefix, addr, netpfx):
return _ip_net_class(lineprefix, addr, 32, netpfx, fmt_ipv4_addr)
def ipv6_net_class(lineprefix, addr, netpfx):
return _ip_net_class(lineprefix, addr, 128, netpfx, fmt_ipv6_addr)
# These last functions are for emulating CFEngine's behavior of
# defining `ipv4_A`, `ipv4_A_B`, `ipv4_A_B_C` when an IPv4 address
# `A.B.C.D` is detected. However the behavior becomes nonsenical with
# CIDR and especially nonsenical and verbose with IPv6 ... so it's
# currently disabled.
def _break_ip_addr(addrwidth, groupwidth, fmt, addr):
"""Break `addr` into groups of digits of `groupwidth` bits each."""
mask = 2**groupwidth - 1
parts = []
for _ in range(addrwidth / groupwidth):
parts.append(fmt % (addr & mask))
addr >>= groupwidth
parts.reverse()
return parts
def _ip_addr_classes(lineprefix, clsprefix, addrwidth, groupwidth, fmt, addr):
parts = _break_ip_addr(addrwidth, groupwidth, fmt, addr)
for i in range(len(parts)+1):
for j in range(1, i+1):
yield ('+' + lineprefix + clsprefix + '_' + str.join('_', parts[:j]))
def ipv4_addr_classes(prefix, addr):
return _ip_addr_classes(prefix, 'ipv4', 32, 8, "%d", addr)
def ipv6_addr_classes(prefix, addr):
return _ip_addr_classes(prefix, 'ipv6', 128, 16, "%04x", addr)
## main
def parse_ip_addr_show_output(stdout):
data = dict()
for line in stdout.split('\n'):
# skip empty lines
line = line.strip()
if line == '':
continue
parts = line.split()
# e.g., 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
if parts[0][0].isdigit():
# start parsing new interface
iface = parts[1][:-1] # strip final ':'
if '@' in iface:
# keep just initial segment of, e.g., 'eth0.618@eth0'
iface = iface.split('@')[0]
data[iface] = dict()
data[iface]['flags'] = parts[2][1:-1].split(',')
if len(parts) > 4:
for name, value in zip(parts[3::2], parts[4::2]):
data[iface][name] = value
# e.g., link/ether 00:11:43:fd:40:fe brd ff:ff:ff:ff:ff:ff
elif parts[0] == 'link/ether':
if 'mac' not in data[iface]:
data[iface]['mac'] = set()
data[iface]['mac'].add(parts[1].lower())
# e.g. inet 130.60.24.9/24 brd 130.60.24.255 scope global eth1
elif parts[0] == 'inet':
add_ipv4_address(data, iface, parts[1])
# # "alias" address lines contain "secondary IFACE:NN"
# if 'secondary' in parts:
# alias_iface = parts[1 + parts.index('secondary')]
# add_ipv4_address(data, alias_iface, parts[1])
# e.g., inet6 fe80::211:43ff:fefd:40fe/64 scope link
elif parts[0] == 'inet6':
add_ipv6_address(data, iface, parts[1])
# all done
return data
def create_cfengine_output_lines(data, selector=(lambda _: True), prefix=''):
"""
Return lines defining CFEngine contexts and variables
corresponding to the passed data.
Optional second argument `selector` is a function that is passed
the entire slice of data corresponding to a given interface, and
should return a boolean, indicating whether the interface should
be silently skipped (``False`` value) or processed (``True`` value).
Optional third argument `prefix` is a string that is prefixed to
all context and variable names.
"""
prefix = canonify(prefix)
lines = set()
for iface in data:
if not selector(data[iface]):
continue
# canonicalize interface name; try to avoid clashes:
# * `eth0.617` -> `eth0_vlan617`
# * `eth0:617` -> `eth0_alias617`
# any other pattern is canonified by just substituting invalid
# characters with ``_``.
if '.' in iface:
ifname, vlan = iface.split('.')
cname = canonify(ifname) + '_vlan' + vlan
elif ':' in iface:
ifname, alias = iface.split(':')
cname = canonify(ifname) + '_alias' + alias
else:
cname = canonify(iface)
lines.add("+%snet_iface_%s" % (prefix, cname))
for flag in data[iface]['flags']:
lines.add("+%snet_iface_%s_%s" % (prefix, cname, canonify(flag.lower())))
if 'mac' in data[iface]:
for macaddr in data[iface]['mac']:
lines.add('+' + canonify(prefix + 'mac_' + macaddr))
if 'ipv4' in data[iface]:
for addr, pfxlen in data[iface]['ipv4']:
addr_ = canonify(fmt_ipv4_addr(addr))
lines.add("+%sipv4_%s" % (prefix, addr_))
netaddr_ = canonify(ipv4_net_class(prefix, addr, pfxlen))
lines.add("+%sipv4_net_%s" % (prefix, netaddr_))
lines.add("@%snet_iface[%s][ipv4]={%s}"
% (prefix, cname, str.join(',', [('"%s"' % fmt_ipv4_addr(addr))
for addr, pfxlen in data[iface]['ipv4']])))
# for ipv4_addr in data[iface]['ipv4']:
# for line in ipv4_addr_classes(prefix, ipv4_addr[0]):
# lines.add(line)
if 'ipv6' in data[iface]:
for addr, pfxlen in data[iface]['ipv6']:
addr_ = canonify(fmt_ipv6_addr(addr))
lines.add("+%sipv6_%s" % (prefix, addr_))
netaddr_ = canonify(ipv6_net_class(prefix, addr, pfxlen))
lines.add("+%sipv6_net_%s" % (prefix, netaddr_))
lines.add("@%snet_iface[%s][ipv6]={%s}"
% (prefix, cname, str.join(',', [('"%s"' % fmt_ipv6_addr(addr))
for addr, pfxlen in data[iface]['ipv6']])))
# for ipv6_addr in data[iface]['ipv6']:
# for line in ipv6_addr_classes(prefix, ipv6_addr[0]):
# lines.add(line)
for key, value in data[iface].items():
if key in ['mac', 'ipv4', 'ipv6', 'flags']:
continue
lines.add('=%snet_iface[%s][%s]=%s' % (prefix, cname, key, value))
return lines
## main
if __name__ == '__main__':
cmdline = optparse.OptionParser('Usage: %prog [options]', description=__doc__)
cmdline.add_option('-a', '--all',
dest='all', action='store_true', default=False,
help="Include all interfaces, not just those in state UP.")
cmdline.add_option('-p', '--prefix',
dest='prefix', action='store', default='ip_',
help="Prefix all contexts and variable names with this string. (Default: 'ip_')")
cmdline.add_option('-i', '--input',
dest='input', metavar='FILE', action='store', default=None,
help="Parse data from the given FILE, instead of running `ip addr show`.")
cmdline.add_option('--selftest',
dest='selftest', action='store_true', default=False,
help="Run internal tests.")
(options, args) = cmdline.parse_args()
if len(args) > 0:
cmdline.error("No arguments should be given. Run '%prog --help' to get usage help.")
if not options.selftest:
if options.input:
stdout = open(options.input).read()
else:
ip_addr_show = subprocess.Popen(
['ip', 'addr', 'show'],
stdin=None, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)
stdout, stderr = ip_addr_show.communicate()
if stderr:
sys.stderr.write("ERROR running command `ip addr show`: aborting."
" Original error message follows.\n")
sys.stderr.write(stderr)
sys.exit(1)
if options.all:
def selector(iface_data):
return True
else:
def selector(iface_data):
return iface_data['state'] == 'UP'
data = parse_ip_addr_show_output(stdout)
lines = create_cfengine_output_lines(data, selector, options.prefix)
for line in sorted(lines):
print(line)
sys.exit(0)
else: # run self-test
from pprint import pprint
TEST_INPUT = """
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:11:43:fd:40:fe brd ff:ff:ff:ff:ff:ff
inet 192.168.160.20/22 brd 192.168.163.255 scope global eth0
inet 10.1.160.20/16 brd 10.1.255.255 scope global eth0:10
inet 192.168.160.1/22 brd 192.168.163.255 scope global secondary eth0:0
inet6 fe80::211:43ff:fefd:40fe/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
link/ether 00:26:2d:f6:0a:3c brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0e:0c:82:e4:ad brd ff:ff:ff:ff:ff:ff
inet 192.168.166.20/22 brd 192.168.167.255 scope global eth2
inet6 fe80::20e:cff:fe82:e4ad/64 scope link
valid_lft forever preferred_lft forever
5: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:24:d7:04:d8:bc brd ff:ff:ff:ff:ff:ff
inet 192.168.178.22/24 brd 192.168.178.255 scope global wlan0
valid_lft forever preferred_lft forever
inet6 fd00::4058:45da:6729:5b32/64 scope global temporary dynamic
valid_lft 6760sec preferred_lft 3160sec
inet6 fd00::224:d7ff:fe04:d8bc/64 scope global dynamic
valid_lft 6760sec preferred_lft 3160sec
inet6 fe80::224:d7ff:fe04:d8bc/64 scope link
valid_lft forever preferred_lft forever
6: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether c2:d8:1e:32:a0:a8 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
7: eth0.618@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 00:11:43:fd:40:fe brd ff:ff:ff:ff:ff:ff
inet 10.129.160.20/16 brd 10.129.255.255 scope global eth0.618
inet6 fe80::211:43ff:fefd:40fe/64 scope link
valid_lft forever preferred_lft forever
8: eth0.617@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 00:11:43:fd:40:fe brd ff:ff:ff:ff:ff:ff
inet 10.128.160.20/16 brd 10.128.255.255 scope global eth0.617
inet6 fe80::211:43ff:fefd:40fe/64 scope link
valid_lft forever preferred_lft forever
"""
# build variants
selectors = {
'--all': (lambda _: True),
'--up': (lambda ifdata: ifdata['state']=='UP'),
}
prefixes = [ 'ip_', '' ]
print ("Test parsing `ip addr show` output ...")
data = parse_ip_addr_show_output(TEST_INPUT)
assert data == {
'eth0': {
'flags': ['BROADCAST', 'MULTICAST', 'UP', 'LOWER_UP'],
'ipv4': set([(167878676, 16),
(3232276481, 22),
(3232276500, 22)]),
'ipv6': set([(338288524927261089654167871870801363198L,
64)]),
'mac': set(['00:11:43:fd:40:fe']),
'mtu': '1500',
'qdisc': 'pfifo_fast',
'qlen': '1000',
'state': 'UP'},
'eth0.617': {
'flags': ['BROADCAST', 'MULTICAST', 'UP', 'LOWER_UP'],
'ipv4': set([(176201748, 16)]),
'ipv6': set([(338288524927261089654167871870801363198L,
64)]),
'mac': set(['00:11:43:fd:40:fe']),
'mtu': '1500',
'qdisc': 'noqueue',
'state': 'UP'},
'eth0.618': {
'flags': ['BROADCAST', 'MULTICAST', 'UP', 'LOWER_UP'],
'ipv4': set([(176267284, 16)]),
'ipv6': set([(338288524927261089654167871870801363198L,
64)]),
'mac': set(['00:11:43:fd:40:fe']),
'mtu': '1500',
'qdisc': 'noqueue',
'state': 'UP'},
'eth1': {
'flags': ['NO-CARRIER', 'BROADCAST', 'MULTICAST', 'UP'],
'mac': set(['00:26:2d:f6:0a:3c']),
'mtu': '1500',
'qdisc': 'pfifo_fast',
'qlen': '1000',
'state': 'DOWN'},
'eth2': {
'flags': ['BROADCAST', 'MULTICAST', 'UP', 'LOWER_UP'],
'ipv4': set([(3232278036, 22)]),
'ipv6': set([(338288524927261089654166966972723684525L,
64)]),
'mac': set(['00:0e:0c:82:e4:ad']),
'mtu': '1500',
'qdisc': 'pfifo_fast',
'qlen': '1000',
'state': 'UP'},
'lo': {
'flags': ['LOOPBACK', 'UP', 'LOWER_UP'],
'ipv4': set([(2130706433, 8)]),
'ipv6': set([(1L, 128)]),
'mtu': '16436',
'qdisc': 'noqueue',
'state': 'UNKNOWN'},
'virbr0': {
'flags': ['NO-CARRIER',
'BROADCAST',
'MULTICAST',
'UP'],
'ipv4': set([(3232266753, 24)]),
'mac': set(['c2:d8:1e:32:a0:a8']),
'mtu': '1500',
'qdisc': 'noqueue',
'state': 'DOWN'},
'wlan0': {
'flags': ['BROADCAST', 'MULTICAST', 'UP', 'LOWER_UP'],
'ipv4': set([(3232281110, 24)]),
'ipv6': set([(336294682933583715844817672032642980028L,
64),
(336294682933583715849299718871641054002L,
64),
(338288524927261089654173382623063496892L,
64)]),
'mac': set(['00:24:d7:04:d8:bc']),
'mtu': '1500',
'qdisc': 'mq',
'qlen': '1000',
'state': 'UP'},
}
# build all possible outputs
lines = []
for selname, selector in selectors.items():
for pfx in prefixes:
print ("Distil CFEngine output with prefix '%s' and option '%s' ..."
% (pfx, selname))
lines.append(create_cfengine_output_lines(data, selector, pfx))
assert len(lines) == 4
# for n, ls in enumerate(lines):
# print ("=== Line set #%d ===" % n)
# print '\n'.join(sorted(ls))
#=== Line set #0 ===
assert '+ip_ipv4_10_128_160_20' in lines[0]
assert '+ip_ipv4_10_129_160_20' in lines[0]
assert '+ip_ipv4_10_1_160_20' in lines[0]
assert '+ip_ipv4_127_0_0_1' in lines[0]
assert '+ip_ipv4_192_168_122_1' in lines[0]
assert '+ip_ipv4_192_168_160_1' in lines[0]
assert '+ip_ipv4_192_168_160_20' in lines[0]
assert '+ip_ipv4_192_168_166_20' in lines[0]
assert '+ip_ipv4_192_168_178_22' in lines[0]
assert '+ip_ipv4_net_10_128_0_0' in lines[0]
assert '+ip_ipv4_net_10_129_0_0' in lines[0]
assert '+ip_ipv4_net_10_1_0_0' in lines[0]
assert '+ip_ipv4_net_127_0_0_0' in lines[0]
assert '+ip_ipv4_net_192_168_122_0' in lines[0]
assert '+ip_ipv4_net_192_168_160_0' in lines[0]
assert '+ip_ipv4_net_192_168_164_0' in lines[0]
assert '+ip_ipv4_net_192_168_178_0' in lines[0]
assert '+ip_ipv6_0000_0000_0000_0000_0000_0000_0000_0001' in lines[0]
assert '+ip_ipv6_fd00_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[0]
assert '+ip_ipv6_fd00_0000_0000_0000_4058_45da_6729_5b32' in lines[0]
assert '+ip_ipv6_fe80_0000_0000_0000_020e_0cff_fe82_e4ad' in lines[0]
assert '+ip_ipv6_fe80_0000_0000_0000_0211_43ff_fefd_40fe' in lines[0]
assert '+ip_ipv6_fe80_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[0]
assert '+ip_ipv6_net_0000_0000_0000_0000_0000_0000_0000_0001' in lines[0]
assert '+ip_ipv6_net_fd00_0000_0000_0000_0000_0000_0000_0000' in lines[0]
assert '+ip_ipv6_net_fe80_0000_0000_0000_0000_0000_0000_0000' in lines[0]
assert '+ip_mac_00_0e_0c_82_e4_ad' in lines[0]
assert '+ip_mac_00_11_43_fd_40_fe' in lines[0]
assert '+ip_mac_00_24_d7_04_d8_bc' in lines[0]
assert '+ip_mac_00_26_2d_f6_0a_3c' in lines[0]
assert '+ip_mac_c2_d8_1e_32_a0_a8' in lines[0]
assert '+ip_net_iface_eth0' in lines[0]
assert '+ip_net_iface_eth0_broadcast' in lines[0]
assert '+ip_net_iface_eth0_lower_up' in lines[0]
assert '+ip_net_iface_eth0_multicast' in lines[0]
assert '+ip_net_iface_eth0_up' in lines[0]
assert '+ip_net_iface_eth0_vlan617' in lines[0]
assert '+ip_net_iface_eth0_vlan617_broadcast' in lines[0]
assert '+ip_net_iface_eth0_vlan617_lower_up' in lines[0]
assert '+ip_net_iface_eth0_vlan617_multicast' in lines[0]
assert '+ip_net_iface_eth0_vlan617_up' in lines[0]
assert '+ip_net_iface_eth0_vlan618' in lines[0]
assert '+ip_net_iface_eth0_vlan618_broadcast' in lines[0]
assert '+ip_net_iface_eth0_vlan618_lower_up' in lines[0]
assert '+ip_net_iface_eth0_vlan618_multicast' in lines[0]
assert '+ip_net_iface_eth0_vlan618_up' in lines[0]
assert '+ip_net_iface_eth1' in lines[0]
assert '+ip_net_iface_eth1_broadcast' in lines[0]
assert '+ip_net_iface_eth1_multicast' in lines[0]
assert '+ip_net_iface_eth1_no_carrier' in lines[0]
assert '+ip_net_iface_eth1_up' in lines[0]
assert '+ip_net_iface_eth2' in lines[0]
assert '+ip_net_iface_eth2_broadcast' in lines[0]
assert '+ip_net_iface_eth2_lower_up' in lines[0]
assert '+ip_net_iface_eth2_multicast' in lines[0]
assert '+ip_net_iface_eth2_up' in lines[0]
assert '+ip_net_iface_lo' in lines[0]
assert '+ip_net_iface_lo_loopback' in lines[0]
assert '+ip_net_iface_lo_lower_up' in lines[0]
assert '+ip_net_iface_lo_up' in lines[0]
assert '+ip_net_iface_virbr0' in lines[0]
assert '+ip_net_iface_virbr0_broadcast' in lines[0]
assert '+ip_net_iface_virbr0_multicast' in lines[0]
assert '+ip_net_iface_virbr0_no_carrier' in lines[0]
assert '+ip_net_iface_virbr0_up' in lines[0]
assert '+ip_net_iface_wlan0' in lines[0]
assert '+ip_net_iface_wlan0_broadcast' in lines[0]
assert '+ip_net_iface_wlan0_lower_up' in lines[0]
assert '+ip_net_iface_wlan0_multicast' in lines[0]
assert '+ip_net_iface_wlan0_up' in lines[0]
assert '=ip_net_iface[eth0][mtu]=1500' in lines[0]
assert '=ip_net_iface[eth0][qdisc]=pfifo_fast' in lines[0]
assert '=ip_net_iface[eth0][qlen]=1000' in lines[0]
assert '=ip_net_iface[eth0][state]=UP' in lines[0]
assert '=ip_net_iface[eth0_vlan617][mtu]=1500' in lines[0]
assert '=ip_net_iface[eth0_vlan617][qdisc]=noqueue' in lines[0]
assert '=ip_net_iface[eth0_vlan617][state]=UP' in lines[0]
assert '=ip_net_iface[eth0_vlan618][mtu]=1500' in lines[0]
assert '=ip_net_iface[eth0_vlan618][qdisc]=noqueue' in lines[0]
assert '=ip_net_iface[eth0_vlan618][state]=UP' in lines[0]
assert '=ip_net_iface[eth1][mtu]=1500' in lines[0]
assert '=ip_net_iface[eth1][qdisc]=pfifo_fast' in lines[0]
assert '=ip_net_iface[eth1][qlen]=1000' in lines[0]
assert '=ip_net_iface[eth1][state]=DOWN' in lines[0]
assert '=ip_net_iface[eth2][mtu]=1500' in lines[0]
assert '=ip_net_iface[eth2][qdisc]=pfifo_fast' in lines[0]
assert '=ip_net_iface[eth2][qlen]=1000' in lines[0]
assert '=ip_net_iface[eth2][state]=UP' in lines[0]
assert '=ip_net_iface[lo][mtu]=16436' in lines[0]
assert '=ip_net_iface[lo][qdisc]=noqueue' in lines[0]
assert '=ip_net_iface[lo][state]=UNKNOWN' in lines[0]
assert '=ip_net_iface[virbr0][mtu]=1500' in lines[0]
assert '=ip_net_iface[virbr0][qdisc]=noqueue' in lines[0]
assert '=ip_net_iface[virbr0][state]=DOWN' in lines[0]
assert '=ip_net_iface[wlan0][mtu]=1500' in lines[0]
assert '=ip_net_iface[wlan0][qdisc]=mq' in lines[0]
assert '=ip_net_iface[wlan0][qlen]=1000' in lines[0]
assert '=ip_net_iface[wlan0][state]=UP' in lines[0]
assert '@ip_net_iface[eth0][ipv4]={"192.168.160.1","192.168.160.20","10.1.160.20"}' in lines[0]
assert '@ip_net_iface[eth0][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[0]
assert '@ip_net_iface[eth0_vlan617][ipv4]={"10.128.160.20"}' in lines[0]
assert '@ip_net_iface[eth0_vlan617][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[0]
assert '@ip_net_iface[eth0_vlan618][ipv4]={"10.129.160.20"}' in lines[0]
assert '@ip_net_iface[eth0_vlan618][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[0]
assert '@ip_net_iface[eth2][ipv4]={"192.168.166.20"}' in lines[0]
assert '@ip_net_iface[eth2][ipv6]={"fe80:0000:0000:0000:020e:0cff:fe82:e4ad"}' in lines[0]
assert '@ip_net_iface[lo][ipv4]={"127.0.0.1"}' in lines[0]
assert '@ip_net_iface[lo][ipv6]={"0000:0000:0000:0000:0000:0000:0000:0001"}' in lines[0]
assert '@ip_net_iface[virbr0][ipv4]={"192.168.122.1"}' in lines[0]
assert '@ip_net_iface[wlan0][ipv4]={"192.168.178.22"}' in lines[0]
assert '@ip_net_iface[wlan0][ipv6]={"fd00:0000:0000:0000:4058:45da:6729:5b32","fe80:0000:0000:0000:0224:d7ff:fe04:d8bc","fd00:0000:0000:0000:0224:d7ff:fe04:d8bc"}' in lines[0]
# === Line set #1 ===
assert '+ipv4_10_128_160_20' in lines[1]
assert '+ipv4_10_129_160_20' in lines[1]
assert '+ipv4_10_1_160_20' in lines[1]
assert '+ipv4_127_0_0_1' in lines[1]
assert '+ipv4_192_168_122_1' in lines[1]
assert '+ipv4_192_168_160_1' in lines[1]
assert '+ipv4_192_168_160_20' in lines[1]
assert '+ipv4_192_168_166_20' in lines[1]
assert '+ipv4_192_168_178_22' in lines[1]
assert '+ipv4_net_10_128_0_0' in lines[1]
assert '+ipv4_net_10_129_0_0' in lines[1]
assert '+ipv4_net_10_1_0_0' in lines[1]
assert '+ipv4_net_127_0_0_0' in lines[1]
assert '+ipv4_net_192_168_122_0' in lines[1]
assert '+ipv4_net_192_168_160_0' in lines[1]
assert '+ipv4_net_192_168_164_0' in lines[1]
assert '+ipv4_net_192_168_178_0' in lines[1]
assert '+ipv6_0000_0000_0000_0000_0000_0000_0000_0001' in lines[1]
assert '+ipv6_fd00_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[1]
assert '+ipv6_fd00_0000_0000_0000_4058_45da_6729_5b32' in lines[1]
assert '+ipv6_fe80_0000_0000_0000_020e_0cff_fe82_e4ad' in lines[1]
assert '+ipv6_fe80_0000_0000_0000_0211_43ff_fefd_40fe' in lines[1]
assert '+ipv6_fe80_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[1]
assert '+ipv6_net_0000_0000_0000_0000_0000_0000_0000_0001' in lines[1]
assert '+ipv6_net_fd00_0000_0000_0000_0000_0000_0000_0000' in lines[1]
assert '+ipv6_net_fe80_0000_0000_0000_0000_0000_0000_0000' in lines[1]
assert '+mac_00_0e_0c_82_e4_ad' in lines[1]
assert '+mac_00_11_43_fd_40_fe' in lines[1]
assert '+mac_00_24_d7_04_d8_bc' in lines[1]
assert '+mac_00_26_2d_f6_0a_3c' in lines[1]
assert '+mac_c2_d8_1e_32_a0_a8' in lines[1]
assert '+net_iface_eth0' in lines[1]
assert '+net_iface_eth0_broadcast' in lines[1]
assert '+net_iface_eth0_lower_up' in lines[1]
assert '+net_iface_eth0_multicast' in lines[1]
assert '+net_iface_eth0_up' in lines[1]
assert '+net_iface_eth0_vlan617' in lines[1]
assert '+net_iface_eth0_vlan617_broadcast' in lines[1]
assert '+net_iface_eth0_vlan617_lower_up' in lines[1]
assert '+net_iface_eth0_vlan617_multicast' in lines[1]
assert '+net_iface_eth0_vlan617_up' in lines[1]
assert '+net_iface_eth0_vlan618' in lines[1]
assert '+net_iface_eth0_vlan618_broadcast' in lines[1]
assert '+net_iface_eth0_vlan618_lower_up' in lines[1]
assert '+net_iface_eth0_vlan618_multicast' in lines[1]
assert '+net_iface_eth0_vlan618_up' in lines[1]
assert '+net_iface_eth1' in lines[1]
assert '+net_iface_eth1_broadcast' in lines[1]
assert '+net_iface_eth1_multicast' in lines[1]
assert '+net_iface_eth1_no_carrier' in lines[1]
assert '+net_iface_eth1_up' in lines[1]
assert '+net_iface_eth2' in lines[1]
assert '+net_iface_eth2_broadcast' in lines[1]
assert '+net_iface_eth2_lower_up' in lines[1]
assert '+net_iface_eth2_multicast' in lines[1]
assert '+net_iface_eth2_up' in lines[1]
assert '+net_iface_lo' in lines[1]
assert '+net_iface_lo_loopback' in lines[1]
assert '+net_iface_lo_lower_up' in lines[1]
assert '+net_iface_lo_up' in lines[1]
assert '+net_iface_virbr0' in lines[1]
assert '+net_iface_virbr0_broadcast' in lines[1]
assert '+net_iface_virbr0_multicast' in lines[1]
assert '+net_iface_virbr0_no_carrier' in lines[1]
assert '+net_iface_virbr0_up' in lines[1]
assert '+net_iface_wlan0' in lines[1]
assert '+net_iface_wlan0_broadcast' in lines[1]
assert '+net_iface_wlan0_lower_up' in lines[1]
assert '+net_iface_wlan0_multicast' in lines[1]
assert '+net_iface_wlan0_up' in lines[1]
assert '=net_iface[eth0][mtu]=1500' in lines[1]
assert '=net_iface[eth0][qdisc]=pfifo_fast' in lines[1]
assert '=net_iface[eth0][qlen]=1000' in lines[1]
assert '=net_iface[eth0][state]=UP' in lines[1]
assert '=net_iface[eth0_vlan617][mtu]=1500' in lines[1]
assert '=net_iface[eth0_vlan617][qdisc]=noqueue' in lines[1]
assert '=net_iface[eth0_vlan617][state]=UP' in lines[1]
assert '=net_iface[eth0_vlan618][mtu]=1500' in lines[1]
assert '=net_iface[eth0_vlan618][qdisc]=noqueue' in lines[1]
assert '=net_iface[eth0_vlan618][state]=UP' in lines[1]
assert '=net_iface[eth1][mtu]=1500' in lines[1]
assert '=net_iface[eth1][qdisc]=pfifo_fast' in lines[1]
assert '=net_iface[eth1][qlen]=1000' in lines[1]
assert '=net_iface[eth1][state]=DOWN' in lines[1]
assert '=net_iface[eth2][mtu]=1500' in lines[1]
assert '=net_iface[eth2][qdisc]=pfifo_fast' in lines[1]
assert '=net_iface[eth2][qlen]=1000' in lines[1]
assert '=net_iface[eth2][state]=UP' in lines[1]
assert '=net_iface[lo][mtu]=16436' in lines[1]
assert '=net_iface[lo][qdisc]=noqueue' in lines[1]
assert '=net_iface[lo][state]=UNKNOWN' in lines[1]
assert '=net_iface[virbr0][mtu]=1500' in lines[1]
assert '=net_iface[virbr0][qdisc]=noqueue' in lines[1]
assert '=net_iface[virbr0][state]=DOWN' in lines[1]
assert '=net_iface[wlan0][mtu]=1500' in lines[1]
assert '=net_iface[wlan0][qdisc]=mq' in lines[1]
assert '=net_iface[wlan0][qlen]=1000' in lines[1]
assert '=net_iface[wlan0][state]=UP' in lines[1]
assert '@net_iface[eth0][ipv4]={"192.168.160.1","192.168.160.20","10.1.160.20"}' in lines[1]
assert '@net_iface[eth0][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[1]
assert '@net_iface[eth0_vlan617][ipv4]={"10.128.160.20"}' in lines[1]
assert '@net_iface[eth0_vlan617][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[1]
assert '@net_iface[eth0_vlan618][ipv4]={"10.129.160.20"}' in lines[1]
assert '@net_iface[eth0_vlan618][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[1]
assert '@net_iface[eth2][ipv4]={"192.168.166.20"}' in lines[1]
assert '@net_iface[eth2][ipv6]={"fe80:0000:0000:0000:020e:0cff:fe82:e4ad"}' in lines[1]
assert '@net_iface[lo][ipv4]={"127.0.0.1"}' in lines[1]
assert '@net_iface[lo][ipv6]={"0000:0000:0000:0000:0000:0000:0000:0001"}' in lines[1]
assert '@net_iface[virbr0][ipv4]={"192.168.122.1"}' in lines[1]
assert '@net_iface[wlan0][ipv4]={"192.168.178.22"}' in lines[1]
assert '@net_iface[wlan0][ipv6]={"fd00:0000:0000:0000:4058:45da:6729:5b32","fe80:0000:0000:0000:0224:d7ff:fe04:d8bc","fd00:0000:0000:0000:0224:d7ff:fe04:d8bc"}' in lines[1]
# === Line set #2 ===
assert '+ip_ipv4_10_128_160_20' in lines[2]
assert '+ip_ipv4_10_129_160_20' in lines[2]
assert '+ip_ipv4_10_1_160_20' in lines[2]
assert '+ip_ipv4_192_168_160_1' in lines[2]
assert '+ip_ipv4_192_168_160_20' in lines[2]
assert '+ip_ipv4_192_168_166_20' in lines[2]
assert '+ip_ipv4_192_168_178_22' in lines[2]
assert '+ip_ipv4_net_10_128_0_0' in lines[2]
assert '+ip_ipv4_net_10_129_0_0' in lines[2]
assert '+ip_ipv4_net_10_1_0_0' in lines[2]
assert '+ip_ipv4_net_192_168_160_0' in lines[2]
assert '+ip_ipv4_net_192_168_164_0' in lines[2]
assert '+ip_ipv4_net_192_168_178_0' in lines[2]
assert '+ip_ipv6_fd00_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[2]
assert '+ip_ipv6_fd00_0000_0000_0000_4058_45da_6729_5b32' in lines[2]
assert '+ip_ipv6_fe80_0000_0000_0000_020e_0cff_fe82_e4ad' in lines[2]
assert '+ip_ipv6_fe80_0000_0000_0000_0211_43ff_fefd_40fe' in lines[2]
assert '+ip_ipv6_fe80_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[2]
assert '+ip_ipv6_net_fd00_0000_0000_0000_0000_0000_0000_0000' in lines[2]
assert '+ip_ipv6_net_fe80_0000_0000_0000_0000_0000_0000_0000' in lines[2]
assert '+ip_mac_00_0e_0c_82_e4_ad' in lines[2]
assert '+ip_mac_00_11_43_fd_40_fe' in lines[2]
assert '+ip_mac_00_24_d7_04_d8_bc' in lines[2]
assert '+ip_net_iface_eth0' in lines[2]
assert '+ip_net_iface_eth0_broadcast' in lines[2]
assert '+ip_net_iface_eth0_lower_up' in lines[2]
assert '+ip_net_iface_eth0_multicast' in lines[2]
assert '+ip_net_iface_eth0_up' in lines[2]
assert '+ip_net_iface_eth0_vlan617' in lines[2]
assert '+ip_net_iface_eth0_vlan617_broadcast' in lines[2]
assert '+ip_net_iface_eth0_vlan617_lower_up' in lines[2]
assert '+ip_net_iface_eth0_vlan617_multicast' in lines[2]
assert '+ip_net_iface_eth0_vlan617_up' in lines[2]
assert '+ip_net_iface_eth0_vlan618' in lines[2]
assert '+ip_net_iface_eth0_vlan618_broadcast' in lines[2]
assert '+ip_net_iface_eth0_vlan618_lower_up' in lines[2]
assert '+ip_net_iface_eth0_vlan618_multicast' in lines[2]
assert '+ip_net_iface_eth0_vlan618_up' in lines[2]
assert '+ip_net_iface_eth2' in lines[2]
assert '+ip_net_iface_eth2_broadcast' in lines[2]
assert '+ip_net_iface_eth2_lower_up' in lines[2]
assert '+ip_net_iface_eth2_multicast' in lines[2]
assert '+ip_net_iface_eth2_up' in lines[2]
assert '+ip_net_iface_wlan0' in lines[2]
assert '+ip_net_iface_wlan0_broadcast' in lines[2]
assert '+ip_net_iface_wlan0_lower_up' in lines[2]
assert '+ip_net_iface_wlan0_multicast' in lines[2]
assert '+ip_net_iface_wlan0_up' in lines[2]
assert '=ip_net_iface[eth0][mtu]=1500' in lines[2]
assert '=ip_net_iface[eth0][qdisc]=pfifo_fast' in lines[2]
assert '=ip_net_iface[eth0][qlen]=1000' in lines[2]
assert '=ip_net_iface[eth0][state]=UP' in lines[2]
assert '=ip_net_iface[eth0_vlan617][mtu]=1500' in lines[2]
assert '=ip_net_iface[eth0_vlan617][qdisc]=noqueue' in lines[2]
assert '=ip_net_iface[eth0_vlan617][state]=UP' in lines[2]
assert '=ip_net_iface[eth0_vlan618][mtu]=1500' in lines[2]
assert '=ip_net_iface[eth0_vlan618][qdisc]=noqueue' in lines[2]
assert '=ip_net_iface[eth0_vlan618][state]=UP' in lines[2]
assert '=ip_net_iface[eth2][mtu]=1500' in lines[2]
assert '=ip_net_iface[eth2][qdisc]=pfifo_fast' in lines[2]
assert '=ip_net_iface[eth2][qlen]=1000' in lines[2]
assert '=ip_net_iface[eth2][state]=UP' in lines[2]
assert '=ip_net_iface[wlan0][mtu]=1500' in lines[2]
assert '=ip_net_iface[wlan0][qdisc]=mq' in lines[2]
assert '=ip_net_iface[wlan0][qlen]=1000' in lines[2]
assert '=ip_net_iface[wlan0][state]=UP' in lines[2]
assert '@ip_net_iface[eth0][ipv4]={"192.168.160.1","192.168.160.20","10.1.160.20"}' in lines[2]
assert '@ip_net_iface[eth0][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[2]
assert '@ip_net_iface[eth0_vlan617][ipv4]={"10.128.160.20"}' in lines[2]
assert '@ip_net_iface[eth0_vlan617][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[2]
assert '@ip_net_iface[eth0_vlan618][ipv4]={"10.129.160.20"}' in lines[2]
assert '@ip_net_iface[eth0_vlan618][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[2]
assert '@ip_net_iface[eth2][ipv4]={"192.168.166.20"}' in lines[2]
assert '@ip_net_iface[eth2][ipv6]={"fe80:0000:0000:0000:020e:0cff:fe82:e4ad"}' in lines[2]
assert '@ip_net_iface[wlan0][ipv4]={"192.168.178.22"}' in lines[2]
assert '@ip_net_iface[wlan0][ipv6]={"fd00:0000:0000:0000:4058:45da:6729:5b32","fe80:0000:0000:0000:0224:d7ff:fe04:d8bc","fd00:0000:0000:0000:0224:d7ff:fe04:d8bc"}' in lines[2]
# === Line set #3 ===
assert '+ipv4_10_128_160_20' in lines[3]
assert '+ipv4_10_129_160_20' in lines[3]
assert '+ipv4_10_1_160_20' in lines[3]
assert '+ipv4_192_168_160_1' in lines[3]
assert '+ipv4_192_168_160_20' in lines[3]
assert '+ipv4_192_168_166_20' in lines[3]
assert '+ipv4_192_168_178_22' in lines[3]
assert '+ipv4_net_10_128_0_0' in lines[3]
assert '+ipv4_net_10_129_0_0' in lines[3]
assert '+ipv4_net_10_1_0_0' in lines[3]
assert '+ipv4_net_192_168_160_0' in lines[3]
assert '+ipv4_net_192_168_164_0' in lines[3]
assert '+ipv4_net_192_168_178_0' in lines[3]
assert '+ipv6_fd00_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[3]
assert '+ipv6_fd00_0000_0000_0000_4058_45da_6729_5b32' in lines[3]
assert '+ipv6_fe80_0000_0000_0000_020e_0cff_fe82_e4ad' in lines[3]
assert '+ipv6_fe80_0000_0000_0000_0211_43ff_fefd_40fe' in lines[3]
assert '+ipv6_fe80_0000_0000_0000_0224_d7ff_fe04_d8bc' in lines[3]
assert '+ipv6_net_fd00_0000_0000_0000_0000_0000_0000_0000' in lines[3]
assert '+ipv6_net_fe80_0000_0000_0000_0000_0000_0000_0000' in lines[3]
assert '+mac_00_0e_0c_82_e4_ad' in lines[3]
assert '+mac_00_11_43_fd_40_fe' in lines[3]
assert '+mac_00_24_d7_04_d8_bc' in lines[3]
assert '+net_iface_eth0' in lines[3]
assert '+net_iface_eth0_broadcast' in lines[3]
assert '+net_iface_eth0_lower_up' in lines[3]
assert '+net_iface_eth0_multicast' in lines[3]
assert '+net_iface_eth0_up' in lines[3]
assert '+net_iface_eth0_vlan617' in lines[3]
assert '+net_iface_eth0_vlan617_broadcast' in lines[3]
assert '+net_iface_eth0_vlan617_lower_up' in lines[3]
assert '+net_iface_eth0_vlan617_multicast' in lines[3]
assert '+net_iface_eth0_vlan617_up' in lines[3]
assert '+net_iface_eth0_vlan618' in lines[3]
assert '+net_iface_eth0_vlan618_broadcast' in lines[3]
assert '+net_iface_eth0_vlan618_lower_up' in lines[3]
assert '+net_iface_eth0_vlan618_multicast' in lines[3]
assert '+net_iface_eth0_vlan618_up' in lines[3]
assert '+net_iface_eth2' in lines[3]
assert '+net_iface_eth2_broadcast' in lines[3]
assert '+net_iface_eth2_lower_up' in lines[3]
assert '+net_iface_eth2_multicast' in lines[3]
assert '+net_iface_eth2_up' in lines[3]
assert '+net_iface_wlan0' in lines[3]
assert '+net_iface_wlan0_broadcast' in lines[3]
assert '+net_iface_wlan0_lower_up' in lines[3]
assert '+net_iface_wlan0_multicast' in lines[3]
assert '+net_iface_wlan0_up' in lines[3]
assert '=net_iface[eth0][mtu]=1500' in lines[3]
assert '=net_iface[eth0][qdisc]=pfifo_fast' in lines[3]
assert '=net_iface[eth0][qlen]=1000' in lines[3]
assert '=net_iface[eth0][state]=UP' in lines[3]
assert '=net_iface[eth0_vlan617][mtu]=1500' in lines[3]
assert '=net_iface[eth0_vlan617][qdisc]=noqueue' in lines[3]
assert '=net_iface[eth0_vlan617][state]=UP' in lines[3]
assert '=net_iface[eth0_vlan618][mtu]=1500' in lines[3]
assert '=net_iface[eth0_vlan618][qdisc]=noqueue' in lines[3]
assert '=net_iface[eth0_vlan618][state]=UP' in lines[3]
assert '=net_iface[eth2][mtu]=1500' in lines[3]
assert '=net_iface[eth2][qdisc]=pfifo_fast' in lines[3]
assert '=net_iface[eth2][qlen]=1000' in lines[3]
assert '=net_iface[eth2][state]=UP' in lines[3]
assert '=net_iface[wlan0][mtu]=1500' in lines[3]
assert '=net_iface[wlan0][qdisc]=mq' in lines[3]
assert '=net_iface[wlan0][qlen]=1000' in lines[3]
assert '=net_iface[wlan0][state]=UP' in lines[3]
assert '@net_iface[eth0][ipv4]={"192.168.160.1","192.168.160.20","10.1.160.20"}' in lines[3]
assert '@net_iface[eth0][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[3]
assert '@net_iface[eth0_vlan617][ipv4]={"10.128.160.20"}' in lines[3]
assert '@net_iface[eth0_vlan617][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[3]
assert '@net_iface[eth0_vlan618][ipv4]={"10.129.160.20"}' in lines[3]
assert '@net_iface[eth0_vlan618][ipv6]={"fe80:0000:0000:0000:0211:43ff:fefd:40fe"}' in lines[3]
assert '@net_iface[eth2][ipv4]={"192.168.166.20"}' in lines[3]
assert '@net_iface[eth2][ipv6]={"fe80:0000:0000:0000:020e:0cff:fe82:e4ad"}' in lines[3]
assert '@net_iface[wlan0][ipv4]={"192.168.178.22"}' in lines[3]
assert '@net_iface[wlan0][ipv6]={"fd00:0000:0000:0000:4058:45da:6729:5b32","fe80:0000:0000:0000:0224:d7ff:fe04:d8bc","fd00:0000:0000:0000:0224:d7ff:fe04:d8bc"}' in lines[3]
print ("All OK.")
# Sample CFEngine usage of the `ips` module.
#
# You should get something like the following:
#
# $ cf-agent -I -f ./TEST.cf -K
# 2014-01-31T16:43:01+0100 info: Executing 'no timeout' ... 'ips'
# 2014-01-31T16:43:01+0100 info: Completed execution of 'ips'
# 2014-01-31T16:43:01+0100 notice: R: Running a test
# 2014-01-31T16:43:01+0100 notice: R: Interface `lo` NOT detected, as it's not UP
# 2014-01-31T16:43:01+0100 notice: R: Interface `wlan0` detected UP
# 2014-01-31T16:43:01+0100 notice: R: MAC address detected
# 2014-01-31T16:43:01+0100 notice: R: MTU on wlan0: 1500
# 2014-01-31T16:43:01+0100 notice: R: IPv4 address on wlan0: 192.168.178.22
# 2014-01-31T16:43:01+0100 notice: R: IPv6 address on wlan0: 192.168.178.22
#
body common control
{
inputs => { };
bundlesequence => { "test" };
}
bundle agent test
{
commands:
"ips" module => "true";
reports:
cfengine::
"Running a test";
!ip_net_iface_lo::
"Interface `lo` NOT detected, as it's not UP";
ip_net_iface_wlan0_up::
"Interface `wlan0` detected UP";
ip_mac_00_24_d7_04_d8_bc::
"MAC address detected";
ip_net_iface_wlan0::
"MTU on wlan0: $(ips.ip_net_iface[wlan0][mtu])";
"IPv4 address on wlan0: $(ips.ip_net_iface[wlan0][ipv4])";
"IPv6 address on wlan0: $(ips.ip_net_iface[wlan0][ipv4])";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment