summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/config_mgmt.py27
-rw-r--r--python/vyos/util.py16
-rw-r--r--python/vyos/utils/network.py8
-rw-r--r--python/vyos/utils/system.py82
-rw-r--r--python/vyos/xml_ref/definition.py7
5 files changed, 111 insertions, 29 deletions
diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py
index 26114149f..e1870aa0a 100644
--- a/python/vyos/config_mgmt.py
+++ b/python/vyos/config_mgmt.py
@@ -21,6 +21,8 @@ import logging
from typing import Optional, Tuple, Union
from filecmp import cmp
from datetime import datetime
+from textwrap import dedent
+from pathlib import Path
from tabulate import tabulate
from vyos.config import Config
@@ -456,19 +458,18 @@ Proceed ?'''
return ConfigTree(c)
def _add_logrotate_conf(self):
- conf = f"""{archive_config_file} {{
- su root vyattacfg
- rotate {self.max_revisions}
- start 0
- compress
- copy
-}}"""
- mask = os.umask(0o133)
-
- with open(logrotate_conf, 'w') as f:
- f.write(conf)
-
- os.umask(mask)
+ conf: str = dedent(f"""\
+ {archive_config_file} {{
+ su root vyattacfg
+ rotate {self.max_revisions}
+ start 0
+ compress
+ copy
+ }}
+ """)
+ conf_file = Path(logrotate_conf)
+ conf_file.write_text(conf)
+ conf_file.chmod(0o644)
def _archive_active_config(self) -> bool:
mask = os.umask(0o113)
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 33da5da40..ed651fdc3 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -913,7 +913,7 @@ def get_interface_config(interface):
if not os.path.exists(f'/sys/class/net/{interface}'):
return None
from json import loads
- tmp = loads(cmd(f'ip -d -j link show {interface}'))[0]
+ tmp = loads(cmd(f'ip --detail --json link show dev {interface}'))[0]
return tmp
def get_interface_address(interface):
@@ -923,7 +923,7 @@ def get_interface_address(interface):
if not os.path.exists(f'/sys/class/net/{interface}'):
return None
from json import loads
- tmp = loads(cmd(f'ip -d -j addr show {interface}'))[0]
+ tmp = loads(cmd(f'ip --detail --json addr show dev {interface}'))[0]
return tmp
def get_interface_namespace(iface):
@@ -937,17 +937,17 @@ def get_interface_namespace(iface):
return None
for ns in tmp:
- namespace = f'{ns["name"]}'
+ netns = f'{ns["name"]}'
# Search interface in each netns
- data = loads(cmd(f'ip netns exec {namespace} ip -j link show'))
- for compare in data:
- if iface == compare["ifname"]:
- return namespace
+ data = loads(cmd(f'ip netns exec {netns} ip --json link show'))
+ for tmp in data:
+ if iface == tmp["ifname"]:
+ return netns
def get_all_vrfs():
""" Return a dictionary of all system wide known VRF instances """
from json import loads
- tmp = loads(cmd('ip -j vrf list'))
+ tmp = loads(cmd('ip --json vrf list'))
# Result is of type [{"name":"red","table":1000},{"name":"blue","table":2000}]
# so we will re-arrange it to a more nicer representation:
# {'red': {'table': 1000}, 'blue': {'table': 2000}}
diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py
index 72b7ca6da..7386d44f0 100644
--- a/python/vyos/utils/network.py
+++ b/python/vyos/utils/network.py
@@ -15,7 +15,6 @@
import os
-
def get_protocol_by_name(protocol_name):
"""Get protocol number by protocol name
@@ -28,3 +27,10 @@ def get_protocol_by_name(protocol_name):
return protocol_number
except socket.error:
return protocol_name
+
+def interface_exists_in_netns(interface_name, netns):
+ from vyos.util import rc_cmd
+ rc, out = rc_cmd(f'ip netns exec {netns} ip link show dev {interface_name}')
+ if rc == 0:
+ return True
+ return False
diff --git a/python/vyos/utils/system.py b/python/vyos/utils/system.py
new file mode 100644
index 000000000..7102d5985
--- /dev/null
+++ b/python/vyos/utils/system.py
@@ -0,0 +1,82 @@
+# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+from subprocess import run
+
+
+def sysctl_read(name: str) -> str:
+ """Read and return current value of sysctl() option
+
+ Args:
+ name (str): sysctl key name
+
+ Returns:
+ str: sysctl key value
+ """
+ tmp = run(['sysctl', '-nb', name], capture_output=True)
+ return tmp.stdout.decode()
+
+
+def sysctl_write(name: str, value: str | int) -> bool:
+ """Change value via sysctl()
+
+ Args:
+ name (str): sysctl key name
+ value (str | int): sysctl key value
+
+ Returns:
+ bool: True if changed, False otherwise
+ """
+ # convert other types to string before comparison
+ if not isinstance(value, str):
+ value = str(value)
+ # do not change anything if a value is already configured
+ if sysctl_read(name) == value:
+ return True
+ # return False if sysctl call failed
+ if run(['sysctl', '-wq', f'{name}={value}']).returncode != 0:
+ return False
+ # compare old and new values
+ # sysctl may apply value, but its actual value will be
+ # different from requested
+ if sysctl_read(name) == value:
+ return True
+ # False in other cases
+ return False
+
+
+def sysctl_apply(sysctl_dict: dict[str, str], revert: bool = True) -> bool:
+ """Apply sysctl values.
+
+ Args:
+ sysctl_dict (dict[str, str]): dictionary with sysctl keys with values
+ revert (bool, optional): Revert to original values if new were not
+ applied. Defaults to True.
+
+ Returns:
+ bool: True if all params configured properly, False in other cases
+ """
+ # get current values
+ sysctl_original: dict[str, str] = {}
+ for key_name in sysctl_dict.keys():
+ sysctl_original[key_name] = sysctl_read(key_name)
+ # apply new values and revert in case one of them was not applied
+ for key_name, value in sysctl_dict.items():
+ if not sysctl_write(key_name, value):
+ if revert:
+ sysctl_apply(sysctl_original, revert=False)
+ return False
+ # everything applied
+ return True
diff --git a/python/vyos/xml_ref/definition.py b/python/vyos/xml_ref/definition.py
index 33a49ca69..7634773d6 100644
--- a/python/vyos/xml_ref/definition.py
+++ b/python/vyos/xml_ref/definition.py
@@ -123,9 +123,6 @@ class Xml:
return d
def multi_to_list(self, rpath: list, conf: dict) -> dict:
- if rpath and rpath[-1] in list(conf):
- raise ValueError('rpath should be disjoint from conf keys')
-
res: Any = {}
for k in list(conf):
@@ -246,10 +243,6 @@ class Xml:
if not conf:
return self.get_defaults(path, get_first_key=get_first_key,
recursive=recursive)
- if path and path[-1] in list(conf):
- conf = conf[path[-1]]
- conf = {} if not isinstance(conf, dict) else conf
-
if not self._well_defined(path, conf):
print('path to config dict does not define full config paths')
return {}