ifstate 2.0.0rc1__py3-none-any.whl → 2.0.0rc3__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
@@ -136,6 +136,8 @@ def main():
136
136
  help="be more quiet, print only warnings and errors")
137
137
  parser.add_argument("-s", "--soft-schema", action="store_true",
138
138
  help="ignore schema validation errors, expect ifstatecli to trigger internal exceptions")
139
+ parser.add_argument("-S", "--show-secrets", action="store_true",
140
+ help="show secrets when dumping config")
139
141
  parser.add_argument("-c", "--config", type=str,
140
142
  default="/etc/ifstate/config.yml", help="configuration YaML filename")
141
143
  subparsers = parser.add_subparsers(
@@ -191,7 +193,7 @@ def main():
191
193
  if args.action == Actions.IDENTIFY:
192
194
  print(yaml.dump(ifs.identify()))
193
195
  else:
194
- print(yaml.dump(ifs.show(args.action == Actions.SHOWALL)))
196
+ print(yaml.dump(ifs.show(args.action == Actions.SHOWALL, args.show_secrets)))
195
197
 
196
198
  ifslog.quit()
197
199
  exit(0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ifstate
3
- Version: 2.0.0rc1
3
+ Version: 2.0.0rc3
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -9,7 +9,7 @@ License: GPL3+
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: jsonschema
12
- Requires-Dist: pyroute2
12
+ Requires-Dist: pyroute2!=0.9.3
13
13
  Requires-Dist: pyyaml
14
14
  Requires-Dist: setproctitle
15
15
  Provides-Extra: shell
@@ -1,13 +1,13 @@
1
1
  hooks/wrapper.sh,sha256=ipCmvcadJbXTT6oUR7BIhT5uglITnHfiAdm44vydZuw,1101
2
2
  ifstate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- ifstate/ifstate.py,sha256=OYSQ437-y8oRhnTtudZnHgzIW3kVuyCW9U4mNeA_i54,9119
3
+ ifstate/ifstate.py,sha256=ioiM9xgVWdrpTpK_UxJdaJFlmpFM9R-2_d5pq9_Hepo,9272
4
4
  ifstate/shell.py,sha256=7_JFpi4icr9MijynDzbb0v5mxhFsng6PCC4m3uQ255A,2177
5
5
  ifstate/vrrp.py,sha256=FJ9b1eJseTtZFfknHU-xV68Qz7cPrRrc5PTcjUVj-fY,5953
6
- ifstate-2.0.0rc1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
7
- libifstate/__init__.py,sha256=riz2m6o4yfab3Ta8pbX_Rfbk658N9yDkZWkjJKOiraA,33048
8
- libifstate/exception.py,sha256=5i59BZdl56J_sNJbyU9n6uHuUNJEyDOO4FJ-neDn9Ds,2608
6
+ ifstate-2.0.0rc3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
7
+ libifstate/__init__.py,sha256=iDV2VI11gPAIDrTXKqkWbo4B9bRcokiY3Fzyu440ayg,33194
8
+ libifstate/exception.py,sha256=jhLN46mqlyGNEz7lmc0K2d3SoZJtKzEVyPduPh22oC0,2280
9
9
  libifstate/log.py,sha256=XVoZdwdQoWsjuupFIuG6OP0OrBpXpx7oqyAaUhQ-nJk,4553
10
- libifstate/util.py,sha256=1CGVgaEj7L4At9FPWcDQLwSe027XSKoxFHIdkS5spSA,11354
10
+ libifstate/util.py,sha256=raYAaRy15JQNUbU3_4GchYV_PkaCvWR_8xjt7NTzMYw,11335
11
11
  libifstate/address/__init__.py,sha256=zIGM7UWXSvoijHMD06DfS2CDtiHpiJlqDgJG7Dl1IPE,3222
12
12
  libifstate/bpf/__init__.py,sha256=NVzaunTmJU2PbIQg9eWBMKpFgLh3EnD3ujNa7Yt6rNc,7699
13
13
  libifstate/bpf/ctypes.py,sha256=kLZJHZlba09Vc-tbsJAcKpDwdoNO2IjlYVLCopawHmA,4274
@@ -21,18 +21,18 @@ libifstate/link/physical.py,sha256=ectyXVchCHqWZR8qsjAD9667wjQbGW1OUKLQheTUFys,5
21
21
  libifstate/link/tun.py,sha256=SWkscSAgIk3DWFPWHo9Cmokhj88rO1_sR7Z0Qlg2xGA,993
22
22
  libifstate/link/veth.py,sha256=Sv5WZMMsefYFz9I0BQSZyKytCQYxv0vjwAnB7FYHR1A,2283
23
23
  libifstate/neighbour/__init__.py,sha256=FJJpbJvqnxvOEii6QDMYzW5jQDEbiEy71GQOEbqaS48,2463
24
- libifstate/netns/__init__.py,sha256=4DWFsgkT84foKoE0ZIbCIAqezDZzOBf8Ka1OAZS_T9E,10164
24
+ libifstate/netns/__init__.py,sha256=ptSIVld_BNXPE6f4SiIPVdYOE1sgprf5-ZhR-L_3BPE,10145
25
25
  libifstate/parser/__init__.py,sha256=byz1W0G7UewVc5FFie-ti3UZjGK3-75wHIaOeq0oySQ,88
26
26
  libifstate/parser/base.py,sha256=EV7uJYdVke3a2ghkUZ6ZeaIeVQAPVS4rFnYhebXeQm0,5932
27
27
  libifstate/parser/yaml.py,sha256=MC0kmwqt3P45z61fb_wfUqoj0iZyhFYkdPyr0UqMSZA,1415
28
- libifstate/routing/__init__.py,sha256=EvuS0GC5s7up92DYwSGhkohqhCQKPJpvs-alY4WAQws,25326
29
- libifstate/sysctl/__init__.py,sha256=EF52CdOOkVSUFR2t21A99KlG1-PjsD4qOiceQC4eI24,3074
28
+ libifstate/routing/__init__.py,sha256=O4lbaCJvLgx-iQUa0WDgRmSPR4AKvveqPgxxb4HwYQ4,25305
29
+ libifstate/sysctl/__init__.py,sha256=u1VJ1aPXeGCl3rwj3g0bDbz6k5k9YS5hQIsgFOBokpk,3202
30
30
  libifstate/tc/__init__.py,sha256=inPdampCOIr_4oKNB3awqMkW0Eh4fpPh9jvSba6sPVg,12092
31
- libifstate/wireguard/__init__.py,sha256=9v9szQdPtAQ7vx4-_adnh-82WdLtg9meeEjlV-uA-9o,6705
31
+ libifstate/wireguard/__init__.py,sha256=dXILLIuahBCkX2ONhre28SzJrVNksbjOICs-cSGGaRg,8625
32
32
  libifstate/xdp/__init__.py,sha256=X1xhEIGng7R5d5F4KsChykT2g6H-XBRWbWABijoYDQA,7208
33
- schema/2/ifstate.conf.schema.json,sha256=W47erPkAJi8BhBZJF_mLdZ1v7832W67BMGOx6KHzsw0,218580
34
- ifstate-2.0.0rc1.dist-info/METADATA,sha256=9EggrnXIHU69cZWFHFTcyHJvwYbpzTiOJoxtV4rgJ_4,1600
35
- ifstate-2.0.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- ifstate-2.0.0rc1.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
37
- ifstate-2.0.0rc1.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
38
- ifstate-2.0.0rc1.dist-info/RECORD,,
33
+ schema/2/ifstate.conf.schema.json,sha256=ukCafLPfHCXpk44u5RMMhWIh9JoIAt2j_3idysAVHaQ,218763
34
+ ifstate-2.0.0rc3.dist-info/METADATA,sha256=hdygdnfWvpggPIMQXwGSHPovg8Xt8VzsE-gAlPf1y-Y,1607
35
+ ifstate-2.0.0rc3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ ifstate-2.0.0rc3.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
37
+ ifstate-2.0.0rc3.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
38
+ ifstate-2.0.0rc3.dist-info/RECORD,,
libifstate/__init__.py CHANGED
@@ -49,7 +49,7 @@ import json
49
49
  import errno
50
50
  import logging
51
51
 
52
- __version__ = "2.0.0rc1"
52
+ __version__ = "2.0.0rc3"
53
53
 
54
54
  class IfState():
55
55
  def __init__(self):
@@ -638,7 +638,7 @@ class IfState():
638
638
  return {**root_config}
639
639
 
640
640
  def _identify_netns(self, netns):
641
- ifs_links = []
641
+ ifs_links = {}
642
642
  for ipr_link in netns.ipr.get_links():
643
643
  name = ipr_link.get_attr('IFLA_IFNAME')
644
644
  # skip links on ignore list
@@ -653,7 +653,6 @@ class IfState():
653
653
  continue
654
654
 
655
655
  ifs_link = {
656
- 'name': name,
657
656
  'identify': {
658
657
  },
659
658
  }
@@ -663,14 +662,14 @@ class IfState():
663
662
  if value is not None:
664
663
  ifs_link['identify'][attr] = value
665
664
 
666
- ifs_links.append(ifs_link)
665
+ ifs_links[name] = ifs_link
667
666
 
668
667
  if ifs_links:
669
668
  return {**{'interfaces': ifs_links}}
670
669
  else:
671
670
  return None
672
671
 
673
- def show(self, showall=False):
672
+ def show(self, showall=False, show_secrets=False):
674
673
  if showall:
675
674
  defaults = deepcopy(Parser._default_ifstates)
676
675
  else:
@@ -680,26 +679,25 @@ class IfState():
680
679
  for ip in Parser._default_ifstates['parameters']['ignore']['ipaddr_builtin']:
681
680
  ipaddr_ignore.append(ip_network(ip))
682
681
 
683
- root_config = self._show_netns(self.root_netns, showall, ipaddr_ignore)
682
+ root_config = self._show_netns(self.root_netns, showall, show_secrets, ipaddr_ignore)
684
683
  netns_instances = get_netns_instances()
685
684
  if len(netns_instances) > 0:
686
685
  netns_configs = {}
687
686
  for netns in netns_instances:
688
- netns_configs[netns.netns] = self._show_netns(netns, showall, ipaddr_ignore)
687
+ netns_configs[netns.netns] = self._show_netns(netns, showall, show_secrets, ipaddr_ignore)
689
688
 
690
689
  return {**defaults, **root_config, 'namespaces': netns_configs}
691
690
 
692
691
 
693
692
  return {**defaults, **root_config}
694
693
 
695
- def _show_netns(self, netns, showall, ipaddr_ignore):
696
- ifs_links = []
694
+ def _show_netns(self, netns, showall, show_secrets, ipaddr_ignore):
695
+ ifs_links = {}
697
696
  for ipr_link in netns.ipr.get_links():
698
697
  name = ipr_link.get_attr('IFLA_IFNAME')
699
698
  # skip links on ignore list
700
699
  if name != 'lo' and not any(re.match(regex, name) for regex in Parser._default_ifstates['parameters']['ignore']['ifname_builtin']):
701
700
  ifs_link = {
702
- 'name': name,
703
701
  'addresses': [],
704
702
  'link': {
705
703
  'state': ipr_link['state'],
@@ -772,6 +770,9 @@ class IfState():
772
770
 
773
771
  brport.BRPort.show(netns.ipr, showall, ipr_link['index'], ifs_link)
774
772
 
773
+ if ifs_link['link']['kind'] == 'wireguard':
774
+ wireguard.WireGuard.show(netns, showall, show_secrets, name, ifs_link)
775
+
775
776
  if name == 'lo':
776
777
  if ifs_link['addresses'] == Parser._default_lo_link['addresses']:
777
778
  del(ifs_link['addresses'])
@@ -780,9 +781,9 @@ class IfState():
780
781
  del(ifs_link['link'])
781
782
 
782
783
  if len(ifs_link) > 1:
783
- ifs_links.append(ifs_link)
784
+ ifs_links['lo'] = ifs_link
784
785
  else:
785
- ifs_links.append(ifs_link)
786
+ ifs_links[name] = ifs_link
786
787
 
787
788
  routing = {
788
789
  'routes': Tables(netns).show_routes(Parser._default_ifstates['parameters']['ignore']['routes_builtin']),
libifstate/exception.py CHANGED
@@ -1,15 +1,7 @@
1
- from pyroute2.netlink.exceptions import NetlinkError
1
+ from pyroute2 import NetlinkError
2
2
  from libifstate.util import logger
3
3
 
4
- # pyroute2.minimal exceptions might be broken
5
- # => workaround for pyroute2 #845 #847
6
4
  netlinkerror_classes = (NetlinkError)
7
- try:
8
- from pr2modules.netlink.exceptions import NetlinkError as Pr2mNetlinkError
9
- netlinkerror_classes = (NetlinkError, Pr2mNetlinkError)
10
- except ModuleNotFoundError:
11
- # required for pyroute2 before 0.6.0
12
- pass
13
5
 
14
6
  class ExceptionCollector():
15
7
  def __init__(self, ifname):
@@ -5,7 +5,7 @@ import atexit
5
5
  from copy import deepcopy
6
6
  import logging
7
7
  import pyroute2
8
- from pyroute2.netlink.exceptions import NetlinkError
8
+ from pyroute2 import NetlinkError
9
9
  import re
10
10
  import secrets
11
11
  import shutil
@@ -202,7 +202,7 @@ class RTLookup():
202
202
  self.str2id = {}
203
203
  self.id2str = {}
204
204
 
205
- for basedir in ['/usr/share/iproute2', '/usr/lib/iproute2', '/etc/iproute2']:
205
+ for basedir in ['/usr/share/iproute2', '/etc/iproute2']:
206
206
  fn = os.path.join(basedir, name)
207
207
  try:
208
208
  with open(fn, 'r') as fp:
@@ -6,7 +6,13 @@ import os
6
6
 
7
7
  class Sysctl():
8
8
  def __init__(self, netns):
9
- self.sysctls = {}
9
+ self.sysctls = {
10
+ "all": {
11
+ "ipv6": {
12
+ "optimistic_dad": 1
13
+ }
14
+ }
15
+ }
10
16
  self.globals = {}
11
17
  self.netns = netns
12
18
 
libifstate/util.py CHANGED
@@ -3,7 +3,7 @@ from libifstate.log import logger, IfStateLogging
3
3
  import pyroute2
4
4
  from pyroute2 import IPRoute, IW, NetNS
5
5
 
6
- from pyroute2.netlink.exceptions import NetlinkError
6
+ from pyroute2 import NetlinkError
7
7
  from pyroute2.netlink.rtnl.tcmsg import tcmsg
8
8
  from pyroute2.netlink.rtnl import RTM_DELTFILTER, RTM_NEWNSID
9
9
  from pyroute2.netlink.rtnl.nsidmsg import nsidmsg
@@ -1,12 +1,14 @@
1
1
  from libifstate.util import logger, IfStateLogging
2
2
  from libifstate.exception import netlinkerror_classes, FeatureMissingError
3
- from wgnlpy import WireGuard as WG
4
- from ipaddress import ip_network
3
+ import wgnlpy
4
+ import ipaddress
5
5
  import collections
6
6
  from copy import deepcopy
7
7
  import pyroute2.netns
8
8
  import socket
9
9
 
10
+ SECRET_SETTINGS = ['private_key', 'preshared_key']
11
+
10
12
  class WireGuard():
11
13
  def __init__(self, netns, iface, wireguard):
12
14
  self.netns = netns
@@ -17,7 +19,7 @@ class WireGuard():
17
19
  pyroute2.netns.pushns(self.netns.netns)
18
20
 
19
21
  try:
20
- self.wg = WG()
22
+ self.wg = wgnlpy.WireGuard()
21
23
  finally:
22
24
  if self.netns.netns is not None:
23
25
  pyroute2.netns.popns()
@@ -28,7 +30,7 @@ class WireGuard():
28
30
  for i, peer in enumerate(self.wireguard['peers']):
29
31
  if 'allowedips' in peer:
30
32
  self.wireguard['peers'][i]['allowedips'] = set(
31
- [ip_network(x) for x in self.wireguard['peers'][i]['allowedips']])
33
+ [ipaddress.ip_network(x) for x in self.wireguard['peers'][i]['allowedips']])
32
34
 
33
35
  def __deepcopy__(self, memo):
34
36
  '''
@@ -43,7 +45,7 @@ class WireGuard():
43
45
  pyroute2.netns.pushns(self.netns.netns)
44
46
 
45
47
  try:
46
- setattr(result, k, WG())
48
+ setattr(result, k, wgnlpy.WireGuard())
47
49
  finally:
48
50
  if self.netns.netns is not None:
49
51
  pyroute2.netns.popns()
@@ -157,3 +159,57 @@ class WireGuard():
157
159
 
158
160
  del(opts['endpoint'])
159
161
  self.wg.set_peer(self.iface, public_key=public_key, **opts)
162
+
163
+ def show(netns, show_all, show_secrets, name, config):
164
+ if netns.netns is not None:
165
+ pyroute2.netns.pushns(self.netns.netns)
166
+
167
+ try:
168
+ wg = wgnlpy.WireGuard()
169
+ finally:
170
+ if netns.netns is not None:
171
+ pyroute2.netns.popns()
172
+
173
+ state = wg.get_interface(
174
+ name, spill_private_key=show_secrets, spill_preshared_keys=show_secrets)
175
+
176
+ config['wireguard'] = {
177
+ 'peers': {},
178
+ }
179
+
180
+ def _dump_value(value):
181
+ if isinstance(value, (ipaddress.IPv4Network, ipaddress.IPv6Network, wgnlpy.sockaddr_in.sockaddr_in)):
182
+ return str(value)
183
+ elif type(value) is list:
184
+ result = []
185
+ for v in value:
186
+ result.append(_dump_value(v))
187
+ return result
188
+ else:
189
+ return value
190
+
191
+ def _dump_values(cfg, key, value):
192
+ if show_all:
193
+ if value is None:
194
+ return
195
+ else:
196
+ if not value:
197
+ return
198
+
199
+ if key in SECRET_SETTINGS:
200
+ if show_secrets:
201
+ cfg[key] = str(value)
202
+ else:
203
+ cfg[key] = f"# VALUE IS HIDDEN - USE --show-secrets TO REVEAL"
204
+ else:
205
+ cfg[key] = _dump_value(value)
206
+
207
+ for key in ['private_key', 'listen_port', 'fwmark']:
208
+ value = getattr(state, key)
209
+ _dump_values(config['wireguard'], key, value)
210
+
211
+ for peer in state.peers:
212
+ config['wireguard']['peers'][str(peer)] = {}
213
+ for key in ['preshared_key', 'endpoint', 'persistent_keepalive_interval', 'allowedips']:
214
+ value = getattr(state.peers[peer], key)
215
+ _dump_values(config['wireguard']['peers'][str(peer)], key, value)
@@ -989,6 +989,7 @@
989
989
  "type": "integer"
990
990
  },
991
991
  "optimistic_dad": {
992
+ "description": "perform Optimistic Duplicate Address Detection (RFC 4429); *This option is enabled by default in ifstate!*",
992
993
  "type": "integer"
993
994
  },
994
995
  "proxy_ndp": {
@@ -1756,7 +1757,7 @@
1756
1757
  "additionalProperties": false,
1757
1758
  "properties": {
1758
1759
  "script": {
1759
- "description": "filename to be executed on interface configuration, the hook name will be used by default; relatives file are based on `/etc/needrestart/hooks`",
1760
+ "description": "filename to be executed on interface configuration: the hook name will be used by default; relatives file are based on `/etc/needrestart/hooks`",
1760
1761
  "type": "string",
1761
1762
  "minLength": 1
1762
1763
  },
@@ -1864,7 +1865,7 @@
1864
1865
  }
1865
1866
  },
1866
1867
  "interfaces": {
1867
- "description": "list of interface settings (link settings and ip addresses)",
1868
+ "description": "dictionary of interfaces related settings, the name of the interface needs to be specified as key",
1868
1869
  "type": "object",
1869
1870
  "additionalProperties": false,
1870
1871
  "patternProperties": {