ifstate 1.13.1__tar.gz → 1.13.3__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.13.1 → ifstate-1.13.3}/PKG-INFO +11 -2
  2. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate/ifstate.py +5 -3
  3. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate/vrrp.py +9 -1
  4. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate.egg-info/PKG-INFO +11 -2
  5. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/__init__.py +5 -2
  6. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/fdb/__init__.py +37 -31
  7. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/link/base.py +29 -1
  8. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/link/veth.py +5 -0
  9. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/netns/__init__.py +14 -13
  10. {ifstate-1.13.1 → ifstate-1.13.3}/schema/ifstate.conf.schema.json +3 -3
  11. {ifstate-1.13.1 → ifstate-1.13.3}/LICENSE +0 -0
  12. {ifstate-1.13.1 → ifstate-1.13.3}/README.md +0 -0
  13. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate/__init__.py +0 -0
  14. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate/shell.py +0 -0
  15. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate.egg-info/SOURCES.txt +0 -0
  16. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate.egg-info/dependency_links.txt +0 -0
  17. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate.egg-info/entry_points.txt +0 -0
  18. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate.egg-info/requires.txt +0 -0
  19. {ifstate-1.13.1 → ifstate-1.13.3}/ifstate.egg-info/top_level.txt +0 -0
  20. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/address/__init__.py +0 -0
  21. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/bpf/__init__.py +0 -0
  22. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/bpf/ctypes.py +0 -0
  23. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/bpf/map.py +0 -0
  24. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/brport/__init__.py +0 -0
  25. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/exception.py +0 -0
  26. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/link/__init__.py +0 -0
  27. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/link/dsa.py +0 -0
  28. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/link/physical.py +0 -0
  29. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/link/tun.py +0 -0
  30. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/log.py +0 -0
  31. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/neighbour/__init__.py +0 -0
  32. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/parser/__init__.py +0 -0
  33. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/parser/base.py +0 -0
  34. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/parser/yaml.py +0 -0
  35. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/routing/__init__.py +0 -0
  36. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/sysctl/__init__.py +0 -0
  37. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/tc/__init__.py +0 -0
  38. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/util.py +0 -0
  39. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/wireguard/__init__.py +0 -0
  40. {ifstate-1.13.1 → ifstate-1.13.3}/libifstate/xdp/__init__.py +0 -0
  41. {ifstate-1.13.1 → ifstate-1.13.3}/setup.cfg +0 -0
  42. {ifstate-1.13.1 → ifstate-1.13.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ifstate
3
- Version: 1.13.1
3
+ Version: 1.13.3
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -16,6 +16,15 @@ Provides-Extra: shell
16
16
  Requires-Dist: pygments; extra == "shell"
17
17
  Provides-Extra: wireguard
18
18
  Requires-Dist: wgnlpy; extra == "wireguard"
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: provides-extra
26
+ Dynamic: requires-dist
27
+ Dynamic: summary
19
28
 
20
29
  # IfState
21
30
 
@@ -4,6 +4,7 @@ from libifstate.parser import YamlParser
4
4
  from libifstate import __version__, IfState
5
5
  from libifstate.exception import FeatureMissingError, LinkNoConfigFound, LinkCircularLinked, NetNSNotRoot, ParserValidationError, ParserOpenError, ParserParseError, ParserIncludeError
6
6
  from libifstate.util import logger, IfStateLogging
7
+ from ifstate.vrrp import KEEPALIVED_STATES, KEEPALIVED_IGNORE_STATES
7
8
  from setproctitle import setproctitle
8
9
 
9
10
  import argparse
@@ -148,7 +149,7 @@ def main():
148
149
  action_parsers[Actions.VRRP].add_argument(
149
150
  "name", type=str, help="name of the vrrp group or instance")
150
151
  action_parsers[Actions.VRRP].add_argument(
151
- "state", type=str.lower, choices=["unknown", "fault", "backup", "master"], help="the new state for the vrrp group or instance")
152
+ "state", type=str.lower, choices=KEEPALIVED_STATES, help="the new state for the vrrp group or instance")
152
153
 
153
154
  # Parameters for the vrrp-fifo action
154
155
  action_parsers[Actions.VRRP_FIFO].add_argument(
@@ -226,8 +227,9 @@ def main():
226
227
  ifs_config.ifs.apply()
227
228
  sighup_vrrp_fifo()
228
229
  elif args.action == Actions.VRRP:
229
- ifs_config.ifs.apply(
230
- args.type, args.name, args.state)
230
+ if not args.state in KEEPALIVED_IGNORE_STATES:
231
+ ifs_config.ifs.apply(
232
+ args.type, args.name, args.state)
231
233
  except LinkNoConfigFound:
232
234
  pass
233
235
  except LinkCircularLinked as ex:
@@ -12,6 +12,10 @@ import signal
12
12
  import subprocess
13
13
  import sys
14
14
 
15
+ KEEPALIVED_HANDLE_STATES = ['backup', 'fault', 'master', 'stop', 'unknown']
16
+ KEEPALIVED_IGNORE_STATES = ['backup_priority', 'master_priority', 'master_rx_lower_pri']
17
+ KEEPALIVED_STATES = KEEPALIVED_HANDLE_STATES + KEEPALIVED_IGNORE_STATES
18
+
15
19
  class VrrpFifoProcess():
16
20
  '''
17
21
  Process for vrrp group/instance configuration.
@@ -135,7 +139,7 @@ def vrrp_fifo(args_fifo, ifs_config):
135
139
 
136
140
  try:
137
141
  status_pattern = re.compile(
138
- r'(group|instance) "([^"]+)" (unknown|fault|backup|master|stop)( \d+)?$', re.IGNORECASE)
142
+ r'(group|instance) "([^"]+)" (' + '|'.join(KEEPALIVED_STATES) + ')( \d+)?$', re.IGNORECASE)
139
143
 
140
144
  with open(args_fifo) as fifo:
141
145
  logger.debug("entering fifo loop...")
@@ -146,6 +150,10 @@ def vrrp_fifo(args_fifo, ifs_config):
146
150
  vrrp_name = m.group(2)
147
151
  vrrp_state = m.group(3)
148
152
 
153
+ # ignore priority changes w/o state changes
154
+ if vrrp_state.lower() in KEEPALIVED_IGNORE_STATES:
155
+ continue
156
+
149
157
  vrrp_states.update(vrrp_type, vrrp_name, vrrp_state)
150
158
  else:
151
159
  logger.warning(f'failed to parse fifo input: {line.strip()}')
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ifstate
3
- Version: 1.13.1
3
+ Version: 1.13.3
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -16,6 +16,15 @@ Provides-Extra: shell
16
16
  Requires-Dist: pygments; extra == "shell"
17
17
  Provides-Extra: wireguard
18
18
  Requires-Dist: wgnlpy; extra == "wireguard"
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: provides-extra
26
+ Dynamic: requires-dist
27
+ Dynamic: summary
19
28
 
20
29
  # IfState
21
30
 
@@ -48,7 +48,7 @@ import json
48
48
  import errno
49
49
  import logging
50
50
 
51
- __version__ = "1.13.1"
51
+ __version__ = "1.13.3"
52
52
 
53
53
 
54
54
  class IfState():
@@ -111,6 +111,9 @@ class IfState():
111
111
  self.ipaddr_ignore = set()
112
112
  for ip in self.ignore.get('ipaddr', []):
113
113
  self.ipaddr_ignore.add(ip_network(ip))
114
+ self.fdb_ignore = None
115
+ if self.ignore.get('fdb'):
116
+ self.fdb_ignore = re.compile('|'.join(self.ignore.get('fdb')))
114
117
 
115
118
  # save cshaper profiles
116
119
  self.cshaper_profiles = ifstates['cshaper']
@@ -598,7 +601,7 @@ class IfState():
598
601
  'ipaddr_dynamic', True), do_apply)
599
602
 
600
603
  if ifname in netns.fdb:
601
- netns.fdb[ifname].apply(do_apply)
604
+ netns.fdb[ifname].apply(self.fdb_ignore, do_apply)
602
605
 
603
606
  if ifname in netns.neighbours:
604
607
  netns.neighbours[ifname].apply(do_apply)
@@ -88,7 +88,7 @@ class FDB():
88
88
 
89
89
  return fdb
90
90
 
91
- def apply(self, do_apply):
91
+ def apply(self, fdb_ignore_re, do_apply):
92
92
  logger.debug('getting fdb', extra={'iface': self.iface})
93
93
 
94
94
  # get ifindex and lladdr
@@ -108,41 +108,12 @@ class FDB():
108
108
  if linkinfo and linkinfo.get_attr('IFLA_INFO_KIND') in ['vxlan']:
109
109
  default_state |= NUD_NOARP
110
110
 
111
- # configure fdb entries
112
- ipr_entries = self.get_kernel_fdb()
111
+ # set default_state if missing
113
112
  for lladdr, entries in self.fdb.items():
114
113
  for entry in entries:
115
- # set default_state if missing
116
114
  if not 'state' in entry:
117
115
  entry['state'] = default_state
118
116
 
119
- # check if fdb entry is already present
120
- if lladdr in ipr_entries:
121
- if entry in ipr_entries[lladdr]:
122
- logger.log_ok('fdb', '= {}'.format(lladdr))
123
- continue
124
-
125
- # fdb entry needs to be added
126
- logger.log_add('fdb', '+ {}'.format(lladdr))
127
-
128
- # prepare arguments
129
- args = {
130
- 'ifindex': self.idx,
131
- 'family': AF_BRIDGE
132
- }
133
- args.update(entry)
134
- logger.debug("bridge fdb append: {}".format(
135
- " ".join("{}={}".format(k, v) for k, v in args.items())))
136
-
137
- if do_apply:
138
- try:
139
- self.netns.ipr.fdb("append", **args)
140
- except Exception as err:
141
- if not isinstance(err, netlinkerror_classes):
142
- raise
143
- logger.warning('add {} to fdb failed: {}'.format(
144
- entry['lladdr'], err.args[1]))
145
-
146
117
  # cleanup orphan fdb entries
147
118
  ipr_entries = self.get_kernel_fdb()
148
119
  for lladdr, entries in ipr_entries.items():
@@ -150,6 +121,10 @@ class FDB():
150
121
  if lladdr == self.lladdr:
151
122
  continue
152
123
 
124
+ # skip ignored lladdr
125
+ if fdb_ignore_re is not None and fdb_ignore_re.match(lladdr):
126
+ continue
127
+
153
128
  for entry in entries:
154
129
  # check if fdb entry is already present
155
130
  if lladdr not in self.fdb or entry not in self.fdb[lladdr]:
@@ -172,3 +147,34 @@ class FDB():
172
147
  raise
173
148
  logger.warning('remove {} from fdb failed: {}'.format(
174
149
  entry['lladdr'], err.args[1]))
150
+
151
+ # configure fdb entries
152
+ ipr_entries = self.get_kernel_fdb()
153
+ for lladdr, entries in self.fdb.items():
154
+ for entry in entries:
155
+ # check if fdb entry is already present
156
+ if lladdr in ipr_entries:
157
+ if entry in ipr_entries[lladdr]:
158
+ logger.log_ok('fdb', '= {}'.format(lladdr))
159
+ continue
160
+
161
+ # fdb entry needs to be added
162
+ logger.log_add('fdb', '+ {}'.format(lladdr))
163
+
164
+ # prepare arguments
165
+ args = {
166
+ 'ifindex': self.idx,
167
+ 'family': AF_BRIDGE
168
+ }
169
+ args.update(entry)
170
+ logger.debug("bridge fdb append: {}".format(
171
+ " ".join("{}={}".format(k, v) for k, v in args.items())))
172
+
173
+ if do_apply:
174
+ try:
175
+ self.netns.ipr.fdb("append", **args)
176
+ except Exception as err:
177
+ if not isinstance(err, netlinkerror_classes):
178
+ raise
179
+ logger.warning('add {} to fdb failed: {}'.format(
180
+ entry['lladdr'], err.args[1]))
@@ -3,6 +3,7 @@ from libifstate.exception import ExceptionCollector, LinkTypeUnknown, NetnsUnkno
3
3
  from libifstate.brport import BRPort
4
4
  from libifstate.routing import RTLookups
5
5
  from abc import ABC, abstractmethod
6
+ import errno
6
7
  import os
7
8
  import subprocess
8
9
  import yaml
@@ -66,6 +67,11 @@ class Link(ABC):
66
67
  1: "bandwidth",
67
68
  2: "count",
68
69
  },
70
+ # === bridge ===
71
+ 'br_vlan_protocol': {
72
+ 0x88a8: '802.1ad',
73
+ 0x8100: '802.1q',
74
+ },
69
75
  # === tuntap ===
70
76
  'tun_type': {
71
77
  1: 'tun',
@@ -104,6 +110,12 @@ class Link(ABC):
104
110
  'wireguard',
105
111
  'xfrm',
106
112
  ]
113
+ # the attributes will be unset using an emptry string,
114
+ # if unset they are not return via netlink and handled
115
+ # as a `None` value in ifstate
116
+ attr_empty_unset = [
117
+ 'ifalias',
118
+ ]
107
119
 
108
120
  def __new__(cls, *args, **kwargs):
109
121
  cname = cls.__name__
@@ -208,6 +220,10 @@ class Link(ABC):
208
220
  if 'bind_netns' in self.settings:
209
221
  del(self.settings['bind_netns'])
210
222
 
223
+ for attr in self.attr_empty_unset:
224
+ if attr in self.settings and self.settings[attr] == "":
225
+ self.settings[attr] = None
226
+
211
227
  def search_link_registry(self):
212
228
  for args in self.link_registry_search_args:
213
229
  item = self.ifstate.link_registry.get_link(**args)
@@ -628,7 +644,9 @@ class Link(ABC):
628
644
  except Exception as err:
629
645
  if not isinstance(err, netlinkerror_classes):
630
646
  raise
631
- excpts.add('del', err)
647
+
648
+ if err.code != errno.ENODEV:
649
+ excpts.add('del', err)
632
650
  self.idx = None
633
651
  self.create(do_apply, sysctl, excpts, "replace")
634
652
 
@@ -723,6 +741,12 @@ class Link(ABC):
723
741
  if setting in self.settings:
724
742
  skipped_settings[setting] = self.settings.pop(setting)
725
743
 
744
+ # handle settings which are unset using empty strings (i.e. ifstate)
745
+ for setting in self.attr_empty_unset:
746
+ if setting in self.settings and self.settings[setting] == None:
747
+ skipped_settings[setting] = self.settings.pop(setting)
748
+ self.settings[setting] = ""
749
+
726
750
  if has_ifname_change:
727
751
  self.prevent_altname_conflict()
728
752
 
@@ -738,6 +762,10 @@ class Link(ABC):
738
762
  # None index references are configuration via the invalid ifindex 0
739
763
  value = 0
740
764
 
765
+ # these attributes are not returned if unset (i.e. ifstate)
766
+ if setting in self.attr_empty_unset and value == None:
767
+ value = ""
768
+
741
769
  if value != self.settings[setting]:
742
770
  if self.cap_create:
743
771
  logger.debug(' %s: setting could not be changed', setting, extra={'iface': self.settings['ifname']})
@@ -23,7 +23,12 @@ class VethLink(Link):
23
23
  except NetnsUnknown as ex:
24
24
  excpts.add(oper, ex)
25
25
  return excpts
26
+
26
27
  peer_link = next(iter(bind_netns.ipr.get_links(ifname=self.settings['peer'])), None)
28
+ if peer_link is None:
29
+ excpts.add(oper, LinkCannotAdd(-1,"Failed to get peer ifIndex"))
30
+ return excpts
31
+
27
32
  self.ifstate.link_registry.add_link(bind_netns, peer_link)
28
33
 
29
34
  return result
@@ -13,10 +13,6 @@ import subprocess
13
13
  netns_name_map = {}
14
14
  netns_name_root = None
15
15
  netns_nsid_map = {}
16
- findmnt_cmd = shutil.which('findmnt')
17
-
18
- if findmnt_cmd is None:
19
- logger.debug("findmnt binary is not available, netns binding of links might not be correct")
20
16
 
21
17
  @atexit.register
22
18
  def close_netns():
@@ -52,10 +48,7 @@ class NetNameSpace():
52
48
  else:
53
49
  self.ipr = NetNSExt(name)
54
50
  netns_name_map[name] = self.ipr
55
- if findmnt_cmd is None:
56
- self.mount = name.encode("utf-8")
57
- else:
58
- self.mount = subprocess.check_output([findmnt_cmd, '-f', '-J', "/run/netns/{}".format(name)])
51
+ self.mount = name.encode("utf-8")
59
52
 
60
53
  def __deepcopy__(self, memo):
61
54
  '''
@@ -217,14 +210,14 @@ class LinkRegistry():
217
210
 
218
211
  class LinkRegistryItem():
219
212
  def __init__(self, registry, netns, link):
220
- self.registry = registry
221
- self.netns = netns
222
- self.link = None
223
213
  self.attributes = {
224
214
  'index': link['index'],
225
215
  'ifname': link.get_attr('IFLA_IFNAME'),
226
216
  'address': link.get_attr('IFLA_ADDRESS'),
227
217
  }
218
+ self.registry = registry
219
+ self.netns = netns
220
+ self.link = None
228
221
  self.state = link['state']
229
222
 
230
223
  linkinfo = link.get_attr('IFLA_LINKINFO')
@@ -235,8 +228,6 @@ class LinkRegistryItem():
235
228
  self.attributes['businfo'] = self.netns.ipr.get_businfo(self.attributes['ifname'])
236
229
  self.attributes['permaddr'] = link.get_attr('IFLA_PERM_ADDRESS')
237
230
 
238
- self.attributes['netns'] =self.netns.netns
239
-
240
231
  def __ipr_link(self, command, **kwargs):
241
232
  logger.debug("ip link set netns={} {}".format(
242
233
  self.netns.netns,
@@ -249,6 +240,16 @@ class LinkRegistryItem():
249
240
  def index(self):
250
241
  return self.attributes['index']
251
242
 
243
+ @property
244
+ def netns(self):
245
+ return self._netns
246
+
247
+ @netns.setter
248
+ def netns(self, value):
249
+ self._netns = value
250
+ self.attributes['netns'] = value.netns
251
+ return self._netns
252
+
252
253
  def match(self, **kwargs):
253
254
  for attr, value in kwargs.items():
254
255
  if self.attributes.get(attr) != value:
@@ -3363,10 +3363,10 @@
3363
3363
  "$ref": "#/$defs/iface-link_ifalias"
3364
3364
  },
3365
3365
  "ip6gre_remote": {
3366
- "$ref": "#/$defs/iface-link_tun-remote4"
3366
+ "$ref": "#/$defs/iface-link_tun-remote6"
3367
3367
  },
3368
3368
  "ip6gre_local": {
3369
- "$ref": "#/$defs/iface-link_tun-local4"
3369
+ "$ref": "#/$defs/iface-link_tun-local6"
3370
3370
  },
3371
3371
  "ip6gre_link": {
3372
3372
  "$ref": "#/$defs/iface-link_tun-dev"
@@ -4256,4 +4256,4 @@
4256
4256
  }
4257
4257
  }
4258
4258
  }
4259
- }
4259
+ }
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