diff options
Diffstat (limited to 'src/op_mode')
-rwxr-xr-x | src/op_mode/bridge.py | 32 | ||||
-rwxr-xr-x | src/op_mode/dhcp.py | 88 | ||||
-rwxr-xr-x | src/op_mode/show_ntp.sh | 2 | ||||
-rwxr-xr-x | src/op_mode/webproxy_update_blacklist.sh | 9 |
4 files changed, 127 insertions, 4 deletions
diff --git a/src/op_mode/bridge.py b/src/op_mode/bridge.py index 5531c41d0..1834b9cc9 100755 --- a/src/op_mode/bridge.py +++ b/src/op_mode/bridge.py @@ -24,6 +24,7 @@ from tabulate import tabulate from vyos.utils.process import cmd from vyos.utils.process import rc_cmd +from vyos.utils.process import call from vyos.utils.dict import dict_search import vyos.opmode @@ -129,7 +130,8 @@ def _get_formatted_output_vlan(data): if vlan_entry.get('vlanEnd'): vlan_end = vlan_entry.get('vlanEnd') vlan = f'{vlan}-{vlan_end}' - flags = ', '.join(vlan_entry.get('flags')).lower() + flags_raw = vlan_entry.get('flags') + flags = ', '.join(flags_raw if isinstance(flags_raw,list) else "").lower() data_entries.append([interface, vlan, flags]) headers = ["Interface", "Vlan", "Flags"] @@ -164,6 +166,23 @@ def _get_formatted_output_mdb(data): output = tabulate(data_entries, headers) return output +def _get_bridge_detail(iface): + """Get interface detail statistics""" + return call(f'vtysh -c "show interface {iface}"') + +def _get_bridge_detail_nexthop_group(iface): + """Get interface detail nexthop_group statistics""" + return call(f'vtysh -c "show interface {iface} nexthop-group"') + +def _get_bridge_detail_nexthop_group_raw(iface): + out = cmd(f'vtysh -c "show interface {iface} nexthop-group"') + return out + +def _get_bridge_detail_raw(iface): + """Get interface detail json statistics""" + data = cmd(f'vtysh -c "show interface {iface} json"') + data_dict = json.loads(data) + return data_dict def show(raw: bool): bridge_data = _get_raw_data_summary() @@ -196,6 +215,17 @@ def show_mdb(raw: bool, interface: str): else: return _get_formatted_output_mdb(mdb_data) +def show_detail(raw: bool, nexthop_group: typing.Optional[bool], interface: str): + if raw: + if nexthop_group: + return _get_bridge_detail_nexthop_group_raw(interface) + else: + return _get_bridge_detail_raw(interface) + else: + if nexthop_group: + return _get_bridge_detail_nexthop_group(interface) + else: + return _get_bridge_detail(interface) if __name__ == '__main__': try: diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index 3e51e990b..20ef698bd 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -14,10 +14,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import os import sys import typing from datetime import datetime +from glob import glob from ipaddress import ip_address from isc_dhcp_leases import IscDhcpLeases from tabulate import tabulate @@ -27,10 +29,13 @@ import vyos.opmode from vyos.base import Warning from vyos.configquery import ConfigTreeQuery -from vyos.utils.process import cmd from vyos.utils.dict import dict_search +from vyos.utils.file import read_file +from vyos.utils.process import cmd from vyos.utils.process import is_systemd_service_running +time_string = "%a %b %d %H:%M:%S %Z %Y" + config = ConfigTreeQuery() lease_valid_states = ['all', 'active', 'free', 'expired', 'released', 'abandoned', 'reset', 'backup'] sort_valid_inet = ['end', 'mac', 'hostname', 'ip', 'pool', 'remaining', 'start', 'state'] @@ -287,6 +292,87 @@ def show_server_leases(raw: bool, family: ArgFamily, pool: typing.Optional[str], return _get_formatted_server_leases(lease_data, family=family) +def _get_raw_client_leases(family='inet', interface=None): + from time import mktime + from datetime import datetime + + lease_dir = '/var/lib/dhcp' + lease_files = [] + lease_data = [] + + if interface: + tmp = f'{lease_dir}/dhclient_{interface}.lease' + if os.path.exists(tmp): + lease_files.append(tmp) + else: + # All DHCP leases + lease_files = glob(f'{lease_dir}/dhclient_*.lease') + + for lease in lease_files: + tmp = {} + with open(lease, 'r') as f: + for line in f.readlines(): + line = line.rstrip() + if 'last_update' not in tmp: + # ISC dhcp client contains least_update timestamp in human readable + # format this makes less sense for an API and also the expiry + # timestamp is provided in UNIX time. Convert string (e.g. Sun Jul + # 30 18:13:44 CEST 2023) to UNIX time (1690733624) + tmp.update({'last_update' : int(mktime(datetime.strptime(line, time_string).timetuple()))}) + continue + + k, v = line.split('=') + tmp.update({k : v.replace("'", "")}) + + lease_data.append(tmp) + + return lease_data + +def _get_formatted_client_leases(lease_data, family): + from time import localtime + from time import strftime + + from vyos.validate import is_intf_addr_assigned + + data_entries = [] + for lease in lease_data: + data_entries.append(["Interface", lease['interface']]) + if 'new_ip_address' in lease: + tmp = '[Active]' if is_intf_addr_assigned(lease['interface'], lease['new_ip_address']) else '[Inactive]' + data_entries.append(["IP address", lease['new_ip_address'], tmp]) + if 'new_subnet_mask' in lease: + data_entries.append(["Subnet Mask", lease['new_subnet_mask']]) + if 'new_domain_name' in lease: + data_entries.append(["Domain Name", lease['new_domain_name']]) + if 'new_routers' in lease: + data_entries.append(["Router", lease['new_routers']]) + if 'new_domain_name_servers' in lease: + data_entries.append(["Name Server", lease['new_domain_name_servers']]) + if 'new_dhcp_server_identifier' in lease: + data_entries.append(["DHCP Server", lease['new_dhcp_server_identifier']]) + if 'new_dhcp_lease_time' in lease: + data_entries.append(["DHCP Server", lease['new_dhcp_lease_time']]) + if 'last_update' in lease: + tmp = strftime(time_string, localtime(int(lease['last_update']))) + data_entries.append(["Last Update", tmp]) + if 'new_expiry' in lease: + tmp = strftime(time_string, localtime(int(lease['new_expiry']))) + data_entries.append(["Expiry", tmp]) + + # Add empty marker + data_entries.append(['']) + + output = tabulate(data_entries, tablefmt='plain') + + return output + +def show_client_leases(raw: bool, family: ArgFamily, interface: typing.Optional[str]): + lease_data = _get_raw_client_leases(family=family, interface=interface) + if raw: + return lease_data + else: + return _get_formatted_client_leases(lease_data, family=family) + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) diff --git a/src/op_mode/show_ntp.sh b/src/op_mode/show_ntp.sh index 85f8eda15..4b59b801e 100755 --- a/src/op_mode/show_ntp.sh +++ b/src/op_mode/show_ntp.sh @@ -18,7 +18,7 @@ if ! ps -C chronyd &>/dev/null; then fi PID=$(pgrep chronyd | head -n1) -VRF_NAME=$(ip vrf identify ) +VRF_NAME=$(ip vrf identify ${PID}) if [ ! -z ${VRF_NAME} ]; then VRF_CMD="sudo ip vrf exec ${VRF_NAME}" diff --git a/src/op_mode/webproxy_update_blacklist.sh b/src/op_mode/webproxy_update_blacklist.sh index 4fb9a54c6..05ea86f9e 100755 --- a/src/op_mode/webproxy_update_blacklist.sh +++ b/src/op_mode/webproxy_update_blacklist.sh @@ -45,6 +45,9 @@ do --auto-update-blacklist) auto="yes" ;; + --vrf) + vrf="yes" + ;; (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; (*) break;; esac @@ -76,7 +79,11 @@ fi if [[ -n $update ]] && [[ $update -eq "yes" ]]; then tmp_blacklists='/tmp/blacklists.gz' - curl -o $tmp_blacklists $blacklist_url + if [[ -n $vrf ]] && [[ $vrf -eq "yes" ]]; then + sudo ip vrf exec $1 curl -o $tmp_blacklists $blacklist_url + else + curl -o $tmp_blacklists $blacklist_url + fi if [ $? -ne 0 ]; then echo "Unable to download [$blacklist_url]!" exit 1 |