diff options
-rw-r--r-- | python/vyos/ifconfig/interface.py | 2 | ||||
-rw-r--r-- | python/vyos/ifconfig/macvlan.py | 3 | ||||
-rw-r--r-- | python/vyos/ifconfig/vxlan.py | 3 | ||||
-rw-r--r-- | python/vyos/ifconfig/wireguard.py | 5 | ||||
-rw-r--r-- | python/vyos/ifconfig/wireless.py | 3 | ||||
-rwxr-xr-x | src/op_mode/show_dhcp.py | 89 | ||||
-rwxr-xr-x | src/op_mode/show_dhcpv6.py | 74 | ||||
-rwxr-xr-x | src/op_mode/wireguard.py | 8 |
8 files changed, 114 insertions, 73 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 32ce1a80c..5b26f8bab 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -49,7 +49,7 @@ class Interface(Control): # WireGuard to modify their display behaviour OperationalClass = Operational - options = [] + options = ['debug', 'create',] required = [] default = { 'type': '', diff --git a/python/vyos/ifconfig/macvlan.py b/python/vyos/ifconfig/macvlan.py index 55b1a3e91..37228e57f 100644 --- a/python/vyos/ifconfig/macvlan.py +++ b/python/vyos/ifconfig/macvlan.py @@ -35,7 +35,8 @@ class MACVLANIf(Interface): 'prefixes': ['peth', ], }, } - options = Interface.options + ['source_interface', 'mode'] + options = Interface.options + \ + ['source_interface', 'mode'] def _create(self): cmd = 'ip link add {ifname} link {source_interface} type macvlan mode {mode}'.format( diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py index f47ae17cc..f9f2e38e9 100644 --- a/python/vyos/ifconfig/vxlan.py +++ b/python/vyos/ifconfig/vxlan.py @@ -59,7 +59,8 @@ class VXLANIf(Interface): 'bridgeable': True, } } - options = ['group', 'remote', 'src_interface', 'port', 'vni', 'src_address'] + options = Interface.options + \ + ['group', 'remote', 'src_interface', 'port', 'vni', 'src_address'] mapping = { 'ifname': 'add', diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py index ff945c9d0..fdf5d9347 100644 --- a/python/vyos/ifconfig/wireguard.py +++ b/python/vyos/ifconfig/wireguard.py @@ -165,8 +165,9 @@ class WireGuardIf(Interface): 'bridgeable': True, } } - options = ['port', 'private-key', 'pubkey', 'psk', - 'allowed-ips', 'fwmark', 'endpoint', 'keepalive'] + options = Interface.options + \ + ['port', 'private-key', 'pubkey', 'psk', + 'allowed-ips', 'fwmark', 'endpoint', 'keepalive'] """ Wireguard interface class, contains a comnfig dictionary since diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py index 946ae1642..3122ac0a3 100644 --- a/python/vyos/ifconfig/wireless.py +++ b/python/vyos/ifconfig/wireless.py @@ -38,7 +38,8 @@ class WiFiIf(Interface): 'bridgeable': True, } } - options = ['phy', 'op_mode'] + options = Interface.options + \ + ['phy', 'op_mode'] def _create(self): # all interfaces will be added in monitor mode diff --git a/src/op_mode/show_dhcp.py b/src/op_mode/show_dhcp.py index c49e604b7..fd23cd9f1 100755 --- a/src/op_mode/show_dhcp.py +++ b/src/op_mode/show_dhcp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018-2019 VyOS maintainers and contributors +# Copyright (C) 2018-2020 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -14,14 +14,14 @@ # 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 json -import argparse -import ipaddress -import tabulate -import sys -import collections -import os +# TODO: merge with show_dhcpv6.py + +from json import dumps +from argparse import ArgumentParser +from ipaddress import ip_address +from tabulate import tabulate +from sys import exit +from collections import OrderedDict from datetime import datetime from isc_dhcp_leases import Lease, IscDhcpLeases @@ -33,7 +33,7 @@ from vyos.util import call lease_file = "/config/dhcpd.leases" pool_key = "shared-networkname" -lease_display_fields = collections.OrderedDict() +lease_display_fields = OrderedDict() lease_display_fields['ip'] = 'IP address' lease_display_fields['hardware_address'] = 'Hardware address' lease_display_fields['state'] = 'State' @@ -102,7 +102,7 @@ def get_lease_data(lease): return data -def get_leases(leases, state, pool=None, sort='ip'): +def get_leases(config, leases, state, pool=None, sort='ip'): # get leases from file leases = IscDhcpLeases(lease_file).get() @@ -116,7 +116,7 @@ def get_leases(leases, state, pool=None, sort='ip'): leases = list(filter(lambda x: in_pool(x, pool), leases)) else: print("Pool {0} does not exist.".format(pool)) - sys.exit(0) + exit(0) # should maybe filter all state=active by lease.valid here? @@ -134,7 +134,7 @@ def get_leases(leases, state, pool=None, sort='ip'): # apply output/display sort if sort == 'ip': - leases = sorted(leases, key = lambda lease: int(ipaddress.ip_address(lease['ip']))) + leases = sorted(leases, key = lambda lease: int(ip_address(lease['ip']))) else: leases = sorted(leases, key = lambda lease: lease[sort]) @@ -148,7 +148,7 @@ def show_leases(leases): lease_list_params.append(l[k]) lease_list.append(lease_list_params) - output = tabulate.tabulate(lease_list, lease_display_fields.values()) + output = tabulate(lease_list, lease_display_fields.values()) print(output) @@ -161,18 +161,18 @@ def get_pool_size(config, pool): start = config.return_effective_value("service dhcp-server shared-network-name {0} subnet {1} range {2} start".format(pool, s, r)) stop = config.return_effective_value("service dhcp-server shared-network-name {0} subnet {1} range {2} stop".format(pool, s, r)) - size += int(ipaddress.ip_address(stop)) - int(ipaddress.ip_address(start)) + size += int(ip_address(stop)) - int(ip_address(start)) return size def show_pool_stats(stats): headers = ["Pool", "Size", "Leases", "Available", "Usage"] - output = tabulate.tabulate(stats, headers) + output = tabulate(stats, headers) print(output) if __name__ == '__main__': - parser = argparse.ArgumentParser() + parser = ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-l", "--leases", action="store_true", help="Show DHCP leases") @@ -180,27 +180,50 @@ if __name__ == '__main__': group.add_argument("--allowed", type=str, choices=["pool", "sort", "state"], help="Show allowed values for argument") parser.add_argument("-p", "--pool", type=str, help="Show lease for specific pool") - parser.add_argument("-S", "--sort", type=str, choices=lease_display_fields.keys(), default='ip', help="Sort by") - parser.add_argument("-t", "--state", type=str, nargs="+", choices=lease_valid_states, default="active", help="Lease state to show (can specify multiple with spaces)") + parser.add_argument("-S", "--sort", type=str, default='ip', help="Sort by") + parser.add_argument("-t", "--state", type=str, nargs="+", default=["active"], help="Lease state to show (can specify multiple with spaces)") parser.add_argument("-j", "--json", action="store_true", default=False, help="Produce JSON output") args = parser.parse_args() + conf = Config() + + if args.allowed == 'pool': + if conf.exists_effective('service dhcp-server'): + print(' '.join(conf.list_effective_nodes("service dhcp-server shared-network-name"))) + exit(0) + elif args.allowed == 'sort': + print(' '.join(lease_display_fields.keys())) + exit(0) + elif args.allowed == 'state': + print(' '.join(lease_valid_states)) + exit(0) + elif args.allowed: + parser.print_help() + exit(1) + + if args.sort not in lease_display_fields.keys(): + print(f'Invalid sort key, choose from: {list(lease_display_fields.keys())}') + exit(0) + + if not set(args.state) < set(lease_valid_states): + print(f'Invalid lease state, choose from: {lease_valid_states}') + exit(0) + # Do nothing if service is not configured - config = Config() - if not config.exists_effective('service dhcp-server'): + if not conf.exists_effective('service dhcp-server'): print("DHCP service is not configured.") - sys.exit(0) + exit(0) # if dhcp server is down, inactive leases may still be shown as active, so warn the user. if call('systemctl -q is-active isc-dhcp-server.service') != 0: print("WARNING: DHCP server is configured but not started. Data may be stale.") if args.leases: - leases = get_leases(lease_file, args.state, args.pool, args.sort) + leases = get_leases(conf, lease_file, args.state, args.pool, args.sort) if args.json: - print(json.dumps(leases, indent=4)) + print(dumps(leases, indent=4)) else: show_leases(leases) @@ -211,18 +234,15 @@ if __name__ == '__main__': if args.pool: pools = [args.pool] else: - pools = config.list_effective_nodes("service dhcp-server shared-network-name") + pools = conf.list_effective_nodes("service dhcp-server shared-network-name") # Get pool usage stats stats = [] for p in pools: - size = get_pool_size(config, p) + size = get_pool_size(conf, p) leases = len(get_leases(lease_file, state='active', pool=p)) - if size != 0: - use_percentage = round(leases / size * 100) - else: - use_percentage = 0 + use_percentage = round(leases / size * 100) if size != 0 else 0 if args.json: pool_stats = {"pool": p, "size": size, "leases": leases, @@ -234,15 +254,10 @@ if __name__ == '__main__': # Print stats if args.json: - print(json.dumps(stats, indent=4)) + print(dumps(stats, indent=4)) else: show_pool_stats(stats) - elif args.allowed == 'pool': - print(' '.join(config.list_effective_nodes("service dhcp-server shared-network-name"))) - elif args.allowed == 'sort': - print(' '.join(lease_display_fields.keys())) - elif args.allowed == 'state': - print(' '.join(lease_valid_states)) else: parser.print_help() + exit(1) diff --git a/src/op_mode/show_dhcpv6.py b/src/op_mode/show_dhcpv6.py index d686defc0..ac211fb0a 100755 --- a/src/op_mode/show_dhcpv6.py +++ b/src/op_mode/show_dhcpv6.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018-2019 VyOS maintainers and contributors +# Copyright (C) 2018-2020 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -14,14 +14,14 @@ # 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 json -import argparse -import ipaddress -import tabulate -import sys -import collections -import os +# TODO: merge with show_dhcp.py + +from json import dumps +from argparse import ArgumentParser +from ipaddress import ip_address +from tabulate import tabulate +from sys import exit +from collections import OrderedDict from datetime import datetime from isc_dhcp_leases import Lease, IscDhcpLeases @@ -32,7 +32,7 @@ from vyos.util import call lease_file = "/config/dhcpdv6.leases" pool_key = "shared-networkname" -lease_display_fields = collections.OrderedDict() +lease_display_fields = OrderedDict() lease_display_fields['ip'] = 'IPv6 address' lease_display_fields['state'] = 'State' lease_display_fields['last_comm'] = 'Last communication' @@ -108,7 +108,7 @@ def get_lease_data(lease): return data -def get_leases(leases, state, pool=None, sort='ip'): +def get_leases(config, leases, state, pool=None, sort='ip'): leases = IscDhcpLeases(lease_file).get() # filter leases by state @@ -121,7 +121,7 @@ def get_leases(leases, state, pool=None, sort='ip'): leases = list(filter(lambda x: in_pool(x, pool), leases)) else: print("Pool {0} does not exist.".format(pool)) - sys.exit(0) + exit(0) # should maybe filter all state=active by lease.valid here? @@ -139,7 +139,7 @@ def get_leases(leases, state, pool=None, sort='ip'): # apply output/display sort if sort == 'ip': - leases = sorted(leases, key = lambda k: int(ipaddress.ip_address(k['ip']))) + leases = sorted(leases, key = lambda k: int(ip_address(k['ip']))) else: leases = sorted(leases, key = lambda k: k[sort]) @@ -153,12 +153,12 @@ def show_leases(leases): lease_list_params.append(l[k]) lease_list.append(lease_list_params) - output = tabulate.tabulate(lease_list, lease_display_fields.values()) + output = tabulate(lease_list, lease_display_fields.values()) print(output) if __name__ == '__main__': - parser = argparse.ArgumentParser() + parser = ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-l", "--leases", action="store_true", help="Show DHCPv6 leases") @@ -166,36 +166,54 @@ if __name__ == '__main__': group.add_argument("--allowed", type=str, choices=["pool", "sort", "state"], help="Show allowed values for argument") parser.add_argument("-p", "--pool", type=str, help="Show lease for specific pool") - parser.add_argument("-S", "--sort", type=str, choices=lease_display_fields.keys(), default='ip', help="Sort by") - parser.add_argument("-t", "--state", type=str, nargs="+", choices=lease_valid_states, default="active", help="Lease state to show (can specify multiple with spaces)") + parser.add_argument("-S", "--sort", type=str, default='ip', help="Sort by") + parser.add_argument("-t", "--state", type=str, nargs="+", default=["active"], help="Lease state to show (can specify multiple with spaces)") parser.add_argument("-j", "--json", action="store_true", default=False, help="Produce JSON output") args = parser.parse_args() + conf = Config() + + if args.allowed == 'pool': + if conf.exists_effective('service dhcpv6-server'): + print(' '.join(conf.list_effective_nodes("service dhcpv6-server shared-network-name"))) + exit(0) + elif args.allowed == 'sort': + print(' '.join(lease_display_fields.keys())) + exit(0) + elif args.allowed == 'state': + print(' '.join(lease_valid_states)) + exit(0) + elif args.allowed: + parser.print_help() + exit(1) + + if args.sort not in lease_display_fields.keys(): + print(f'Invalid sort key, choose from: {list(lease_display_fields.keys())}') + exit(0) + + if not set(args.state) < set(lease_valid_states): + print(f'Invalid lease state, choose from: {lease_valid_states}') + exit(0) + # Do nothing if service is not configured - c = Config() - if not c.exists_effective('service dhcpv6-server'): + if not conf.exists_effective('service dhcpv6-server'): print("DHCPv6 service is not configured") - sys.exit(0) + exit(0) # if dhcp server is down, inactive leases may still be shown as active, so warn the user. if call('systemctl -q is-active isc-dhcp-server6.service') != 0: print("WARNING: DHCPv6 server is configured but not started. Data may be stale.") if args.leases: - leases = get_leases(lease_file, args.state, args.pool, args.sort) + leases = get_leases(conf, lease_file, args.state, args.pool, args.sort) if args.json: - print(json.dumps(leases, indent=4)) + print(dumps(leases, indent=4)) else: show_leases(leases) elif args.statistics: print("DHCPv6 statistics option is not available") - elif args.allowed == 'pool': - print(' '.join(c.list_effective_nodes("service dhcpv6-server shared-network-name"))) - elif args.allowed == 'sort': - print(' '.join(lease_display_fields.keys())) - elif args.allowed == 'state': - print(' '.join(lease_valid_states)) else: parser.print_help() + exit(1) diff --git a/src/op_mode/wireguard.py b/src/op_mode/wireguard.py index 297ba599d..15bf63e81 100755 --- a/src/op_mode/wireguard.py +++ b/src/op_mode/wireguard.py @@ -147,8 +147,12 @@ if __name__ == '__main__': if args.listkdir: list_key_dirs() if args.showinterface: - intf = WireGuardIf(args.showinterface, create=False, debug=False) - print(intf.operational.show_interface()) + try: + intf = WireGuardIf(args.showinterface, create=False, debug=False) + print(intf.operational.show_interface()) + # the interface does not exists + except Exception: + pass if args.delkdir: if args.location: del_key_dir(args.location) |