ifstate 1.11.9__tar.gz → 1.12.0__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.
Files changed (42) hide show
  1. {ifstate-1.11.9 → ifstate-1.12.0}/PKG-INFO +1 -1
  2. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate.egg-info/PKG-INFO +1 -1
  3. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate.egg-info/SOURCES.txt +1 -0
  4. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/__init__.py +7 -3
  5. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/address/__init__.py +8 -4
  6. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/exception.py +5 -1
  7. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/link/__init__.py +1 -0
  8. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/link/base.py +26 -18
  9. ifstate-1.12.0/libifstate/link/dsa.py +10 -0
  10. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/link/veth.py +6 -2
  11. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/log.py +20 -8
  12. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/routing/__init__.py +2 -2
  13. {ifstate-1.11.9 → ifstate-1.12.0}/schema/ifstate.conf.schema.json +48 -0
  14. {ifstate-1.11.9 → ifstate-1.12.0}/LICENSE +0 -0
  15. {ifstate-1.11.9 → ifstate-1.12.0}/README.md +0 -0
  16. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate/__init__.py +0 -0
  17. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate/ifstate.py +0 -0
  18. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate/shell.py +0 -0
  19. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate/vrrp.py +0 -0
  20. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate.egg-info/dependency_links.txt +0 -0
  21. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate.egg-info/entry_points.txt +0 -0
  22. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate.egg-info/requires.txt +0 -0
  23. {ifstate-1.11.9 → ifstate-1.12.0}/ifstate.egg-info/top_level.txt +0 -0
  24. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/bpf/__init__.py +0 -0
  25. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/bpf/ctypes.py +0 -0
  26. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/bpf/map.py +0 -0
  27. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/brport/__init__.py +0 -0
  28. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/fdb/__init__.py +0 -0
  29. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/link/physical.py +0 -0
  30. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/link/tun.py +0 -0
  31. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/neighbour/__init__.py +0 -0
  32. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/netns/__init__.py +0 -0
  33. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/parser/__init__.py +0 -0
  34. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/parser/base.py +0 -0
  35. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/parser/yaml.py +0 -0
  36. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/sysctl/__init__.py +0 -0
  37. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/tc/__init__.py +0 -0
  38. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/util.py +0 -0
  39. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/wireguard/__init__.py +0 -0
  40. {ifstate-1.11.9 → ifstate-1.12.0}/libifstate/xdp/__init__.py +0 -0
  41. {ifstate-1.11.9 → ifstate-1.12.0}/setup.cfg +0 -0
  42. {ifstate-1.11.9 → ifstate-1.12.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ifstate
3
- Version: 1.11.9
3
+ Version: 1.12.0
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ifstate
3
- Version: 1.11.9
3
+ Version: 1.12.0
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -24,6 +24,7 @@ libifstate/brport/__init__.py
24
24
  libifstate/fdb/__init__.py
25
25
  libifstate/link/__init__.py
26
26
  libifstate/link/base.py
27
+ libifstate/link/dsa.py
27
28
  libifstate/link/physical.py
28
29
  libifstate/link/tun.py
29
30
  libifstate/link/veth.py
@@ -1,4 +1,4 @@
1
- from libifstate.exception import LinkDuplicate
1
+ from libifstate.exception import LinkDuplicate, NetnsUnknown
2
2
  from libifstate.link.base import ethtool_path, Link
3
3
  from libifstate.address import Addresses
4
4
  from libifstate.fdb import FDB
@@ -48,7 +48,7 @@ import json
48
48
  import errno
49
49
  import logging
50
50
 
51
- __version__ = "1.11.9"
51
+ __version__ = "1.12.0"
52
52
 
53
53
 
54
54
  class IfState():
@@ -519,7 +519,11 @@ class IfState():
519
519
  if link_dep.netns is None:
520
520
  self._apply_iface(do_apply, self.root_netns, link_dep, by_vrrp, vrrp_type, vrrp_name, vrrp_state)
521
521
  else:
522
- self._apply_iface(do_apply, self.namespaces[link_dep.netns], link_dep, by_vrrp, vrrp_type, vrrp_name, vrrp_state)
522
+ if link_dep.netns not in self.namespaces:
523
+ logger.warning("add link {} failed: netns '{}' is unknown".format(link_dep.ifname, link_dep.netns))
524
+ return
525
+ else:
526
+ self._apply_iface(do_apply, self.namespaces[link_dep.netns], link_dep, by_vrrp, vrrp_type, vrrp_name, vrrp_state)
523
527
 
524
528
  # configure routing
525
529
  logger.info("")
@@ -25,25 +25,29 @@ class Addresses():
25
25
  # get active ip addresses
26
26
  ipr_addr = {}
27
27
  addr_add = []
28
- addr_dad = []
28
+ addr_renew = []
29
29
  for addr in self.netns.ipr.get_addr(index=idx):
30
30
  flags = addr.get_attr('IFA_FLAGS', 0)
31
31
  ip = ip_interface(addr.get_attr('IFA_ADDRESS') +
32
32
  '/' + str(addr['prefixlen']))
33
33
  if flags & IFA_F_DADFAILED == IFA_F_DADFAILED:
34
34
  logger.debug('{} has failed dad'.format(ip), extra={'iface': self.iface, 'netns': self.netns})
35
- addr_dad.append(ip)
35
+ addr_renew.append(ip)
36
36
  ipr_addr[ip] = addr
37
37
 
38
38
  for addr in self.addresses:
39
- if addr in ipr_addr and addr not in addr_dad:
39
+ if addr in ipr_addr and addr not in addr_renew:
40
40
  logger.log_ok('addresses', '= {}'.format(addr.with_prefixlen))
41
41
  del ipr_addr[addr]
42
42
  else:
43
43
  addr_add.append(addr)
44
+ for ip in ipr_addr.keys():
45
+ if addr.ip == ip.ip:
46
+ addr_renew.append(ip)
47
+ break
44
48
 
45
49
  for ip, addr in ipr_addr.items():
46
- if addr in addr_dad or not any(ip in net for net in ignore):
50
+ if ip in addr_renew or not any(ip in net for net in ignore):
47
51
  if not ign_dynamic or ipr_addr[ip]['flags'] & IFA_F_PERMANENT == IFA_F_PERMANENT:
48
52
  logger.log_del('addresses', '- {}'.format(ip.with_prefixlen))
49
53
  try:
@@ -104,5 +104,9 @@ class ParserParseError(Exception):
104
104
  def exit_code(self):
105
105
  return 2
106
106
 
107
- class RouteDupblicate(Exception):
107
+ class RouteDuplicate(Exception):
108
108
  pass
109
+
110
+ class NetnsUnknown(Exception):
111
+ def __init__(self, netns):
112
+ self.args = (None, "netns '{}' is unknown".format(netns))
@@ -1,4 +1,5 @@
1
1
  import libifstate.link.base
2
+ import libifstate.link.dsa
2
3
  import libifstate.link.physical
3
4
  import libifstate.link.tun
4
5
  import libifstate.link.veth
@@ -1,5 +1,5 @@
1
1
  from libifstate.util import logger, IfStateLogging, LinkDependency
2
- from libifstate.exception import ExceptionCollector, LinkTypeUnknown, netlinkerror_classes
2
+ from libifstate.exception import ExceptionCollector, LinkTypeUnknown, NetnsUnknown, netlinkerror_classes
3
3
  from libifstate.brport import BRPort
4
4
  from libifstate.routing import RTLookups
5
5
  from abc import ABC, abstractmethod
@@ -99,6 +99,7 @@ class Link(ABC):
99
99
  'ip6gre',
100
100
  'ip6gretap',
101
101
  'geneve',
102
+ 'sit',
102
103
  'wireguard',
103
104
  'xfrm',
104
105
  ]
@@ -246,14 +247,16 @@ class Link(ABC):
246
247
  return ret
247
248
 
248
249
  info = self.iface.get_attr('IFLA_LINKINFO')
249
- if not info is None:
250
- ret = info.get_attr(nla)
250
+ op = getattr(info, 'get_attr', None)
251
+ if callable(op):
252
+ ret = op(nla)
251
253
  if not ret is None:
252
254
  return ret
253
255
 
254
- info = info.get_attr('IFLA_INFO_DATA')
255
- if not info is None:
256
- ret = info.get_attr(nla)
256
+ info = op('IFLA_INFO_DATA')
257
+ op = getattr(info, 'get_attr', None)
258
+ if callable(op):
259
+ ret = op(nla)
257
260
  if not ret is None:
258
261
  return ret
259
262
 
@@ -388,6 +391,9 @@ class Link(ABC):
388
391
  if self.bind_netns is None:
389
392
  return self.ifstate.root_netns
390
393
 
394
+ if not self.bind_netns in self.ifstate.namespaces:
395
+ raise NetnsUnknown(self.bind_netns)
396
+
391
397
  return self.ifstate.namespaces.get(self.bind_netns)
392
398
 
393
399
  def bind_needs_recreate(self, item):
@@ -395,13 +401,6 @@ class Link(ABC):
395
401
  return False
396
402
 
397
403
  bind_netns = self.get_bind_netns()
398
- if bind_netns is None:
399
- logger.warning('bind_netns "%s" is unknown',
400
- self.bind_netns,
401
- extra={
402
- 'iface': self.settings['ifname'],
403
- 'netns': self.netns})
404
- return False
405
404
 
406
405
  fn = self.get_bind_fn(item.netns.netns, item.index)
407
406
  try:
@@ -468,11 +467,15 @@ class Link(ABC):
468
467
  item = self.search_link_registry()
469
468
 
470
469
  # check if bind_netns option requires a recreate
471
- if item is not None and self.bind_needs_recreate(item):
472
- self.idx = item.index
473
- self.recreate(do_apply, sysctl, excpts)
470
+ try:
471
+ if item is not None and self.bind_needs_recreate(item):
472
+ self.idx = item.index
473
+ self.recreate(do_apply, sysctl, excpts)
474
474
 
475
- self.settings = osettings
475
+ self.settings = osettings
476
+ return excpts
477
+ except NetnsUnknown as ex:
478
+ excpts.add('apply', ex)
476
479
  return excpts
477
480
 
478
481
  # move interface into netns if required
@@ -534,7 +537,12 @@ class Link(ABC):
534
537
  logger.log_add('link', oper)
535
538
 
536
539
  settings = copy.deepcopy(self.settings)
537
- bind_netns = self.get_bind_netns()
540
+ try:
541
+ bind_netns = self.get_bind_netns()
542
+ except NetnsUnknown as ex:
543
+ excpts.add(oper, ex)
544
+ return excpts
545
+
538
546
  if bind_netns is not None and bind_netns.netns != self.netns.netns:
539
547
  logger.debug("handle link binding", extra={
540
548
  'iface': self.settings['ifname'],
@@ -0,0 +1,10 @@
1
+ from libifstate.util import logger
2
+ from libifstate.link.physical import PhysicalLink
3
+
4
+ class DsaLink(PhysicalLink):
5
+ """
6
+ Distributed Switch Architecture (DSA) user interface
7
+
8
+ https://docs.kernel.org/networking/dsa/configuration.html
9
+ """
10
+ pass
@@ -1,6 +1,6 @@
1
1
  from libifstate.util import logger
2
2
  from libifstate.link.base import Link
3
- from libifstate.exception import LinkCannotAdd
3
+ from libifstate.exception import LinkCannotAdd, NetnsUnknown
4
4
 
5
5
  class VethLink(Link):
6
6
  def __init__(self, ifstate, netns, name, link, ethtool, vrrp, brport):
@@ -18,7 +18,11 @@ class VethLink(Link):
18
18
  '''
19
19
  result = super().create(do_apply, sysctl, excpts, oper)
20
20
 
21
- bind_netns = self.get_bind_netns()
21
+ try:
22
+ bind_netns = self.get_bind_netns()
23
+ except NetnsUnknown as ex:
24
+ excpts.add(oper, ex)
25
+ return excpts
22
26
  peer_link = next(iter(bind_netns.ipr.get_links(ifname=self.settings['peer'])), None)
23
27
  self.ifstate.link_registry.add_link(bind_netns, peer_link)
24
28
 
@@ -2,6 +2,7 @@ import logging
2
2
  from logging.handlers import QueueHandler, QueueListener
3
3
  import os
4
4
  import queue
5
+ import stat
5
6
  import sys
6
7
 
7
8
  logger = logging.getLogger('ifstate')
@@ -98,14 +99,25 @@ class IfStateLogging:
98
99
  handlers.append(stream)
99
100
 
100
101
  # log to syslog
101
- syslog = logging.handlers.SysLogHandler('/dev/log', facility=logging.handlers.SysLogHandler.LOG_DAEMON)
102
- if action is None:
103
- syslog.ident = 'ifstate[{}] '.format(os.getpid())
104
- else:
105
- syslog.ident = 'ifstate-{}[{}] '.format(action, os.getpid())
106
- syslog.addFilter(IfStateLogFilter(False))
107
- syslog.setFormatter(formatter)
108
- handlers.append(syslog)
102
+ socket_filename = '/dev/log'
103
+ try:
104
+ if not stat.S_ISSOCK(os.stat(socket_filename).st_mode):
105
+ socket_filename = None
106
+ except OSError:
107
+ socket_filename = None
108
+
109
+ if socket_filename is not None:
110
+ syslog = logging.handlers.SysLogHandler(socket_filename, facility=logging.handlers.SysLogHandler.LOG_DAEMON)
111
+ if action is None:
112
+ syslog.ident = 'ifstate[{}] '.format(os.getpid())
113
+ else:
114
+ syslog.ident = 'ifstate-{}[{}] '.format(action, os.getpid())
115
+ syslog.addFilter(IfStateLogFilter(False))
116
+ syslog.setFormatter(formatter)
117
+ handlers.append(syslog)
118
+
119
+ if len(handlers) == 0:
120
+ handlers.append(logging.NullHandler())
109
121
 
110
122
  qu = queue.SimpleQueue()
111
123
  queue_handler = QueueHandler(qu)
@@ -1,5 +1,5 @@
1
1
  from libifstate.util import logger, IfStateLogging
2
- from libifstate.exception import RouteDupblicate, netlinkerror_classes
2
+ from libifstate.exception import RouteDuplicate, netlinkerror_classes
3
3
  from ipaddress import ip_address, ip_network, IPv6Network
4
4
  from pyroute2.netlink.rtnl.fibmsg import FR_ACT_VALUES
5
5
  from pyroute2.netlink.rtnl import rt_type
@@ -90,7 +90,7 @@ class RTLookup():
90
90
  return self.str2id[key]
91
91
 
92
92
  def lookup_str(self, key):
93
- return self.id2str.get(key, key)
93
+ return self.id2str.get(key, str(key))
94
94
 
95
95
 
96
96
  class RTLookups():
@@ -2743,6 +2743,51 @@
2743
2743
  }
2744
2744
  }
2745
2745
  },
2746
+ {
2747
+ "description": "DSA interface",
2748
+ "required": [
2749
+ "kind",
2750
+ "link"
2751
+ ],
2752
+ "additionalProperties": false,
2753
+ "properties": {
2754
+ "kind": {
2755
+ "const": "dsa",
2756
+ "description": "link type"
2757
+ },
2758
+ "address": {
2759
+ "$ref": "#/$defs/iface-link_address"
2760
+ },
2761
+ "group": {
2762
+ "$ref": "#/$defs/iface-link_group"
2763
+ },
2764
+ "permaddr": {
2765
+ "description": "select interface by permanent address [ethtool -P]",
2766
+ "$ref": "#/$defs/iface-link_address"
2767
+ },
2768
+ "state": {
2769
+ "$ref": "#/$defs/iface-link_state"
2770
+ },
2771
+ "master": {
2772
+ "$ref": "#/$defs/iface-link_master"
2773
+ },
2774
+ "mtu": {
2775
+ "$ref": "#/$defs/iface-link_mtu"
2776
+ },
2777
+ "txqlen": {
2778
+ "$ref": "#/$defs/iface-link_txqlen"
2779
+ },
2780
+ "ifalias": {
2781
+ "$ref": "#/$defs/iface-link_ifalias"
2782
+ },
2783
+ "link": {
2784
+ "$ref": "#/$defs/iface-link_link"
2785
+ },
2786
+ "link_netns": {
2787
+ "$ref": "#/$defs/iface-link_link-netns"
2788
+ }
2789
+ }
2790
+ },
2746
2791
  {
2747
2792
  "description": "Dummy network interface",
2748
2793
  "required": [
@@ -3136,6 +3181,9 @@
3136
3181
  "address": {
3137
3182
  "$ref": "#/$defs/iface-link_address"
3138
3183
  },
3184
+ "bind_netns": {
3185
+ "$ref": "#/$defs/iface-link_bind-netns"
3186
+ },
3139
3187
  "group": {
3140
3188
  "$ref": "#/$defs/iface-link_group"
3141
3189
  },
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