Initial commit for phase 2, Add some simple validation.
Change-Id: I5b1d5600cdef4b05cc7c2f1cddb60aed2cc49ac2 Signed-off-by: John DeNisco <jdenisco@cisco.com>
This commit is contained in:
John DeNisco
committed by
Dave Barach
parent
cdeb7f2ae0
commit
a3db0782d4
@ -1,7 +1,7 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(name="vpp_config",
|
||||
version="17.10.1",
|
||||
version="17.10.3",
|
||||
author="John DeNisco",
|
||||
author_email="jdenisco@cisco.com",
|
||||
description="VPP Configuration Utility",
|
||||
|
@ -440,6 +440,16 @@ def autoconfig_patch_qemu():
|
||||
acfg.patch_qemu(node)
|
||||
|
||||
|
||||
def autoconfig_ipv4_setup():
|
||||
"""
|
||||
Setup IPv4 interfaces
|
||||
|
||||
"""
|
||||
|
||||
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
||||
acfg.ipv4_interface_setup()
|
||||
|
||||
|
||||
def autoconfig_not_implemented():
|
||||
"""
|
||||
This feature is not implemented
|
||||
@ -449,6 +459,59 @@ def autoconfig_not_implemented():
|
||||
print "\nThis Feature is not implemented yet...."
|
||||
|
||||
|
||||
def autoconfig_basic_test_menu():
|
||||
"""
|
||||
The auto configuration basic test menu
|
||||
|
||||
"""
|
||||
|
||||
basic_menu_text = '\nWhat would you like to do?\n\n\
|
||||
1) List/Create Simple IPv4 Setup\n\
|
||||
9 or q) Back to main menu.'
|
||||
|
||||
print "{}".format(basic_menu_text)
|
||||
|
||||
input_valid = False
|
||||
answer = ''
|
||||
while not input_valid:
|
||||
answer = raw_input("\nCommand: ")
|
||||
if len(answer) > 1:
|
||||
print "Please enter only 1 character."
|
||||
continue
|
||||
if re.findall(r'[Qq1-29]', answer):
|
||||
input_valid = True
|
||||
answer = answer[0].lower()
|
||||
else:
|
||||
print "Please enter a character between 1 and 2 or 9."
|
||||
|
||||
if answer == '9':
|
||||
answer = 'q'
|
||||
|
||||
return answer
|
||||
|
||||
|
||||
def autoconfig_basic_test():
|
||||
"""
|
||||
The auto configuration basic test menu
|
||||
|
||||
"""
|
||||
vutil = VPPUtil()
|
||||
pkgs = vutil.get_installed_vpp_pkgs()
|
||||
if len(pkgs) == 0:
|
||||
print "\nVPP is not installed, install VPP with option 4."
|
||||
return
|
||||
|
||||
answer = ''
|
||||
while answer != 'q':
|
||||
answer = autoconfig_basic_test_menu()
|
||||
if answer == '1':
|
||||
autoconfig_ipv4_setup()
|
||||
elif answer == '9' or answer == 'q':
|
||||
return
|
||||
else:
|
||||
autoconfig_not_implemented()
|
||||
|
||||
|
||||
def autoconfig_main_menu():
|
||||
"""
|
||||
The auto configuration main menu
|
||||
@ -461,6 +524,7 @@ def autoconfig_main_menu():
|
||||
and user input in {}/vpp/vpp-config/configs/auto-config.yaml\n\
|
||||
3) Full configuration (WARNING: This will change the system configuration)\n\
|
||||
4) List/Install/Uninstall VPP.\n\
|
||||
5) Execute some basic tests.\n\
|
||||
9 or q) Quit'.format(rootdir, rootdir)
|
||||
|
||||
# 5) Dry Run from {}/vpp/vpp-config/auto-config.yaml (will not ask questions).\n\
|
||||
@ -479,7 +543,7 @@ def autoconfig_main_menu():
|
||||
input_valid = True
|
||||
answer = answer[0].lower()
|
||||
else:
|
||||
print "Please enter a character between 1 and 7 or 9."
|
||||
print "Please enter a character between 1 and 5 or 9."
|
||||
|
||||
if answer == '9':
|
||||
answer = 'q'
|
||||
@ -503,6 +567,8 @@ def autoconfig_main():
|
||||
autoconfig_apply()
|
||||
elif answer == '4':
|
||||
autoconfig_install()
|
||||
elif answer == '5':
|
||||
autoconfig_basic_test()
|
||||
elif answer == '9' or answer == 'q':
|
||||
return
|
||||
else:
|
||||
|
@ -17,6 +17,7 @@ import logging
|
||||
import os
|
||||
import re
|
||||
import yaml
|
||||
import ipaddress
|
||||
|
||||
from vpplib.VPPUtil import VPPUtil
|
||||
from vpplib.VppPCIUtil import VppPCIUtil
|
||||
@ -83,6 +84,36 @@ class AutoConfig(object):
|
||||
if ret != 0:
|
||||
logging.debug(stderr)
|
||||
|
||||
@staticmethod
|
||||
def _ask_user_ipv4():
|
||||
"""
|
||||
Asks the user for a number within a range.
|
||||
default is returned if return is entered.
|
||||
|
||||
:returns: IP address and prefix len
|
||||
:rtype: tuple
|
||||
"""
|
||||
|
||||
while True:
|
||||
answer = raw_input("Please enter the IPv4 Address [n.n.n.n]: ")
|
||||
try:
|
||||
ipaddr = ipaddress.ip_address(u'{}'.format(answer))
|
||||
except:
|
||||
print "Please enter a valid IPv4 address."
|
||||
continue
|
||||
|
||||
answer = raw_input("Please enter the netmask [n.n.n.n]: ")
|
||||
try:
|
||||
netmask = ipaddress.ip_address(u'{}'.format(answer))
|
||||
pl = ipaddress.ip_network(u'0.0.0.0/{}'.format(netmask))
|
||||
plen = pl.exploded.split('/')[1]
|
||||
break
|
||||
except:
|
||||
print "Please enter a valid IPv4 address and netmask."
|
||||
continue
|
||||
|
||||
return ipaddr, plen
|
||||
|
||||
@staticmethod
|
||||
def _ask_user_range(question, first, last, default):
|
||||
"""
|
||||
@ -1150,7 +1181,7 @@ other than VPP? [0-{}][0]? '.format(str(max_other_cores))
|
||||
print "\nThere currently a total of {} huge pages.". \
|
||||
format(total)
|
||||
question = \
|
||||
"How many huge pages do you want [{} - {}][{}]? ".\
|
||||
"How many huge pages do you want [{} - {}][{}]? ". \
|
||||
format(MIN_TOTAL_HUGE_PAGES, maxpages, MIN_TOTAL_HUGE_PAGES)
|
||||
answer = self._ask_user_range(question, 1024, maxpages, 1024)
|
||||
node['hugepages']['total'] = str(answer)
|
||||
@ -1363,10 +1394,10 @@ other than VPP? [0-{}][0]? '.format(str(max_other_cores))
|
||||
|
||||
# System Memory
|
||||
if 'free' in node['hugepages'] and \
|
||||
'memfree' in node['hugepages'] and \
|
||||
'size' in node['hugepages']:
|
||||
free = node['hugepages']['free']
|
||||
memfree = float(node['hugepages']['memfree'].split(' ')[0])
|
||||
'memfree' in node['hugepages'] and \
|
||||
'size' in node['hugepages']:
|
||||
free = node['hugepages']['free']
|
||||
memfree = float(node['hugepages']['memfree'].split(' ')[0])
|
||||
hugesize = float(node['hugepages']['size'].split(' ')[0])
|
||||
|
||||
memhugepages = MIN_TOTAL_HUGE_PAGES * hugesize
|
||||
@ -1425,3 +1456,94 @@ other than VPP? [0-{}][0]? '.format(str(max_other_cores))
|
||||
self.min_system_resources(node)
|
||||
|
||||
print "\n=============================="
|
||||
|
||||
def _ipv4_interface_setup_questions(self, node):
|
||||
"""
|
||||
Ask the user some questions and get a list of interfaces
|
||||
and IPv4 addresses associated with those interfaces
|
||||
|
||||
:param node: Node dictionary.
|
||||
:type node: dict
|
||||
:returns: A list or interfaces with ip addresses
|
||||
:rtype: dict
|
||||
"""
|
||||
|
||||
vpputl = VPPUtil()
|
||||
interfaces = vpputl.get_hardware(node)
|
||||
if interfaces == {}:
|
||||
return
|
||||
|
||||
interfaces_with_ip = []
|
||||
for intf in sorted(interfaces.items()):
|
||||
name = intf[0]
|
||||
if name == 'local0':
|
||||
continue
|
||||
|
||||
question = "Would you like an address to interface {} [Y/n]? ".format(name)
|
||||
answer = self._ask_user_yn(question, 'y')
|
||||
if answer == 'y':
|
||||
address = {}
|
||||
addr, plen = self._ask_user_ipv4()
|
||||
address['name'] = name
|
||||
address['addr'] = addr
|
||||
address['plen'] = plen
|
||||
interfaces_with_ip.append(address)
|
||||
|
||||
return interfaces_with_ip
|
||||
|
||||
def ipv4_interface_setup(self):
|
||||
"""
|
||||
After asking the user some questions, get a list of interfaces
|
||||
and IPv4 addresses associated with those interfaces
|
||||
|
||||
"""
|
||||
|
||||
for i in self._nodes.items():
|
||||
node = i[1]
|
||||
|
||||
# Show the current interfaces with IP addresses
|
||||
current_ints = VPPUtil.get_int_ip(node)
|
||||
if current_ints is not {}:
|
||||
print ("\nThese are the current interfaces with IP addresses:")
|
||||
for items in sorted(current_ints.items()):
|
||||
name = items[0]
|
||||
value = items[1]
|
||||
if 'address' not in value:
|
||||
address = 'Not Set'
|
||||
else:
|
||||
address = value['address']
|
||||
print ("{:30} {:20} {:10}".format(name, address, value['state']))
|
||||
question = "\nWould you like to keep this configuration [Y/n]? "
|
||||
answer = self._ask_user_yn(question, 'y')
|
||||
if answer == 'y':
|
||||
continue
|
||||
else:
|
||||
print ("\nThere are currently no interfaces with IP addresses.")
|
||||
|
||||
# Create a script that add the ip addresses to the interfaces
|
||||
# and brings the interfaces up
|
||||
ints_with_addrs = self._ipv4_interface_setup_questions(node)
|
||||
content = ''
|
||||
for ints in ints_with_addrs:
|
||||
name = ints['name']
|
||||
addr = ints['addr']
|
||||
plen = ints['plen']
|
||||
setipstr = 'set int ip address {} {}/{}\n'.format(name, addr, plen)
|
||||
setintupstr = 'set int state {} up\n'.format(name)
|
||||
content += setipstr + setintupstr
|
||||
|
||||
# Write the content to the script
|
||||
rootdir = node['rootdir']
|
||||
filename = rootdir + '/vpp/vpp-config/scripts/set_int_ipv4_and_up'
|
||||
with open(filename, 'w+') as sfile:
|
||||
sfile.write(content)
|
||||
|
||||
# Execute the script
|
||||
cmd = 'vppctl exec {}'.format(filename)
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
logging.debug(stderr)
|
||||
|
||||
print("\nA script as been created at {}".format(filename))
|
||||
print("This script can be run using the following:")
|
||||
print("vppctl exec {}\n".format(filename))
|
@ -372,6 +372,45 @@ class VPPUtil(object):
|
||||
for _, value in def_setting_tb_displayed.items():
|
||||
self.exec_command('vppctl sh {}'.format(value))
|
||||
|
||||
@staticmethod
|
||||
def get_int_ip(node):
|
||||
"""
|
||||
Get the VPP interfaces and IP addresses
|
||||
|
||||
:param node: VPP node.
|
||||
:type node: dict
|
||||
:returns: Dictionary containing VPP interfaces and IP addresses
|
||||
:rtype: dictionary
|
||||
"""
|
||||
interfaces = {}
|
||||
cmd = 'vppctl show int addr'
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
return interfaces
|
||||
|
||||
lines = stdout.split('\n')
|
||||
if len(lines[0]) is not 0:
|
||||
if lines[0].split(' ')[0] == 'FileNotFoundError':
|
||||
return interfaces
|
||||
|
||||
for line in lines:
|
||||
if len(line) is 0:
|
||||
continue
|
||||
|
||||
# If the first character is not whitespace
|
||||
# create a new interface
|
||||
if len(re.findall(r'\s', line[0])) is 0:
|
||||
spl = line.split()
|
||||
name = spl[0]
|
||||
if name == 'local0':
|
||||
continue
|
||||
interfaces[name] = {}
|
||||
interfaces[name]['state'] = spl[1].lstrip('(').rstrip('):\r')
|
||||
else:
|
||||
interfaces[name]['address'] = line.lstrip(' ').rstrip('\r')
|
||||
|
||||
return interfaces
|
||||
|
||||
@staticmethod
|
||||
def get_hardware(node):
|
||||
"""
|
||||
@ -380,7 +419,7 @@ class VPPUtil(object):
|
||||
|
||||
:param node: VPP node.
|
||||
:type node: dict
|
||||
:returns: Dictionary containing improtant VPP information
|
||||
:returns: Dictionary containing VPP hardware information
|
||||
:rtype: dictionary
|
||||
"""
|
||||
|
||||
|
Reference in New Issue
Block a user