summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraapostoliuk <a.apostoliuk@vyos.io>2022-10-18 15:27:27 +0300
committeraapostoliuk <a.apostoliuk@vyos.io>2022-11-02 15:04:02 +0200
commit2e83c1eb53e9378873eb2192f85e717df84b9cd0 (patch)
treec9b5f241f8b24124c6da876223e648c1815234d5
parentc8dbd6ce6cd466bd7903987e58b885f0e92d1691 (diff)
downloadvyos-1x-2e83c1eb53e9378873eb2192f85e717df84b9cd0.tar.gz
vyos-1x-2e83c1eb53e9378873eb2192f85e717df84b9cd0.zip
T4496: Added lists of values in the help of op-mode ping command
Added list of possible VRFs in the help of the ping command Added list of possible interfaces in the help of the ping command Changed, if an option was selected before in the ping command, it does not appear in possible completion. Added error message when an unexpected option was selected.
-rwxr-xr-xsrc/op_mode/ping.py90
1 files changed, 73 insertions, 17 deletions
diff --git a/src/op_mode/ping.py b/src/op_mode/ping.py
index 60bbc0c78..5e5b95a0a 100755
--- a/src/op_mode/ping.py
+++ b/src/op_mode/ping.py
@@ -18,6 +18,32 @@ import os
import sys
import socket
import ipaddress
+import json
+from vyos.util import cmd, rc_cmd
+from vyos.ifconfig import Section
+
+
+def interface_list() -> list:
+ """
+ Get list of interfaces in system
+ :rtype: list
+ """
+ return Section.interfaces()
+
+
+def vrf_list() -> list:
+ """
+ Get list of VRFs in system
+ :rtype: list
+ """
+ result = cmd(f'sudo ip --json --brief link show type vrf')
+ data = json.loads(result)
+ vrflist: list = []
+ for o in data:
+ if 'ifname' in o:
+ vrflist.append(o['ifname'])
+ return vrflist
+
options = {
'audible': {
@@ -63,6 +89,7 @@ options = {
'interface': {
'ping': '{command} -I {value}',
'type': '<interface>',
+ 'helpfunction': interface_list,
'help': 'Source interface'
},
'interval': {
@@ -128,6 +155,7 @@ options = {
'ping': 'sudo ip vrf exec {value} {command}',
'type': '<vrf>',
'help': 'Use specified VRF table',
+ 'helpfunction': vrf_list,
'dflt': 'default',
},
'verbose': {
@@ -142,20 +170,33 @@ ping = {
}
-class List (list):
- def first (self):
+class List(list):
+ def first(self):
return self.pop(0) if self else ''
def last(self):
return self.pop() if self else ''
- def prepend(self,value):
- self.insert(0,value)
+ def prepend(self, value):
+ self.insert(0, value)
+
+
+def completion_failure(option: str) -> None:
+ """
+ Shows failure message after TAB when option is wrong
+ :param option: failure option
+ :type str:
+ """
+ sys.stderr.write('\n\n Invalid option: {}\n\n'.format(option))
+ sys.stdout.write('<nocomps>')
+ sys.exit(1)
def expension_failure(option, completions):
reason = 'Ambiguous' if completions else 'Invalid'
- sys.stderr.write('\n\n {} command: {} [{}]\n\n'.format(reason,' '.join(sys.argv), option))
+ sys.stderr.write(
+ '\n\n {} command: {} [{}]\n\n'.format(reason, ' '.join(sys.argv),
+ option))
if completions:
sys.stderr.write(' Possible completions:\n ')
sys.stderr.write('\n '.join(completions))
@@ -196,28 +237,44 @@ if __name__ == '__main__':
if host == '--get-options':
args.first() # pop ping
args.first() # pop IP
+ usedoptionslist = []
while args:
- option = args.first()
-
- matched = complete(option)
+ option = args.first() # pop option
+ matched = complete(option) # get option parameters
+ usedoptionslist.append(option) # list of used options
+ # Select options
if not args:
+ # remove from Possible completions used options
+ for o in usedoptionslist:
+ if o in matched:
+ matched.remove(o)
sys.stdout.write(' '.join(matched))
sys.exit(0)
- if len(matched) > 1 :
+ if len(matched) > 1:
sys.stdout.write(' '.join(matched))
sys.exit(0)
+ # If option doesn't have value
+ if matched:
+ if options[matched[0]]['type'] == 'noarg':
+ continue
+ else:
+ # Unexpected option
+ completion_failure(option)
- if options[matched[0]]['type'] == 'noarg':
- continue
-
- value = args.first()
+ value = args.first() # pop option's value
if not args:
matched = complete(option)
- sys.stdout.write(options[matched[0]]['type'])
+ helplines = options[matched[0]]['type']
+ # Run helpfunction to get list of possible values
+ if 'helpfunction' in options[matched[0]]:
+ result = options[matched[0]]['helpfunction']()
+ if result:
+ helplines = '\n' + ' '.join(result)
+ sys.stdout.write(helplines)
sys.exit(0)
- for name,option in options.items():
+ for name, option in options.items():
if 'dflt' in option and name not in args:
args.append(name)
args.append(option['dflt'])
@@ -234,8 +291,7 @@ if __name__ == '__main__':
except ValueError:
sys.exit(f'ping: Unknown host: {host}')
- command = convert(ping[version],args)
+ command = convert(ping[version], args)
# print(f'{command} {host}')
os.system(f'{command} {host}')
-