ifstate 1.8.2__tar.gz → 1.8.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ifstate-1.8.2 → ifstate-1.8.4}/PKG-INFO +1 -1
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate/ifstate.py +2 -2
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate.egg-info/PKG-INFO +1 -1
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate.egg-info/SOURCES.txt +1 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/__init__.py +19 -7
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/link/__init__.py +1 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/link/base.py +15 -9
- ifstate-1.8.4/libifstate/link/tun.py +23 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/log.py +42 -18
- {ifstate-1.8.2 → ifstate-1.8.4}/schema/ifstate.conf.schema.json +81 -3
- {ifstate-1.8.2 → ifstate-1.8.4}/LICENSE +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/README.md +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate/shell.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate.egg-info/dependency_links.txt +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate.egg-info/entry_points.txt +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate.egg-info/requires.txt +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/ifstate.egg-info/top_level.txt +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/address/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/bpf/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/bpf/ctypes.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/bpf/map.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/brport/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/exception.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/link/physical.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/link/veth.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/neighbour/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/parser/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/parser/base.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/parser/yaml.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/routing/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/sysctl/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/tc/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/util.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/wireguard/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/libifstate/xdp/__init__.py +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/setup.cfg +0 -0
- {ifstate-1.8.2 → ifstate-1.8.4}/setup.py +0 -0
@@ -86,7 +86,7 @@ def main():
|
|
86
86
|
shell()
|
87
87
|
exit(0)
|
88
88
|
|
89
|
-
ifslog = IfStateLogging(lvl)
|
89
|
+
ifslog = IfStateLogging(lvl, action=args.action)
|
90
90
|
ifs = IfState()
|
91
91
|
|
92
92
|
if args.action in [Actions.SHOW, Actions.SHOWALL]:
|
@@ -137,7 +137,7 @@ def main():
|
|
137
137
|
pass
|
138
138
|
elif args.action == Actions.VRRP_FIFO:
|
139
139
|
status_pattern = re.compile(
|
140
|
-
r'(group|instance) "([^"]+)" (unknown|fault|backup|master)
|
140
|
+
r'(group|instance) "([^"]+)" (unknown|fault|backup|master)( \d+)?$', re.IGNORECASE)
|
141
141
|
|
142
142
|
with open(args.fifo) as fifo:
|
143
143
|
for line in fifo:
|
@@ -43,7 +43,7 @@ import json
|
|
43
43
|
import errno
|
44
44
|
import logging
|
45
45
|
|
46
|
-
__version__ = "1.8.
|
46
|
+
__version__ = "1.8.4"
|
47
47
|
|
48
48
|
|
49
49
|
class IfState():
|
@@ -262,11 +262,21 @@ class IfState():
|
|
262
262
|
|
263
263
|
def _apply(self, do_apply, vrrp_type, vrrp_name, vrrp_state):
|
264
264
|
vrrp_ignore = []
|
265
|
-
|
265
|
+
vrrp_disable = []
|
266
266
|
|
267
267
|
by_vrrp = not None in [
|
268
268
|
vrrp_type, vrrp_name, vrrp_state]
|
269
269
|
|
270
|
+
if by_vrrp:
|
271
|
+
logger.info("vrrp state change: {} {} => {}".format(vrrp_type, vrrp_name, vrrp_state))
|
272
|
+
|
273
|
+
# ifstate schema requires lower case keywords
|
274
|
+
vrrp_type = vrrp_type.lower()
|
275
|
+
vrrp_state = vrrp_state.lower()
|
276
|
+
|
277
|
+
# check which links to remove or ignore:
|
278
|
+
# remove: vrrp type & name matches, but vrrp state not
|
279
|
+
# ignore: vrrp type & name does not match
|
270
280
|
for ifname, link in self.links.items():
|
271
281
|
if ifname in self.vrrp['links']:
|
272
282
|
if not by_vrrp:
|
@@ -275,9 +285,11 @@ class IfState():
|
|
275
285
|
if not link.match_vrrp_select(vrrp_type, vrrp_name):
|
276
286
|
vrrp_ignore.append(ifname)
|
277
287
|
elif not vrrp_name in self.vrrp[vrrp_type] or not vrrp_state in self.vrrp[vrrp_type][vrrp_name] or not ifname in self.vrrp[vrrp_type][vrrp_name][vrrp_state]:
|
278
|
-
|
288
|
+
vrrp_disable.append(ifname)
|
279
289
|
elif by_vrrp:
|
280
290
|
vrrp_ignore.append(ifname)
|
291
|
+
logger.debug("vrrp links to be disabled: {}".format(", ".join(vrrp_disable)))
|
292
|
+
logger.debug("vrrp links to be ignored: {}".format(", ".join(vrrp_ignore)))
|
281
293
|
|
282
294
|
self.ipaddr_ignore = set()
|
283
295
|
for ip in self.ignore.get('ipaddr', []):
|
@@ -299,10 +311,10 @@ class IfState():
|
|
299
311
|
if stage == 0:
|
300
312
|
logger.info("\nconfiguring interface links")
|
301
313
|
|
302
|
-
for ifname in
|
303
|
-
logger.debug('to be
|
314
|
+
for ifname in vrrp_disable:
|
315
|
+
logger.debug('to be disabled due to vrrp constraint',
|
304
316
|
extra={'iface': ifname})
|
305
|
-
|
317
|
+
self.links[ifname].settings['state'] = 'down'
|
306
318
|
else:
|
307
319
|
logger.info("\nconfiguring interface links (stage 2)")
|
308
320
|
|
@@ -325,7 +337,7 @@ class IfState():
|
|
325
337
|
applied.append(name)
|
326
338
|
else:
|
327
339
|
deps = link.depends()
|
328
|
-
if all(x in applied for x in deps):
|
340
|
+
if all(x in applied+vrrp_ignore for x in deps):
|
329
341
|
excpts = link.apply(do_apply, self.sysctl)
|
330
342
|
if excpts.has_errno(errno.EEXIST):
|
331
343
|
retry = True
|
@@ -66,6 +66,11 @@ class Link(ABC):
|
|
66
66
|
1: "bandwidth",
|
67
67
|
2: "count",
|
68
68
|
},
|
69
|
+
# === tuntap ===
|
70
|
+
'tun_type': {
|
71
|
+
1: 'tun',
|
72
|
+
2: 'tap',
|
73
|
+
},
|
69
74
|
# === vlan ===
|
70
75
|
'vlan_protocol': {
|
71
76
|
0x88a8: '802.1ad',
|
@@ -108,7 +113,7 @@ class Link(ABC):
|
|
108
113
|
'ip6gre_link', 'vxlan_link', 'xfrm_link']
|
109
114
|
self.idx = None
|
110
115
|
|
111
|
-
if 'address' in self.settings:
|
116
|
+
if 'address' in self.settings and self.settings['kind'] == 'physical':
|
112
117
|
self.settings['address'] = self.settings['address'].lower()
|
113
118
|
self.idx = next(iter(ipr.link_lookup(
|
114
119
|
address=self.settings['address'])), None)
|
@@ -369,7 +374,7 @@ class Link(ABC):
|
|
369
374
|
raise
|
370
375
|
excpts.add('del', err)
|
371
376
|
self.idx = None
|
372
|
-
self.create(do_apply,
|
377
|
+
self.create(do_apply, sysctl, excpts, "replace")
|
373
378
|
|
374
379
|
def update(self, do_apply, sysctl, excpts):
|
375
380
|
logger.debug('checking link', extra={'iface': self.settings['ifname']})
|
@@ -505,13 +510,14 @@ class Link(ABC):
|
|
505
510
|
self.brport.apply(do_apply, self.idx, excpts)
|
506
511
|
|
507
512
|
if has_state_changes:
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
513
|
+
if do_apply:
|
514
|
+
try:
|
515
|
+
ipr.link('set', index=self.idx,
|
516
|
+
state=self.settings["state"])
|
517
|
+
except Exception as err:
|
518
|
+
if not isinstance(err, netlinkerror_classes):
|
519
|
+
raise
|
520
|
+
excpts.add('set', err, state=state)
|
515
521
|
logger.info('change', extra={
|
516
522
|
'iface': self.settings['ifname'], 'style': IfStateLogging.STYLE_CHG})
|
517
523
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from libifstate.util import logger
|
2
|
+
from libifstate.link.base import Link
|
3
|
+
from libifstate.exception import LinkCannotAdd
|
4
|
+
|
5
|
+
from pwd import getpwnam
|
6
|
+
from grp import getgrnam
|
7
|
+
|
8
|
+
class TunLink(Link):
|
9
|
+
def __init__(self, name, link, ethtool, vrrp, brport):
|
10
|
+
if 'tun_owner' in link and isinstance(link['tun_owner'], str):
|
11
|
+
link['tun_owner'] = getpwnam(link['tun_owner'])[2]
|
12
|
+
|
13
|
+
if 'tun_group' in link and isinstance(link['tun_group'], str):
|
14
|
+
link['tun_group'] = getgrnam(link['tun_group'])[2]
|
15
|
+
|
16
|
+
super().__init__(name, link, ethtool, vrrp, brport)
|
17
|
+
self.cap_create = bool(link.get('tun_persist'))
|
18
|
+
|
19
|
+
def create(self, do_apply, sysctl, excpts, oper="add"):
|
20
|
+
if not self.cap_create:
|
21
|
+
logger.warning('Unable to create missing non-persistent tuntap link: {}'.format(self.settings.get('ifname')))
|
22
|
+
else:
|
23
|
+
super().create(do_apply, sysctl, excpts, oper)
|
@@ -1,44 +1,46 @@
|
|
1
1
|
import logging
|
2
2
|
from logging.handlers import QueueHandler, QueueListener
|
3
|
+
import os
|
3
4
|
import queue
|
4
5
|
import sys
|
5
6
|
|
6
7
|
logger = logging.getLogger('ifstate')
|
8
|
+
logger.propagate = False
|
9
|
+
|
10
|
+
formatter = logging.Formatter('%(bol)s%(prefix)s%(style)s%(message)s%(eol)s')
|
7
11
|
|
8
12
|
class IfStateLogFilter(logging.Filter):
|
9
|
-
def __init__(self,
|
13
|
+
def __init__(self, is_terminal):
|
10
14
|
super().__init__()
|
11
|
-
self.
|
15
|
+
self.is_terminal = is_terminal
|
12
16
|
|
13
17
|
def filter(self, record):
|
14
18
|
record.levelshort = record.levelname[:1]
|
19
|
+
|
15
20
|
if hasattr(record, 'iface'):
|
16
21
|
record.prefix = " {:15} ".format(record.iface)
|
17
22
|
else:
|
18
23
|
record.prefix = ''
|
19
24
|
|
20
|
-
if self.
|
25
|
+
if self.is_terminal and record.levelno >= logging.WARNING:
|
21
26
|
if record.levelno >= logging.ERROR:
|
22
27
|
record.bol = IfStateLogging.ANSI_RED
|
23
|
-
elif record.levelno >= logging.WARNING:
|
24
|
-
record.bol = IfStateLogging.ANSI_MAGENTA
|
25
28
|
else:
|
26
|
-
record.bol =
|
29
|
+
record.bol = IfStateLogging.ANSI_MAGENTA
|
27
30
|
record.eol = IfStateLogging.ANSI_RESET
|
28
31
|
else:
|
29
32
|
record.bol = ''
|
30
33
|
record.eol = ''
|
31
34
|
|
32
|
-
if hasattr(record, 'style'):
|
33
|
-
|
34
|
-
|
35
|
-
else:
|
36
|
-
record.style = ""
|
35
|
+
if self.is_terminal and hasattr(record, 'style'):
|
36
|
+
record.style = IfStateLogging.colorize(record.style)
|
37
|
+
record.eol = IfStateLogging.ANSI_RESET
|
37
38
|
else:
|
38
39
|
record.style = ""
|
39
40
|
|
40
41
|
return True
|
41
42
|
|
43
|
+
|
42
44
|
class IfStateLogging:
|
43
45
|
STYLE_OK = "ok"
|
44
46
|
STYLE_CHG = "chg"
|
@@ -61,22 +63,44 @@ class IfStateLogging:
|
|
61
63
|
return IfStateLogging.ANSI_YELLOW
|
62
64
|
return ""
|
63
65
|
|
64
|
-
def __init__(self, level, handlers=[]):
|
66
|
+
def __init__(self, level, handlers=[], action=None):
|
65
67
|
if level != logging.DEBUG:
|
66
68
|
sys.tracebacklimit = 0
|
67
69
|
|
68
70
|
logging.basicConfig(
|
69
71
|
level=level,
|
70
|
-
format='%(bol)s%(prefix)s%(style)s%(message)s%(eol)s',
|
71
72
|
)
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
74
|
+
has_stderr = sys.stderr is not None
|
75
|
+
is_terminal = has_stderr and sys.stderr.isatty()
|
76
|
+
|
77
|
+
# add custom logging handlers
|
78
|
+
if not handlers:
|
79
|
+
handlers = []
|
80
|
+
|
81
|
+
if has_stderr:
|
82
|
+
# log to stderr
|
83
|
+
stream = logging.StreamHandler(sys.stderr)
|
84
|
+
stream.addFilter(IfStateLogFilter(is_terminal))
|
85
|
+
stream.setFormatter(formatter)
|
86
|
+
handlers.append(stream)
|
87
|
+
|
88
|
+
# log to syslog
|
89
|
+
syslog = logging.handlers.SysLogHandler('/dev/log', facility=logging.handlers.SysLogHandler.LOG_DAEMON)
|
90
|
+
if action is None:
|
91
|
+
syslog.ident = 'ifstate[{}] '.format(os.getpid())
|
92
|
+
else:
|
93
|
+
syslog.ident = 'ifstate-{}[{}] '.format(action, os.getpid())
|
94
|
+
syslog.addFilter(IfStateLogFilter(False))
|
95
|
+
syslog.setFormatter(formatter)
|
96
|
+
handlers.append(syslog)
|
76
97
|
|
77
98
|
qu = queue.SimpleQueue()
|
78
|
-
|
79
|
-
|
99
|
+
queue_handler = QueueHandler(qu)
|
100
|
+
queue_handler.setLevel(level)
|
101
|
+
logger.addHandler(queue_handler)
|
102
|
+
self.listener = QueueListener(
|
103
|
+
qu, *handlers, respect_handler_level=True)
|
80
104
|
self.listener.start()
|
81
105
|
|
82
106
|
def quit(self):
|
@@ -1449,13 +1449,15 @@
|
|
1449
1449
|
}
|
1450
1450
|
},
|
1451
1451
|
{
|
1452
|
-
"description": "Virtual software device",
|
1452
|
+
"description": "Virtual software device (TUN/TAP)",
|
1453
1453
|
"required": [
|
1454
|
-
"kind"
|
1454
|
+
"kind",
|
1455
|
+
"tun_type"
|
1455
1456
|
],
|
1457
|
+
"additionalProperties": false,
|
1456
1458
|
"properties": {
|
1457
1459
|
"kind": {
|
1458
|
-
"const": "
|
1460
|
+
"const": "tun",
|
1459
1461
|
"description": "link type"
|
1460
1462
|
},
|
1461
1463
|
"address": {
|
@@ -1478,6 +1480,82 @@
|
|
1478
1480
|
},
|
1479
1481
|
"ifalias": {
|
1480
1482
|
"$ref": "#/$defs/iface-link_ifalias"
|
1483
|
+
},
|
1484
|
+
"tun_type": {
|
1485
|
+
"description": "device mode (Ethernet headers)",
|
1486
|
+
"default": "tap",
|
1487
|
+
"enum": [
|
1488
|
+
1,
|
1489
|
+
"tun",
|
1490
|
+
2,
|
1491
|
+
"tap"
|
1492
|
+
]
|
1493
|
+
},
|
1494
|
+
"tun_pi": {
|
1495
|
+
"description": "provide packet information",
|
1496
|
+
"type": [
|
1497
|
+
"boolean",
|
1498
|
+
"integer"
|
1499
|
+
],
|
1500
|
+
"default": false,
|
1501
|
+
"enum": [
|
1502
|
+
0,
|
1503
|
+
false,
|
1504
|
+
1,
|
1505
|
+
true
|
1506
|
+
]
|
1507
|
+
},
|
1508
|
+
"tun_persist": {
|
1509
|
+
"description": "persistent device; non-persistent devices cannot be created",
|
1510
|
+
"type": [
|
1511
|
+
"boolean",
|
1512
|
+
"integer"
|
1513
|
+
],
|
1514
|
+
"default": false,
|
1515
|
+
"enum": [
|
1516
|
+
0,
|
1517
|
+
false,
|
1518
|
+
1,
|
1519
|
+
true
|
1520
|
+
]
|
1521
|
+
},
|
1522
|
+
"tun_vnet_hdr": {
|
1523
|
+
"description": "prepend frames with struct virtio_net_hdr",
|
1524
|
+
"default": false,
|
1525
|
+
"enum": [
|
1526
|
+
0,
|
1527
|
+
false,
|
1528
|
+
1,
|
1529
|
+
true
|
1530
|
+
]
|
1531
|
+
},
|
1532
|
+
"tun_multi_queue": {
|
1533
|
+
"description": "enable multiqueue tuntap",
|
1534
|
+
"type": [
|
1535
|
+
"boolean",
|
1536
|
+
"integer"
|
1537
|
+
],
|
1538
|
+
"default": false,
|
1539
|
+
"enum": [
|
1540
|
+
0,
|
1541
|
+
false,
|
1542
|
+
1,
|
1543
|
+
true
|
1544
|
+
]
|
1545
|
+
},
|
1546
|
+
"tun_owner": {
|
1547
|
+
"description": "device owner",
|
1548
|
+
"type": [
|
1549
|
+
"integer",
|
1550
|
+
"string"
|
1551
|
+
]
|
1552
|
+
},
|
1553
|
+
"tun_group": {
|
1554
|
+
"description": "device group",
|
1555
|
+
"type": [
|
1556
|
+
"integer",
|
1557
|
+
"string"
|
1558
|
+
]
|
1481
1559
|
}
|
1482
1560
|
}
|
1483
1561
|
},
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|