ifstate 2.0.0rc4__py3-none-any.whl → 2.0.0rc5__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
@@ -130,7 +130,7 @@ def main():
130
130
  group = parser.add_mutually_exclusive_group()
131
131
  parser.add_argument('--version', action='version',
132
132
  version='%(prog)s {version}'.format(version=__version__))
133
- group.add_argument("-v", "--verbose", action="store_true",
133
+ group.add_argument("-v", "--verbose", action="count", default=0,
134
134
  help="be more verbose")
135
135
  group.add_argument("-q", "--quiet", action="store_true",
136
136
  help="be more quiet, print only warnings and errors")
@@ -139,7 +139,7 @@ def main():
139
139
  parser.add_argument("-S", "--show-secrets", action="store_true",
140
140
  help="show secrets when dumping config")
141
141
  parser.add_argument("-c", "--config", type=str,
142
- default="/etc/ifstate/config.yml", help="configuration YaML filename")
142
+ default="/etc/ifstate/ifstate.yaml", help="configuration YaML filename")
143
143
  subparsers = parser.add_subparsers(
144
144
  dest='action', required=True, help="specifies the action to perform")
145
145
 
@@ -166,10 +166,10 @@ def main():
166
166
  "name", type=str, help="name of the vrrp group or instance")
167
167
 
168
168
  args = parser.parse_args()
169
- if args.verbose:
169
+ if args.verbose > 0:
170
170
  lvl = logging.DEBUG
171
171
  elif args.quiet:
172
- lvl = logging.ERROR
172
+ lvl = logging.WARNING
173
173
  else:
174
174
  lvl = logging.INFO
175
175
 
@@ -182,7 +182,7 @@ def main():
182
182
  shell()
183
183
  exit(0)
184
184
 
185
- ifslog = IfStateLogging(lvl, action=args.action)
185
+ ifslog = IfStateLogging(lvl, args.verbose > 1, action=args.action)
186
186
 
187
187
  if args.action in [Actions.IDENTIFY, Actions.SHOW, Actions.SHOWALL]:
188
188
  # preserve dict order on python 3.7+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ifstate
3
- Version: 2.0.0rc4
3
+ Version: 2.0.0rc5
4
4
  Summary: Manage host interface settings in a declarative manner
5
5
  Home-page: https://ifstate.net/
6
6
  Author: Thomas Liske
@@ -1,22 +1,23 @@
1
- hooks/wrapper.sh,sha256=ipCmvcadJbXTT6oUR7BIhT5uglITnHfiAdm44vydZuw,1101
2
1
  ifstate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- ifstate/ifstate.py,sha256=ioiM9xgVWdrpTpK_UxJdaJFlmpFM9R-2_d5pq9_Hepo,9272
2
+ ifstate/ifstate.py,sha256=hmc_AWohcYVzWHU7vooWey0HDqZQOs6Yq8YZAMZBCgo,9304
4
3
  ifstate/shell.py,sha256=7_JFpi4icr9MijynDzbb0v5mxhFsng6PCC4m3uQ255A,2177
5
4
  ifstate/vrrp.py,sha256=FJ9b1eJseTtZFfknHU-xV68Qz7cPrRrc5PTcjUVj-fY,5953
6
- ifstate-2.0.0rc4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
7
- libifstate/__init__.py,sha256=twHhETYpEtBxqnWKOGYwOyOV1Ahgqi_ybAk2rodpre4,33845
5
+ ifstate-2.0.0rc5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
6
+ libifstate/__init__.py,sha256=43OxRa35lKLNpMIR3_jmDICD_R0DUZqpAvasIzfatew,34059
8
7
  libifstate/exception.py,sha256=NmKqD9O8dRWBgO__Pt0_wGSR5GWZ1RHXZZEUI3ArVLo,2360
9
- libifstate/log.py,sha256=XVoZdwdQoWsjuupFIuG6OP0OrBpXpx7oqyAaUhQ-nJk,4553
10
- libifstate/util.py,sha256=raYAaRy15JQNUbU3_4GchYV_PkaCvWR_8xjt7NTzMYw,11335
8
+ libifstate/log.py,sha256=rG0ISWyeGGlC_jRREoSpkdySc5EmyhOQIgSfvRqlaZA,4651
9
+ libifstate/util.py,sha256=DqYyFzNqRceJxxGqTg94gT8OTHQQ2gZxQOo5Gzx6-6s,11555
11
10
  libifstate/address/__init__.py,sha256=SobrZ9e2ItrmEidnKPBhUMitRDdTEajbkU9Rkmtx-gQ,3165
12
11
  libifstate/bpf/__init__.py,sha256=NVzaunTmJU2PbIQg9eWBMKpFgLh3EnD3ujNa7Yt6rNc,7699
13
12
  libifstate/bpf/ctypes.py,sha256=kLZJHZlba09Vc-tbsJAcKpDwdoNO2IjlYVLCopawHmA,4274
14
13
  libifstate/bpf/map.py,sha256=cLHNMvRBDNW2yVCEf3z242_oRdU0HqVbFEYVkKXng0w,10818
15
14
  libifstate/brport/__init__.py,sha256=NzdA8F4hr2se1bXKNnyKZbvOFlCWBq_cdjwsL1H0Y-o,2964
16
15
  libifstate/fdb/__init__.py,sha256=9dpL5n8ct3CaA-z8I6ZEkD3yL6yWJQeq3fpIe9pc2zw,6486
17
- libifstate/hook/__init__.py,sha256=OPUyhrr-eT1UNp8ryYoJyvi4WWqL2Ql33szir673Td4,7379
18
- libifstate/link/__init__.py,sha256=QZggoC-bIscqwVedqVycaSqS1CmXB3Bx3m2FZei8Q_4,115
16
+ libifstate/hook/__init__.py,sha256=012SIm1aULlXG4SoOYFV46u9k-4pPgtIENaUlRWPpe8,7375
17
+ libifstate/hook/wrapper.sh,sha256=ipCmvcadJbXTT6oUR7BIhT5uglITnHfiAdm44vydZuw,1101
18
+ libifstate/link/__init__.py,sha256=epVw6jY8exNeJZUmmUas91yJoeupfgIY7rthq7SGIIw,142
19
19
  libifstate/link/base.py,sha256=zsitL1kSPLvjzZqyUIyEoCVlE_dhX2z5acNL1iZ2EAE,34508
20
+ libifstate/link/dsa.py,sha256=zOdatHE9_TLVVqP2H87V3d_M6Y3fRke2FqHj0u_Su2c,260
20
21
  libifstate/link/physical.py,sha256=IG1OXG2q25QmvhxEDhyT-bf7guwIyXl0OzSJgQOqXzY,613
21
22
  libifstate/link/tun.py,sha256=Rzn3ysE0cVuQGi3naxs9QXYBrLwVQTaVrFv2dtR1D60,1012
22
23
  libifstate/link/veth.py,sha256=Sv5WZMMsefYFz9I0BQSZyKytCQYxv0vjwAnB7FYHR1A,2283
@@ -26,13 +27,13 @@ libifstate/parser/__init__.py,sha256=uzv5U-6RPy-SSIyxR6H_F0SvAOQQF8x5ygErpUhsa7Y
26
27
  libifstate/parser/base.py,sha256=PPUXWzZ1iMWseZzeV2uWmFIInmi8xxGDgul6afmVjd4,6584
27
28
  libifstate/parser/yaml.py,sha256=MC0kmwqt3P45z61fb_wfUqoj0iZyhFYkdPyr0UqMSZA,1415
28
29
  libifstate/routing/__init__.py,sha256=O4lbaCJvLgx-iQUa0WDgRmSPR4AKvveqPgxxb4HwYQ4,25305
30
+ libifstate/schema/2/ifstate.conf.schema.json,sha256=hVf0fduVV09uw3ZphWWwGpeQ7nL5z1aLTHUEemn34wc,221185
29
31
  libifstate/sysctl/__init__.py,sha256=VLzz1YcNEclRMVvwZuJgkYxPTjErl-7-rwSOKiEG6_M,3544
30
32
  libifstate/tc/__init__.py,sha256=T8LEBxiHZH4sayPn9lK5hK8eB8dskuw6-kw81W_aMWU,12097
31
- libifstate/wireguard/__init__.py,sha256=dXILLIuahBCkX2ONhre28SzJrVNksbjOICs-cSGGaRg,8625
33
+ libifstate/wireguard/__init__.py,sha256=VSn3PzQXwZeRV1qf5nOc_RbeePQlXu8FUh2Lg356-ZA,8869
32
34
  libifstate/xdp/__init__.py,sha256=X1xhEIGng7R5d5F4KsChykT2g6H-XBRWbWABijoYDQA,7208
33
- schema/2/ifstate.conf.schema.json,sha256=ukCafLPfHCXpk44u5RMMhWIh9JoIAt2j_3idysAVHaQ,218763
34
- ifstate-2.0.0rc4.dist-info/METADATA,sha256=l7BY5YH_qpCDHZnyMRjS8sa9p4dZn-TyxaVPqCtBpbM,1607
35
- ifstate-2.0.0rc4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- ifstate-2.0.0rc4.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
37
- ifstate-2.0.0rc4.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
38
- ifstate-2.0.0rc4.dist-info/RECORD,,
35
+ ifstate-2.0.0rc5.dist-info/METADATA,sha256=u2yC0kTPo9uQx80fkxj5vp6XnKJh9-EWovvA8ShO9ZA,1607
36
+ ifstate-2.0.0rc5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ ifstate-2.0.0rc5.dist-info/entry_points.txt,sha256=HF6jX7Uu_nF1Ly-J9uEPeiRapOxnM6LuHsb2y6Mt-k4,52
38
+ ifstate-2.0.0rc5.dist-info/top_level.txt,sha256=A7peI7aKBaM69fsiSPvMbL3rzTKZZr5qDxKC-pHMGdE,19
39
+ ifstate-2.0.0rc5.dist-info/RECORD,,
libifstate/__init__.py CHANGED
@@ -42,7 +42,7 @@ except ModuleNotFoundError:
42
42
  pass
43
43
 
44
44
  from libifstate.netns import NetNameSpace, prepare_netns, LinkRegistry, get_netns_instances
45
- from libifstate.util import logger, root_iw, IfStateLogging, LinkDependency, IDENTIFY_LOOKUPS
45
+ from libifstate.util import logger, root_iw, kind_has_identify, IfStateLogging, LinkDependency, IDENTIFY_LOOKUPS
46
46
  from libifstate.exception import FeatureMissingError, LinkCircularLinked, LinkNoConfigFound, ParserValidationError
47
47
  from ipaddress import ip_network, ip_interface
48
48
  from copy import deepcopy
@@ -54,7 +54,7 @@ import json
54
54
  import errno
55
55
  import logging
56
56
 
57
- __version__ = "2.0.0rc4"
57
+ __version__ = "2.0.0rc5"
58
58
 
59
59
  class IfState():
60
60
  def __init__(self):
@@ -659,7 +659,7 @@ class IfState():
659
659
  else:
660
660
  kind = info.get_attr('IFLA_INFO_KIND')
661
661
 
662
- if kind is not None:
662
+ if not kind_has_identify(kind):
663
663
  continue
664
664
 
665
665
  ifs_link = {
@@ -725,12 +725,16 @@ class IfState():
725
725
  if not any(ip in net for net in ipaddr_ignore):
726
726
  ifs_link['addresses'].append(ip.with_prefixlen)
727
727
 
728
+ # drop empty ip addresses list, they are cleaned up by default
729
+ if not ifs_link['addresses']:
730
+ del(ifs_link['addresses'])
731
+
728
732
  info = ipr_link.get_attr('IFLA_LINKINFO')
729
733
  if info is None:
730
734
  kind = None
731
735
  else:
732
736
  kind = info.get_attr('IFLA_INFO_KIND')
733
- if kind is not None:
737
+ if not kind_has_identify(kind):
734
738
  ifs_link['link']['kind'] = kind
735
739
 
736
740
  data = info.get_attr('IFLA_INFO_DATA')
@@ -13,7 +13,7 @@ import tempfile
13
13
 
14
14
 
15
15
  HOOK_DIR = '/etc/ifstate/hooks'
16
- HOOK_WRAPPER = Template(pkgutil.get_data("libifstate", "../hooks/wrapper.sh").decode("utf-8"))
16
+ HOOK_WRAPPER = Template(pkgutil.get_data("libifstate", "hook/wrapper.sh").decode("utf-8"))
17
17
 
18
18
  RC_OK = 0
19
19
  RC_ERROR = 1
@@ -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
libifstate/link/dsa.py ADDED
@@ -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
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
@@ -2851,6 +2851,49 @@
2851
2851
  }
2852
2852
  }
2853
2853
  },
2854
+ {
2855
+ "description": "Distributed Switch Architecture (DSA) user interface",
2856
+ "required": [
2857
+ "kind"
2858
+ ],
2859
+ "additionalProperties": false,
2860
+ "properties": {
2861
+ "kind": {
2862
+ "type": "string",
2863
+ "description": "link type",
2864
+ "enum": [
2865
+ "dsa"
2866
+ ]
2867
+ },
2868
+ "address": {
2869
+ "$ref": "#/$defs/iface-link_address"
2870
+ },
2871
+ "group": {
2872
+ "$ref": "#/$defs/iface-link_group"
2873
+ },
2874
+ "state": {
2875
+ "$ref": "#/$defs/iface-link_state"
2876
+ },
2877
+ "master": {
2878
+ "$ref": "#/$defs/iface-link_master"
2879
+ },
2880
+ "mtu": {
2881
+ "$ref": "#/$defs/iface-link_mtu"
2882
+ },
2883
+ "txqlen": {
2884
+ "$ref": "#/$defs/iface-link_txqlen"
2885
+ },
2886
+ "ifalias": {
2887
+ "$ref": "#/$defs/iface-link_ifalias"
2888
+ },
2889
+ "link": {
2890
+ "$ref": "#/$defs/iface-link_link"
2891
+ },
2892
+ "link_netns": {
2893
+ "$ref": "#/$defs/iface-link_link-netns"
2894
+ }
2895
+ }
2896
+ },
2854
2897
  {
2855
2898
  "description": "Physical network interface",
2856
2899
  "required": [
libifstate/util.py CHANGED
@@ -128,7 +128,7 @@ def get_netns_run_dir(function, netns, *args):
128
128
 
129
129
  def dump_yaml_file(fn, obj, opener=None):
130
130
  """
131
- Dump obj to a YaML file, create directories if needed and catch file
131
+ Dump obj to a YAML file, create directories if needed and catch file
132
132
  I/O errors.
133
133
  """
134
134
  try:
@@ -144,7 +144,7 @@ def dump_yaml_file(fn, obj, opener=None):
144
144
 
145
145
  def slurp_yaml_file(fn, default=None):
146
146
  """
147
- Read the content of a YaML file, returns *default* if the file could not be
147
+ Read the content of a YAML file, returns *default* if the file could not be
148
148
  found, read or parsed.
149
149
  """
150
150
  try:
@@ -157,6 +157,13 @@ def slurp_yaml_file(fn, default=None):
157
157
 
158
158
  return default
159
159
 
160
+ def kind_has_identify(kind):
161
+ """
162
+ Return True if the interface kind can be identified by some unique
163
+ properties. These are all types of physical interfaces.
164
+ """
165
+ return kind is None or kind in ['dsa']
166
+
160
167
  class IPRouteExt(IPRoute):
161
168
  def __init__(self, *args, **kwargs):
162
169
  super().__init__(*args, **kwargs)
@@ -4,7 +4,9 @@ import wgnlpy
4
4
  import ipaddress
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
  SECRET_SETTINGS = ['private_key', 'preshared_key']
@@ -58,6 +60,9 @@ class WireGuard():
58
60
  try:
59
61
  state = self.wg.get_interface(
60
62
  self.iface, spill_private_key=True, spill_preshared_keys=True)
63
+ except NetlinkError as err:
64
+ logger.warning('query wireguard details failed: {}'.format(os.strerror(err.code)), extra={'iface': self.iface, 'netns': self.netns})
65
+ return
61
66
  except TypeError as err:
62
67
  # wgnlpy 0.1.5 can triggger a TypeError exception
63
68
  # if the WGPEER_A_LAST_HANDSHAKE_TIME NLA does not
File without changes