ifstate 2.0.0rc1__py3-none-any.whl → 2.0.0rc2__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.0rc2
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,10 +1,10 @@
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
6
+ ifstate-2.0.0rc2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
7
+ libifstate/__init__.py,sha256=REX94ISXtdyY24_cc26Od5D2xGnz2U8dYNtRRMjRu1M,33194
8
8
  libifstate/exception.py,sha256=5i59BZdl56J_sNJbyU9n6uHuUNJEyDOO4FJ-neDn9Ds,2608
9
9
  libifstate/log.py,sha256=XVoZdwdQoWsjuupFIuG6OP0OrBpXpx7oqyAaUhQ-nJk,4553
10
10
  libifstate/util.py,sha256=1CGVgaEj7L4At9FPWcDQLwSe027XSKoxFHIdkS5spSA,11354
@@ -28,11 +28,11 @@ libifstate/parser/yaml.py,sha256=MC0kmwqt3P45z61fb_wfUqoj0iZyhFYkdPyr0UqMSZA,141
28
28
  libifstate/routing/__init__.py,sha256=EvuS0GC5s7up92DYwSGhkohqhCQKPJpvs-alY4WAQws,25326
29
29
  libifstate/sysctl/__init__.py,sha256=EF52CdOOkVSUFR2t21A99KlG1-PjsD4qOiceQC4eI24,3074
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=cpXqcZK_xNexwhz-1OqN1RQe21NaNVgF-adhXU6mv14,8797
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=_ltHBK8iTy8xAhJapQIMmUavlXbDCcOI3R2EhjrMWa0,218618
34
+ ifstate-2.0.0rc2.dist-info/METADATA,sha256=Hgol7xinIWq2lp6D7PNFpgrZ9_lnqBgspEko0tzIaK4,1607
35
+ ifstate-2.0.0rc2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ ifstate-2.0.0rc2.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
37
+ ifstate-2.0.0rc2.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
38
+ ifstate-2.0.0rc2.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.0rc2"
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']),
@@ -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,61 @@ 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
+ print("{} => {}".format(key, value))
210
+ _dump_values(config['wireguard'], key, value)
211
+
212
+ for peer in state.peers:
213
+ config['wireguard']['peers'][str(peer)] = {}
214
+ print(state.peers[peer].endpoint)
215
+ print(type(state.peers[peer].endpoint))
216
+ print("---")
217
+ for key in ['preshared_key', 'endpoint', 'persistent_keepalive_interval', 'allowedips']:
218
+ value = getattr(state.peers[peer], key)
219
+ _dump_values(config['wireguard']['peers'][str(peer)], key, value)
@@ -1756,7 +1756,7 @@
1756
1756
  "additionalProperties": false,
1757
1757
  "properties": {
1758
1758
  "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`",
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
1760
  "type": "string",
1761
1761
  "minLength": 1
1762
1762
  },
@@ -1864,7 +1864,7 @@
1864
1864
  }
1865
1865
  },
1866
1866
  "interfaces": {
1867
- "description": "list of interface settings (link settings and ip addresses)",
1867
+ "description": "dictionary of interfaces related settings, the name of the interface needs to be specified as key",
1868
1868
  "type": "object",
1869
1869
  "additionalProperties": false,
1870
1870
  "patternProperties": {