ifstate 1.13.7__py3-none-any.whl → 1.13.8__py3-none-any.whl

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/ifstate.py CHANGED
@@ -128,7 +128,7 @@ def main():
128
128
  group = parser.add_mutually_exclusive_group()
129
129
  parser.add_argument('--version', action='version',
130
130
  version='%(prog)s {version}'.format(version=__version__))
131
- group.add_argument("-v", "--verbose", action="store_true",
131
+ group.add_argument("-v", "--verbose", action="count", default=0,
132
132
  help="be more verbose")
133
133
  group.add_argument("-q", "--quiet", action="store_true",
134
134
  help="be more quiet, print only warnings and errors")
@@ -162,10 +162,10 @@ def main():
162
162
  "name", type=str, help="name of the vrrp group or instance")
163
163
 
164
164
  args = parser.parse_args()
165
- if args.verbose:
165
+ if args.verbose > 0:
166
166
  lvl = logging.DEBUG
167
167
  elif args.quiet:
168
- lvl = logging.ERROR
168
+ lvl = logging.WARNING
169
169
  else:
170
170
  lvl = logging.INFO
171
171
 
@@ -178,7 +178,7 @@ def main():
178
178
  shell()
179
179
  exit(0)
180
180
 
181
- ifslog = IfStateLogging(lvl, action=args.action)
181
+ ifslog = IfStateLogging(lvl, args.verbose > 1, action=args.action)
182
182
 
183
183
  if args.action in [Actions.SHOW, Actions.SHOWALL]:
184
184
  # preserve dict order on python 3.7+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ifstate
3
- Version: 1.13.7
3
+ Version: 1.13.8
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -1,37 +1,37 @@
1
1
  ifstate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- ifstate/ifstate.py,sha256=l6VxiAXWyoqj7T5J495gM5Nhn807f5pHmL8_kh1uJAc,8891
2
+ ifstate/ifstate.py,sha256=am8x-ONL1QziOuTfD3Fmr5wVg_Mt2sH9Pi9DTn6YqYY,8921
3
3
  ifstate/shell.py,sha256=7_JFpi4icr9MijynDzbb0v5mxhFsng6PCC4m3uQ255A,2177
4
4
  ifstate/vrrp.py,sha256=FJ9b1eJseTtZFfknHU-xV68Qz7cPrRrc5PTcjUVj-fY,5953
5
- ifstate-1.13.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
6
- libifstate/__init__.py,sha256=dFqgv0fFecMsztHMh_IZnFyv2mOIyoM3KsmR13iCx5w,31132
7
- libifstate/exception.py,sha256=5i59BZdl56J_sNJbyU9n6uHuUNJEyDOO4FJ-neDn9Ds,2608
8
- libifstate/log.py,sha256=XVoZdwdQoWsjuupFIuG6OP0OrBpXpx7oqyAaUhQ-nJk,4553
5
+ ifstate-1.13.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
6
+ libifstate/__init__.py,sha256=9ovYpLf4AVTDNWFru4o4DaR60SQW0tXCrNMXLuoTPpU,31245
7
+ libifstate/exception.py,sha256=QgG4hdP1KYbdVBNfy-bT59aCcYF0IuFdEwZrY3QrwTc,2688
8
+ libifstate/log.py,sha256=rG0ISWyeGGlC_jRREoSpkdySc5EmyhOQIgSfvRqlaZA,4651
9
9
  libifstate/util.py,sha256=WzbGKX78iWUunnZ-v_3OREmxMiYt7vVM_QyCgTcMYow,10802
10
- libifstate/address/__init__.py,sha256=zIGM7UWXSvoijHMD06DfS2CDtiHpiJlqDgJG7Dl1IPE,3222
10
+ libifstate/address/__init__.py,sha256=SobrZ9e2ItrmEidnKPBhUMitRDdTEajbkU9Rkmtx-gQ,3165
11
11
  libifstate/bpf/__init__.py,sha256=NVzaunTmJU2PbIQg9eWBMKpFgLh3EnD3ujNa7Yt6rNc,7699
12
12
  libifstate/bpf/ctypes.py,sha256=kLZJHZlba09Vc-tbsJAcKpDwdoNO2IjlYVLCopawHmA,4274
13
13
  libifstate/bpf/map.py,sha256=cLHNMvRBDNW2yVCEf3z242_oRdU0HqVbFEYVkKXng0w,10818
14
14
  libifstate/brport/__init__.py,sha256=NzdA8F4hr2se1bXKNnyKZbvOFlCWBq_cdjwsL1H0Y-o,2964
15
15
  libifstate/fdb/__init__.py,sha256=9dpL5n8ct3CaA-z8I6ZEkD3yL6yWJQeq3fpIe9pc2zw,6486
16
16
  libifstate/link/__init__.py,sha256=epVw6jY8exNeJZUmmUas91yJoeupfgIY7rthq7SGIIw,142
17
- libifstate/link/base.py,sha256=vGMQDgvLbIX4OF9YOMwttcRAOZeGvsIQqXEpKNdLJH4,34739
17
+ libifstate/link/base.py,sha256=PLHJ594UQboe98jEVZVQvaD1Ka_Ah6EySDfcJtYTVH0,34863
18
18
  libifstate/link/dsa.py,sha256=Y3axTtcym6YL1voKblxctx4PoKDZHzpteKQNnEBUrS8,264
19
- libifstate/link/physical.py,sha256=cJiq-MCfy-3XQoU-OxzgfPZZtu_pJ8u2ioJgn9VYdGk,560
20
- libifstate/link/tun.py,sha256=m55o5cwO3h3DCLofUR-68fM4ggLoTKElp6ZJ2LrJSCc,959
19
+ libifstate/link/physical.py,sha256=rmf8ltjDy1s2NEfaQtOwKBTpESlzqjZd53yfcZCfSPo,579
20
+ libifstate/link/tun.py,sha256=YEW09fYNLvmb0IU4Jb1uNh0iCt0bgIii2pPvOYtgw6U,978
21
21
  libifstate/link/veth.py,sha256=V_jmQCizI5Vv8-pcsfldSfMRTn1knR11wZDZI_yXvks,2249
22
22
  libifstate/neighbour/__init__.py,sha256=FJJpbJvqnxvOEii6QDMYzW5jQDEbiEy71GQOEbqaS48,2463
23
- libifstate/netns/__init__.py,sha256=Fip3g2P1Tt_12pLt8abHsMRjSLZVi5THd1RJYcm9zfM,8887
23
+ libifstate/netns/__init__.py,sha256=-xJ5Qa-x2_MveGHWWR2pv--EBmQzLSZUYeC8vebnLUE,9029
24
24
  libifstate/parser/__init__.py,sha256=byz1W0G7UewVc5FFie-ti3UZjGK3-75wHIaOeq0oySQ,88
25
25
  libifstate/parser/base.py,sha256=VFAo05O3tiKtI381LVUMYfsDTseMKoQGTfkgnEkm3H4,4770
26
26
  libifstate/parser/yaml.py,sha256=MC0kmwqt3P45z61fb_wfUqoj0iZyhFYkdPyr0UqMSZA,1415
27
- libifstate/routing/__init__.py,sha256=fxDqDaNRcrb-8Lo6qH3UBifzJGymWwmMBXQSpMgyG0Y,22754
27
+ libifstate/routing/__init__.py,sha256=5kcIzWpM2v-T_ndxFO5qwF8hla-Fqh2yP1QtmohWZl0,22777
28
28
  libifstate/sysctl/__init__.py,sha256=EF52CdOOkVSUFR2t21A99KlG1-PjsD4qOiceQC4eI24,3074
29
- libifstate/tc/__init__.py,sha256=inPdampCOIr_4oKNB3awqMkW0Eh4fpPh9jvSba6sPVg,12092
30
- libifstate/wireguard/__init__.py,sha256=HEmGsrtIX8MEjxtMbqgzP-e2BIUicyfmcywnRE93lRQ,6579
29
+ libifstate/tc/__init__.py,sha256=T8LEBxiHZH4sayPn9lK5hK8eB8dskuw6-kw81W_aMWU,12097
30
+ libifstate/wireguard/__init__.py,sha256=RPJdMdp7Uv3Kk_koGH8bu0lVQaKlJQwkyobGFqtmp0E,6839
31
31
  libifstate/xdp/__init__.py,sha256=X1xhEIGng7R5d5F4KsChykT2g6H-XBRWbWABijoYDQA,7208
32
32
  schema/ifstate.conf.schema.json,sha256=NOPeI8_r1jXvgAAJeBqz92ZACNvxskId3qMykj-sG7M,201292
33
- ifstate-1.13.7.dist-info/METADATA,sha256=mmhqlLk_amWU3IHFsUo7FWtaZF3sMLoZ0VZNACZra1M,1598
34
- ifstate-1.13.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- ifstate-1.13.7.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
36
- ifstate-1.13.7.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
37
- ifstate-1.13.7.dist-info/RECORD,,
33
+ ifstate-1.13.8.dist-info/METADATA,sha256=dNYDgkvVdmbpS-A7CdZnwhmz-RXww8btSS8YunJ_WUg,1598
34
+ ifstate-1.13.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ ifstate-1.13.8.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
36
+ ifstate-1.13.8.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
37
+ ifstate-1.13.8.dist-info/RECORD,,
libifstate/__init__.py CHANGED
@@ -48,7 +48,7 @@ import json
48
48
  import errno
49
49
  import logging
50
50
 
51
- __version__ = "1.13.7"
51
+ __version__ = "1.13.8"
52
52
 
53
53
 
54
54
  class IfState():
@@ -347,8 +347,8 @@ class IfState():
347
347
  # ignore if the link is already gone, this might happen
348
348
  # when removing veth link peers
349
349
  if err.code != errno.ENODEV:
350
- logger.warning('removing link {} failed: {}'.format(
351
- ifname, err.args[1]), extra={'netns': item.netns})
350
+ logger.warning('removing failed: {}'.format(
351
+ err.args[1]), extra={'iface': ifname, 'netns': item.netns})
352
352
  return True
353
353
  else:
354
354
  # shutdown physical interfaces
@@ -362,8 +362,8 @@ class IfState():
362
362
  except Exception as err:
363
363
  if not isinstance(err, netlinkerror_classes):
364
364
  raise
365
- logger.warning('updating link {} failed: {}'.format(
366
- ifname, err.args[1]), extra={'netns': item.netns})
365
+ logger.warning('updating failed: {}'.format(
366
+ err.args[1]), extra={'iface': ifname, 'netns': item.netns})
367
367
  return False
368
368
 
369
369
  def _dependencies(self, netns):
@@ -516,9 +516,8 @@ class IfState():
516
516
  if link_dep.netns is None:
517
517
  self._apply_iface(do_apply, self.root_netns, link_dep, by_vrrp, vrrp_type, vrrp_name, vrrp_state)
518
518
  else:
519
- if link_dep.netns not in self.namespaces:
520
- logger.warning("add link {} failed: netns '{}' is unknown".format(link_dep.ifname, link_dep.netns))
521
- return
519
+ if self.namespaces is None or link_dep.netns not in self.namespaces:
520
+ logger.warning("apply link {} failed: netns '{}' is unknown".format(link_dep.ifname, link_dep.netns))
522
521
  else:
523
522
  self._apply_iface(do_apply, self.namespaces[link_dep.netns], link_dep, by_vrrp, vrrp_type, vrrp_name, vrrp_state)
524
523
 
@@ -557,8 +556,10 @@ class IfState():
557
556
 
558
557
  def _apply_iface(self, do_apply, netns, link_dep, by_vrrp, vrrp_type, vrrp_name, vrrp_state):
559
558
  ifname = link_dep.ifname
560
- if ifname in netns.links:
561
- link = netns.links[ifname]
559
+ if not ifname in netns.links:
560
+ logger.warning('no link settings found', extra={'iface': ifname, 'netns': netns})
561
+ return
562
+ link = netns.links[ifname]
562
563
 
563
564
  # check for vrrp mode:
564
565
  # disable: vrrp type & name matches, but vrrp state not
@@ -18,8 +18,8 @@ class Addresses():
18
18
  # get ifindex
19
19
  idx = next(iter(self.netns.ipr.link_lookup(ifname=self.iface)), None)
20
20
 
21
+ # check if interface exists
21
22
  if idx == None:
22
- logger.warning('link missing', extra={'iface': self.iface, 'netns': self.netns})
23
23
  return
24
24
 
25
25
  # get active ip addresses
libifstate/exception.py CHANGED
@@ -12,8 +12,9 @@ except ModuleNotFoundError:
12
12
  pass
13
13
 
14
14
  class ExceptionCollector():
15
- def __init__(self, ifname):
15
+ def __init__(self, ifname, netns):
16
16
  self.ifname = ifname
17
+ self.netns = netns
17
18
  self.reset()
18
19
 
19
20
  def reset(self):
@@ -27,8 +28,9 @@ class ExceptionCollector():
27
28
  'args': kwargs,
28
29
  })
29
30
  if not self.quiet:
30
- logger.warning('{} link {} failed: {}'.format(
31
- op, self.ifname, excpt.args[1]))
31
+ logger.warning('{} failed: {}'.format(
32
+ op, excpt.args[1]),
33
+ extra={'iface': self.ifname, 'netns': self.netns})
32
34
 
33
35
  def has_op(self, op):
34
36
  for e in self.excpts:
libifstate/link/base.py CHANGED
@@ -443,7 +443,7 @@ class Link(ABC):
443
443
  return self.match_vrrp_select(vrrp_type, vrrp_name) and (vrrp_state in self.vrrp['states'])
444
444
 
445
445
  def apply(self, do_apply, sysctl):
446
- excpts = ExceptionCollector(self.settings['ifname'])
446
+ excpts = ExceptionCollector(self.settings['ifname'], self.netns)
447
447
  osettings = copy.deepcopy(self.settings)
448
448
 
449
449
  # lookup for attributes requiring a interface index
@@ -455,8 +455,11 @@ class Link(ABC):
455
455
  # ignore *_netns settings if the netns is the same as the interface's one
456
456
  # (there is no IFLA_LINK_NETNSID attribute in such cases)
457
457
  if self.settings[netns_attr] != self.netns.netns:
458
- # ToDo: throw exception for unknown netns
459
- (peer_ipr, peer_nsid) = self.netns.get_netnsid(self.settings[netns_attr])
458
+ try:
459
+ (peer_ipr, peer_nsid) = self.netns.get_netnsid(self.settings[netns_attr])
460
+ except NetnsUnknown as ex:
461
+ excpts.add('apply', ex)
462
+ return excpts
460
463
  self.settings[netnsid_attr] = peer_nsid
461
464
  idx = next(iter(peer_ipr.link_lookup(
462
465
  ifname=self.settings[attr])), None)
@@ -10,4 +10,4 @@ class PhysicalLink(Link):
10
10
  self.ethtool = ethtool
11
11
 
12
12
  def create(self, do_apply, sysctl, excpts, oper="add"):
13
- logger.warning('Unable to create missing physical link: {}'.format(self.settings.get('ifname')))
13
+ logger.warning('unable to create physical link', extra={'iface': self.settings.get('ifname'), 'netns': self.netns})
libifstate/link/tun.py CHANGED
@@ -18,6 +18,6 @@ class TunLink(Link):
18
18
 
19
19
  def create(self, do_apply, sysctl, excpts, oper="add"):
20
20
  if not self.cap_create:
21
- logger.warning('Unable to create missing non-persistent tuntap link: {}'.format(self.settings.get('ifname')))
21
+ logger.warning('unable to create non-persistent tuntap link', extra={'iface': self.settings.get('ifname'), 'netns': self.netns})
22
22
  else:
23
23
  super().create(do_apply, sysctl, excpts, oper)
libifstate/log.py CHANGED
@@ -73,13 +73,16 @@ class IfStateLogging:
73
73
  return IfStateLogging.ANSI_YELLOW
74
74
  return ""
75
75
 
76
- def __init__(self, level, handlers=[], action=None, log_stderr=True):
76
+ def __init__(self, level, global_level, handlers=[], action=None, log_stderr=True):
77
77
  if level != logging.DEBUG:
78
78
  sys.tracebacklimit = 0
79
79
 
80
- logging.basicConfig(
81
- level=level,
82
- )
80
+ if global_level:
81
+ logging.basicConfig(
82
+ level=level,
83
+ )
84
+ else:
85
+ logger.level = level
83
86
 
84
87
  if log_stderr:
85
88
  has_stderr = sys.stderr is not None
@@ -1,3 +1,4 @@
1
+ from libifstate.exception import NetnsUnknown
1
2
  from libifstate.util import logger, IfStateLogging, IPRouteExt, NetNSExt, root_ipr
2
3
  from libifstate.sysctl import Sysctl
3
4
 
@@ -68,9 +69,11 @@ class NetNameSpace():
68
69
  if peer_netns_name is None:
69
70
  peer_ipr = root_ipr
70
71
  peer_pid = 1
71
- else:
72
+ elif peer_netns_name in netns_name_map:
72
73
  peer_ipr = netns_name_map[peer_netns_name]
73
74
  peer_pid = peer_ipr.child
75
+ else:
76
+ raise NetnsUnknown(peer_netns_name)
74
77
 
75
78
  result = self.ipr.get_netnsid(pid=peer_pid)
76
79
  if result['nsid'] == 4294967295:
@@ -1,6 +1,6 @@
1
1
  from libifstate.util import logger, IfStateLogging
2
2
  from libifstate.exception import RouteDuplicate, netlinkerror_classes
3
- from ipaddress import ip_address, ip_network, IPv6Network
3
+ from ipaddress import ip_address, ip_interface, ip_network, IPv6Network
4
4
  from pyroute2.netlink.rtnl.fibmsg import FR_ACT_VALUES
5
5
  from pyroute2.netlink.rtnl import rt_type
6
6
  import collections.abc
@@ -284,8 +284,8 @@ class Tables(collections.abc.Mapping):
284
284
  idx = next(
285
285
  iter(self.netns.ipr.link_lookup(ifname=ignore[attr])), None)
286
286
  if idx is None:
287
- logger.debug("{} '{}' is unknown".format(attr, ignore[attr]))
288
- del ignore[attr]
287
+ logger.debug("{} '{}' is unknown, skipping ignore".format(attr, ignore[attr]))
288
+ continue
289
289
  else:
290
290
  ignore[attr] = idx
291
291
  parsed.append(ignore)
libifstate/tc/__init__.py CHANGED
@@ -254,7 +254,7 @@ class TC():
254
254
  return changes
255
255
 
256
256
  def apply(self, do_apply):
257
- excpts = ExceptionCollector(ifname=self.iface)
257
+ excpts = ExceptionCollector(self.iface, self.netns)
258
258
 
259
259
  # get ifindex
260
260
  self.idx = next(iter(self.netns.ipr.link_lookup(ifname=self.iface)), None)
@@ -4,7 +4,9 @@ from wgnlpy import WireGuard as WG
4
4
  from ipaddress import ip_network
5
5
  import collections
6
6
  from copy import deepcopy
7
+ import os
7
8
  import pyroute2.netns
9
+ from pyroute2 import NetlinkError
8
10
  import socket
9
11
 
10
12
  class WireGuard():
@@ -56,6 +58,9 @@ class WireGuard():
56
58
  try:
57
59
  state = self.wg.get_interface(
58
60
  self.iface, spill_private_key=True, spill_preshared_keys=True)
61
+ except NetlinkError as err:
62
+ logger.warning('query wireguard details failed: {}'.format(os.strerror(err.code)), extra={'iface': self.iface, 'netns': self.netns})
63
+ return
59
64
  except TypeError as err:
60
65
  # wgnlpy 0.1.5 can triggger a TypeError exception
61
66
  # if the WGPEER_A_LAST_HANDSHAKE_TIME NLA does not
@@ -113,10 +118,10 @@ class WireGuard():
113
118
  for setting in peer.keys():
114
119
  attr = getattr(peers[pubkey], setting)
115
120
  if setting == 'allowedips':
116
- attr = set(attr)
121
+ attr = [str(ip) for ip in attr]
117
122
  logger.debug(' peer.%s: %s => %s', setting, attr,
118
123
  peer[setting], extra={'iface': self.iface})
119
- if type(attr) == set:
124
+ if type(attr) == list:
120
125
  pchange |= not (attr == peer[setting])
121
126
  else:
122
127
  pchange |= str(peer[setting]) != str(getattr(