CONFIG: VSPERF Config-file Generation Wizard. 37/68037/2
authorSridhar K. N. Rao <sridhar.rao@spirent.com>
Tue, 11 Jun 2019 07:58:09 +0000 (13:28 +0530)
committerSridhar K. N. Rao <sridhar.rao@spirent.com>
Wed, 12 Jun 2019 14:51:16 +0000 (20:21 +0530)
This patch adds a tool create config file.
When run, the wizard asks user a set of questions.
A config file, named vsperf.conf, will be created.

Fix some pylint Issues.

JIRA: VSPERF-603

Change-Id: I1b800d8384cb3c0883b7f3859a9df77bb874b7b8
Signed-off-by: Sridhar K. N. Rao <sridhar.rao@spirent.com>
requirements.txt
tools/confgenwizard/__init__.py [new file with mode: 0644]
tools/confgenwizard/nicinfo.py [new file with mode: 0644]
tools/confgenwizard/vsperfwiz.py [new file with mode: 0644]

index cb5a0d8..03049fd 100644 (file)
@@ -20,3 +20,5 @@ matplotlib==2.2.2
 numpy
 pycrypto
 tabulate
+pypsi
+paramiko
diff --git a/tools/confgenwizard/__init__.py b/tools/confgenwizard/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/confgenwizard/nicinfo.py b/tools/confgenwizard/nicinfo.py
new file mode 100644 (file)
index 0000000..631b92c
--- /dev/null
@@ -0,0 +1,236 @@
+# Copyright 2019-2020 Spirent Communications.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Retrieve information from remote host.
+In this file, we retrive only NIC PICs
+"""
+
+from __future__ import print_function
+import sys
+import subprocess
+import os
+from os.path import exists
+from stat import S_ISDIR
+import paramiko
+
+# The PCI device class for ETHERNET devices
+ETHERNET_CLASS = "0200"
+LSPCI_PATH = '/usr/bin/lspci'
+RECV_BYTES = 4096
+ADVANCED = True
+
+
+#pylint: disable=too-many-instance-attributes
+class RemoteInfo(object):
+    """
+    Class to extract information from a remote system
+    """
+
+    def __init__(self, host, username, password):
+        """
+        Perform Initialization
+        """
+        # Dict of ethernet devices present. Dictionary indexed by PCI address.
+        # Each device within this is itself a dictionary of device properties
+        self.nic_devices = {}
+        if host == 'local':
+            self.local = True
+        else:
+            self.local = False
+            # Assuming port as 22.
+            self.port = 22
+            self.hostname = host
+            self.password = password
+            self.username = username
+            self.client = paramiko.Transport((self.hostname, self.port))
+            self.client.connect(username=self.username,
+                                password=self.password)
+            self.session = self.client.open_channel(kind='session')
+            self.session.get_pty()
+            self.sftp = paramiko.SFTPClient.from_transport(self.client)
+
+    def sftp_exists(self, path):
+        """
+        Check if remote file exist
+        """
+        try:
+            self.sftp.stat(path)
+            return True
+        except IOError:
+            return False
+
+    def sft_listdir(self, path):
+        """
+        List directories on remote nost
+        """
+        files = []
+        for fil in self.sftp.listdir_attr(path):
+            if not S_ISDIR(fil.st_mode):
+                files.append(fil.filename)
+        return files
+
+    def is_connected(self):
+        """
+        Check if session is connected.
+        """
+        return self.client.is_active()
+
+    def new_channel(self):
+        """
+        FOr every command a new session is setup
+        """
+        if not self.is_connected():
+            self.client = paramiko.Transport((self.hostname, self.port))
+            self.client.connect(username=self.username,
+                                password=self.password)
+        self.session = self.client.open_channel(kind='session')
+
+    # This is roughly compatible with check_output function in subprocess module
+    # which is only available in python 2.7.
+    def check_output(self, args, stderr=None):
+        '''
+        Run a command and capture its output
+        '''
+        stdout_data = []
+        stderr_data = []
+        if self.local:
+            return subprocess.Popen(args, stdout=subprocess.PIPE,
+                                    stderr=stderr,
+                                    universal_newlines=True).communicate()[0]
+        else:
+            self.new_channel()
+            separator = ' '
+            command = separator.join(args)
+            # self.session.get_pty()
+            self.session.exec_command(command)
+            while True:
+                if self.session.recv_ready():
+                    stdout_data.append(self.session.recv(RECV_BYTES))
+                if self.session.recv_stderr_ready():
+                    stderr_data.append(self.session.recv_stderr(RECV_BYTES))
+                if self.session.exit_status_ready():
+                    break
+            if stdout_data:
+                return b"".join(stdout_data)
+        return b"".join(stderr_data)
+
+    def get_pci_details(self, dev_id):
+        '''
+        This function gets additional details for a PCI device
+        '''
+        device = {}
+
+        extra_info = self.check_output([LSPCI_PATH,
+                                        "-vmmks", dev_id]).splitlines()
+
+        # parse lspci details
+        for line in extra_info:
+            if not line:
+                continue
+            if self.local:
+                name, value = line.split("\t", 1)
+            else:
+                name, value = line.decode().split("\t", 1)
+            name = name.strip(":") + "_str"
+            device[name] = value
+        # check for a unix interface name
+        sys_path = "/sys/bus/pci/devices/%s/net/" % dev_id
+        device["Interface"] = ""
+        if self.local:
+            if exists(sys_path):
+                device["Interface"] = ",".join(os.listdir(sys_path))
+        else:
+            if self.sftp_exists(sys_path):
+                device["Interface"] = ",".join(self.sft_listdir(sys_path))
+
+        # check if a port is used for ssh connection
+        device["Ssh_if"] = False
+        device["Active"] = ""
+
+        return device
+
+    def get_nic_details(self):
+        '''
+        This function populates the "devices" dictionary. The keys used are
+        the pci addresses (domain:bus:slot.func). The values are themselves
+        dictionaries - one for each NIC.
+        '''
+        devinfos = []
+        # first loop through and read details for all devices
+        # request machine readable format, with numeric IDs
+        dev = {}
+        dev_lines = self.check_output([LSPCI_PATH, "-Dvmmn"]).splitlines()
+        for dev_line in dev_lines:
+            if not dev_line:
+                if dev["Class"] == ETHERNET_CLASS:
+                    # convert device and vendor ids to numbers, then add to
+                    # global
+                    dev["Vendor"] = int(dev["Vendor"], 16)
+                    dev["Device"] = int(dev["Device"], 16)
+                    self.nic_devices[dev["Slot"]] = dict(
+                        dev)  # use dict to make copy of dev
+            else:
+                # values = re.split(r'\t+', str(dev_line))
+                if self.local:
+                    name, value = dev_line.split('\t', 1)
+                else:
+                    name, value = dev_line.decode().split("\t", 1)
+                dev[name.rstrip(":")] = value
+
+        # based on the basic info, get extended text details
+        for dev in self.nic_devices:
+            # get additional info and add it to existing data
+            if ADVANCED:
+                self.nic_devices[dev].update(self.get_pci_details(dev).items())
+            devinfos.append(self.nic_devices[dev])
+        return devinfos
+
+    def dev_id_from_dev_name(self, dev_name):
+        '''
+        Take a device "name" - a string passed in by user to identify a NIC
+        device, and determine the device id - i.e. the domain:bus:slot.func-for
+        it, which can then be used to index into the devices array
+        '''
+        # dev = None
+        # check if it's already a suitable index
+        if dev_name in self.nic_devices:
+            return dev_name
+        # check if it's an index just missing the domain part
+        elif "0000:" + dev_name in self.nic_devices:
+            return "0000:" + dev_name
+        else:
+            # check if it's an interface name, e.g. eth1
+            for dev in self.nic_devices:
+                if dev_name in self.nic_devices[dev]["Interface"].split(","):
+                    return self.nic_devices[dev]["Slot"]
+        # if nothing else matches - error
+        print("Unknown device: %s. "
+              "Please specify device in \"bus:slot.func\" format" % dev_name)
+        sys.exit(1)
+
+
+def main():
+    '''program main function'''
+    host = input("Enter Host IP: ")
+    username = input("Enter User Name: ")
+    pwd = input("Enter Password: ")
+    rhi = RemoteInfo(host, username, pwd)
+    dev_list = rhi.get_nic_details()
+    for dev in dev_list:
+        print(dev["Slot"])
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/confgenwizard/vsperfwiz.py b/tools/confgenwizard/vsperfwiz.py
new file mode 100644 (file)
index 0000000..48a2d50
--- /dev/null
@@ -0,0 +1,736 @@
+# Copyright 2019-2020 Spirent Communications.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Tool to create configuration file for VSPERF
+"""
+
+from __future__ import print_function
+import signal
+import sys
+from pypsi import wizard as wiz
+from pypsi.shell import Shell
+import nicinfo
+
+
+#pylint: disable=too-many-instance-attributes
+class VsperfWizard(object):
+    """
+    Class to create wizards
+    """
+
+    def __init__(self):
+        """
+        Perform Initialization.
+        """
+        self.shell = Shell()
+        self.vpp_values = {}
+        self.dut_values = {}
+        self.main_values = {}
+        self.guest_values = {}
+        self.ovs_values = {}
+        self.ixnet_values = {}
+        self.stc_values = {}
+        self.trex_values = {}
+        self.traffic_values = {}
+        self.vpp_values = {}
+        self.wiz_dut = None
+        self.wiz_ixnet = None
+        self.wiz_stc = None
+        self.wiz_ovs = None
+        self.wiz_traffic = None
+        self.wiz_main = None
+        self.wiz_guest = None
+        self.wiz_trex = None
+        self.wiz_vpp = None
+        self.rhi = None
+        self.devices = ''
+        self.devs = {}
+
+
+
+######## Support Functions ############################
+    def get_nicpcis(self):
+        """
+        Get NIC information from Remote Host
+        """
+        self.rhi = nicinfo.RemoteInfo(self.dut_values['dutip'],
+                                      self.dut_values['dutuname'],
+                                      self.dut_values['dutpwd'])
+        dev_list = self.rhi.get_nic_details()
+        index = 0
+        for dev in dev_list:
+            self.devices += str("(" + str(index) + ")" + " "
+                                + str(dev["Slot"]) + ', ')
+            self.devs[str(index)] = str(dev["Slot"])
+            index = index + 1
+
+    def get_nics_string(self):
+        """
+        Create string that's acceptable to configuration
+        """
+        indexes = self.main_values['nics'].split(',')
+        wlns = ''
+        for index in indexes:
+            wlns += "'" + self.devs[index] + "' ,"
+        print(wlns)
+        return wlns.rstrip(',')
+
+
+############# All the Wizards ##################################
+
+    def dut_wizard(self):
+        """
+        Wizard to collect DUT information
+        """
+        self.wiz_dut = wiz.PromptWizard(
+            name="VSPERF DUT Info Collection",
+            description="This collects DUT info",
+            steps=(
+                # The list of input prompts to ask the user.
+                wiz.WizardStep(
+                    # ID where the value will be stored
+                    id="dutip",
+                    # Display name
+                    name="Enter the IP address of the DUT [local]",
+                    # Help message
+                    help="IP address of the DUT host",
+                    # List of validators to run on the input
+                    validators=(wiz.required_validator)
+                ),
+                wiz.WizardStep(
+                    # ID where the value will be stored
+                    id="dutuname",
+                    # Display name
+                    name="Enter the username to connect to DUT",
+                    # Help message
+                    help="Username for DUT host",
+                    # List of validators to run on the input
+                    validators=(wiz.required_validator)
+                ),
+                wiz.WizardStep(
+                    # ID where the value will be stored
+                    id="dutpwd",
+                    # Display name
+                    name="Enter the Password to connect to DUT",
+                    # Help message
+                    help="Password for the DUT host",
+                    # List of validators to run on the input
+                    validators=(wiz.required_validator)
+                ),
+            )
+        )
+
+    def main_wizard(self):
+        """
+        The Main Wizard
+        """
+        # First get the nics.
+        self.get_nicpcis()
+        self.wiz_main = wiz.PromptWizard(
+            name="VSPERF Common Configuration",
+            description="This configuration covers Basic inputs",
+            steps=(
+                # The list of input prompts to ask the user.
+                wiz.WizardStep(
+                    # ID where the value will be stored
+                    id="vswitch",
+                    # Display name
+                    name="VSwitch to use? - OVS or VPP?",
+                    # Help message
+                    help=" Enter the vswitch to use - either OVS or VPP",
+                    # List of validators to run on the input
+                    default='OVS'
+                ),
+                wiz.WizardStep(
+                    id='nics',
+                    name="NICs to Whitelist: " + self.devices,
+                    help="Enter the list (separated by comma) of PCI-IDs",
+                    validators=(wiz.required_validator),
+                ),
+                wiz.WizardStep(
+                    id='tgen',
+                    name=("What trafficgen to use: [TestCenter" +
+                          " IxNet, Moongen, Trex]?"),
+                    help=("Enter the trafficgen to use -" +
+                          " TestCenter, IxNet, Moongen, Trex"),
+                    validators=(wiz.required_validator),
+                    default="Trex"
+                ),
+                wiz.WizardStep(
+                    id='guest',
+                    name=("Is Scenario either PVP or PVVP?"),
+                    help=("This is ti capture guest Configuration"),
+                    validators=(wiz.required_validator),
+                    default="YES"
+                )
+            )
+        )
+
+    def traffic_wizard(self):
+        """
+        Wizard to collectd Traffic Info.
+        """
+        self.wiz_traffic = wiz.PromptWizard(
+            name="Traffic Configuration",
+            description="This configuration covers Traffic specifc inputs",
+            steps=(
+                wiz.WizardStep(
+                    id='pktsizes',
+                    name='Enter the Packet Sizes - comma separated',
+                    help="Allowed values: (64,128,256,512,1024,1280,1518)",
+                    validators=(wiz.required_validator)
+                ),
+                wiz.WizardStep(
+                    id='duration',
+                    name='Enter the Duration (in secs) for the traffic',
+                    help="Enter for how long each iteration should be",
+                    default='60',
+                ),
+                # wiz.WizardStep(
+                #    id='multistream',
+                #    name='Multistream preferred?',
+                #    help="Multistream preference - Yes or No",
+                #    default='No',
+                # validators=(wiz.required_validator)
+                #),
+                wiz.WizardStep(
+                    id='count',
+                    name='Number of flows?',
+                    help="Enter the number of flows - 2 - 1,000,000",
+                    default='2',
+                    # validators=(wiz.required_validator)
+                ),
+            )
+        )
+
+    def ovs_wizard(self):
+        """
+        Wizard to collect OVS Information
+        """
+        self.wiz_ovs = wiz.PromptWizard(
+            name="Vswitch Configuration",
+            description="Specific configurations of the virtual-Switch",
+            steps=(
+                wiz.WizardStep(
+                    id='type',
+                    name='OVS Type? [Vanilla or DPDK]',
+                    help='Enter either Vanilla or DPDK',
+                    default='Vanilla',
+                ),
+                wiz.WizardStep(
+                    id='mask',
+                    name='Enter the CPU Mask for OVS to use',
+                    help='Mask for OVS PMDs',
+                    default='30',
+                ),
+            )
+        )
+
+    def vpp_wizard(self):
+        """
+        Wizard to collect VPP configuration
+        """
+        self.wiz_vpp = wiz.PromptWizard(
+            name="Vswitch Configuration",
+            description="Specific configurations of the virtual-Switch",
+            steps=(
+                wiz.WizardStep(
+                    id='mode',
+                    name='L2 Connection mode xconnect|bridge|l2patch to use?',
+                    help='Select the l2 connection mode',
+                    default='xconnect',
+                ),
+            )
+        )
+
+    def trex_wizard(self):
+        """
+        Wizard to collect Trex configuration
+        """
+        self.wiz_trex = wiz.PromptWizard(
+            name="Trex Traffic Generator Configuration",
+            description="Specific configurations of Trex TGen",
+            steps=(
+                wiz.WizardStep(
+                    id='hostip',
+                    name='What is IP address of the T-Rex Host?',
+                    help='Enter the IP address of host where Trex is running',
+                    validators=(wiz.required_validator)
+                ),
+                wiz.WizardStep(
+                    id='user',
+                    name='What is Usernameof the T-Rex Host?',
+                    help='Enter the Username of host where Trex is running',
+                    default='root',
+                ),
+                wiz.WizardStep(
+                    id='bdir',
+                    name='What is Dir where the T-Rex Binary resides?',
+                    help='Enter the Location where Trex Binary is',
+                    default='/root/trex_2.37/scripts/',
+                ),
+                wiz.WizardStep(
+                    id='pci1',
+                    name='What is PCI address of the port-1?',
+                    help='Enter the PCI address of Data port 1',
+                    validators=(wiz.required_validator)
+                ),
+                wiz.WizardStep(
+                    id='pci2',
+                    name='What is PCI address of the port-2?',
+                    help='Enter the PCI address of Data port 2',
+                    validators=(wiz.required_validator)
+                ),
+                wiz.WizardStep(
+                    id='rate',
+                    name='What is Line rate (in Gbps) of the ports?',
+                    help='Enter the linerate of the ports',
+                    default='10',
+                ),
+                wiz.WizardStep(
+                    id='prom',
+                    name='T-Rex Promiscuous enabled?',
+                    help='Do you want to enable the Promiscuous mode?',
+                    default='False',
+                ),
+                wiz.WizardStep(
+                    id='lat',
+                    name='Whats the Trex Latency PPS?',
+                    help='Enter the Latency value in PPS',
+                    default='1000',
+                ),
+                wiz.WizardStep(
+                    id='bslv',
+                    name='Do you want Binary Loss Verification Enabled?',
+                    help='Enter True if you want it to be enabled.',
+                    default='True',
+                ),
+                wiz.WizardStep(
+                    id='maxrep',
+                    name='If Loss Verification, what the max rep?',
+                    help='If BSLV is enabled, whats the max repetition value?',
+                    default='2',
+                ),
+            )
+        )
+
+    def stc_wizard(self):
+        """
+        Wizard to collect STC configuration
+        """
+        self.wiz_stc = wiz.PromptWizard(
+            name="Spirent STC Traffic Generator Configuration",
+            description="Specific configurations of Spirent-STC TGen",
+            steps=(
+                wiz.WizardStep(
+                    id='lab',
+                    name='Lab Server IP?',
+                    help='Enter the IP of Lab Server',
+                    default='10.10.120.244',
+                ),
+                wiz.WizardStep(
+                    id='lisc',
+                    name='License Server IP?',
+                    help='Enter the IP of the License Server',
+                    default='10.10.120.246',
+                ),
+                wiz.WizardStep(
+                    id='eaddr',
+                    name='East Port Chassis Address?',
+                    help='IP address of the East-Port',
+                    default='10.10.120.245',
+                ),
+                wiz.WizardStep(
+                    id='eslot',
+                    name='East Port Slot Number',
+                    help='Slot Number of the East Port',
+                    default='1',
+                ),
+                wiz.WizardStep(
+                    id='eport',
+                    name='Port Number of the East-Port',
+                    help='Port Number for the East Port',
+                    default='1',
+                ),
+                wiz.WizardStep(
+                    id='eint',
+                    name='East port Interface Address',
+                    help='IP to use for East Port?',
+                    default='192.85.1.3',
+                ),
+                wiz.WizardStep(
+                    id='egw',
+                    name='Gateway Address for East Port',
+                    help='IP of the East-Port Gateway',
+                    default='192.85.1.103',
+                ),
+                wiz.WizardStep(
+                    id='waddr',
+                    name='West Port Chassis Address?',
+                    help='IP address of the West-Port',
+                    default='10.10.120.245',
+                ),
+                wiz.WizardStep(
+                    id='wslot',
+                    name='West Port Slot Number',
+                    help='Slot Number of the West Port',
+                    default='1',
+                ),
+                wiz.WizardStep(
+                    id='wport',
+                    name='Port Number of the West-Port',
+                    help='Port Number for the West Port',
+                    default='2',
+                ),
+                wiz.WizardStep(
+                    id='wint',
+                    name='West port Interface Address',
+                    help='IP to use for West Port?',
+                    default='192.85.1.103',
+                ),
+                wiz.WizardStep(
+                    id='wgw',
+                    name='Gateway Address for West Port',
+                    help='IP of the West-Port Gateway',
+                    default='192.85.1.3',
+                ),
+                wiz.WizardStep(
+                    id='script',
+                    name='Name of the Script to use for RFC2544 Tests?',
+                    help='Script Name to use for RFC 2544 Tests.',
+                    default='testcenter-rfc2544-rest.py',
+                ),
+            )
+        )
+
+    def ixnet_wizard(self):
+        """
+        Wizard to collect ixnet configuration
+        """
+        self.wiz_ixnet = wiz.PromptWizard(
+            name="Ixia IxNet Traffic Generator Configuration",
+            description="Specific configurations of Ixia-Ixnet TGen",
+            steps=(
+                wiz.WizardStep(
+                    id='card',
+                    name='Card Number?',
+                    help='Chassis Card Number',
+                    default='1',
+                ),
+                wiz.WizardStep(
+                    id='port1',
+                    name='Port-1 Number?',
+                    help='Chassis Port-1 Number',
+                    default='5',
+                ),
+                wiz.WizardStep(
+                    id='port2',
+                    name='Port-2 Number?',
+                    help='Chassis Port-2 Number',
+                    default='6',
+                ),
+                wiz.WizardStep(
+                    id='libp1',
+                    name='IXIA Library path?',
+                    help='Library path of Ixia',
+                    default='/opt/ixnet/ixos-api/8.01.0.2/lib/ixTcl1.0',
+                ),
+                wiz.WizardStep(
+                    id='libp2',
+                    name='IXNET Library Path',
+                    help='Library Path for the IXNET',
+                    default='/opt/ixnet/ixnetwork/8.01.1029.6/lib/IxTclNetwork',
+                ),
+                wiz.WizardStep(
+                    id='host',
+                    name='IP of the CHassis?',
+                    help='Chassis IP',
+                    default='10.10.50.6',
+                ),
+                wiz.WizardStep(
+                    id='machine',
+                    name='IP of the API Server?',
+                    help='API Server IP ',
+                    default='10.10.120.6',
+                ),
+                wiz.WizardStep(
+                    id='port',
+                    name='Port of the API Server?',
+                    help='API Server Port',
+                    default='9127',
+                ),
+                wiz.WizardStep(
+                    id='user',
+                    name='Username for the API server?',
+                    help='Username to use to connect to API Server',
+                    default='vsperf_sandbox',
+                ),
+                wiz.WizardStep(
+                    id='tdir',
+                    name='Path for Results Directory on API Server',
+                    help='Results Path on API Server',
+                    default='c:/ixia_results/vsperf_sandbox',
+                ),
+                wiz.WizardStep(
+                    id='rdir',
+                    name='Path for Results directory on DUT',
+                    help='DUT Results Path',
+                    default='/mnt/ixia_results/vsperf_sandbox',
+                ),
+            )
+        )
+
+    def guest_wizard(self):
+        """
+        Wizard to collect guest configuration
+        """
+        self.wiz_guest = wiz.PromptWizard(
+            name="Guest Configuration for PVP and PVVP Scenarios",
+            description="Guest configurations",
+            steps=(
+                wiz.WizardStep(
+                    id='image',
+                    name='Enter the Path for the iamge',
+                    help='Complete path where image resides',
+                    default='/home/opnfv/vloop-vnf-ubuntu-14.04_20160823.qcow2',
+                ),
+                wiz.WizardStep(
+                    id='mode',
+                    name='Enter the forwarding mode to use',
+                    help='one of io|mac|mac_retry|macswap|flowgen|rxonly|....',
+                    default='io',
+                ),
+                wiz.WizardStep(
+                    id='smp',
+                    name='Number of SMP to use?',
+                    help='While Spawning the guest, how many SMPs to use?',
+                    default='2',
+                ),
+                wiz.WizardStep(
+                    id='cores',
+                    name="Guest Core binding. For 2 cores a & b: ['a', 'b']",
+                    help='Enter the cores to use in the specified format',
+                    default="['8', '9']",
+                ),
+            )
+        )
+
+############### All the Run Operations ######################
+
+    def run_dutwiz(self):
+        """
+        Run the DUT wizard
+        """
+        self.dut_wizard()
+        self.dut_values = self.wiz_dut.run(self.shell)
+
+    def run_mainwiz(self):
+        """
+        Run the Main wizard
+        """
+        self.main_wizard()
+        self.main_values = self.wiz_main.run(self.shell)
+        print(self.main_values['nics'])
+
+    def run_vswitchwiz(self):
+        """
+        Run the vSwitch wizard
+        """
+        if self.main_values['vswitch'] == "OVS":
+            self.ovs_wizard()
+            self.ovs_values = self.wiz_ovs.run(self.shell)
+        elif self.main_values['vswitch'] == 'VPP':
+            self.vpp_wizard()
+            self.vpp_values = self.wiz_vpp.run(self.shell)
+
+    def run_trafficwiz(self):
+        """
+        Run the Traffic wizard
+        """
+        self.traffic_wizard()
+        self.traffic_values = self.wiz_traffic.run(self.shell)
+
+    def run_tgenwiz(self):
+        """
+        Run the Tgen wizard
+        """
+        if self.main_values['tgen'] == "Trex":
+            self.trex_wizard()
+            self.trex_values = self.wiz_trex.run(self.shell)
+        elif self.main_values['tgen'] == "TestCenter":
+            self.stc_wizard()
+            self.stc_values = self.wiz_stc.run(self.shell)
+        elif self.main_values['tgen'] == 'IxNet':
+            self.ixnet_wizard()
+            self.ixnet_values = self.wiz_ixnet.run(self.shell)
+
+    def run_guestwiz(self):
+        """
+        Run the Guest wizard
+        """
+        if self.main_values['guest'] == 'YES':
+            self.guest_wizard()
+            self.guest_values = self.wiz_guest.run(self.shell)
+
+################ Prepare Configuration File ##################
+    #pylint: disable=too-many-statements
+    def prepare_conffile(self):
+        """
+        Create the Configuration file that can be used with VSPERF
+        """
+        with open("./vsperf.conf", 'w+') as ofile:
+            ofile.write("#### This file is Automatically Created ####\n\n")
+            if self.main_values['vswitch'] == "OVS":
+                if self.ovs_values['type'] == "Vanilla":
+                    ofile.write("VSWITCH = 'OvsVanilla'\n")
+                else:
+                    ofile.write("VSWITCH = 'OvsDpdkVhost'\n")
+                    ofile.write("VSWITCH_PMD_CPU_MASK = '" +
+                                self.ovs_values['mask'] + "'\n")
+            else:
+                ofile.write("VSWITCH = 'VppDpdkVhost'\n")
+                ofile.write("VSWITCH_VPP_L2_CONNECT_MODE = '" +
+                            self.vpp_values['mode'] + "'\n")
+            nics = self.get_nics_string()
+            wln = "WHITELIST_NICS = [" + nics + "]" + "\n"
+            ofile.write(wln)
+            ofile.write("RTE_TARGET = 'x86_64-native-linuxapp-gcc'")
+            ofile.write("\n")
+            ofile.write("TRAFFICGEN = " + "'" + self.main_values['tgen'] + "'")
+            ofile.write("\n")
+            ofile.write("VSWITCH_BRIDGE_NAME = 'vsperf-br0'")
+            ofile.write("\n")
+            ofile.write("TRAFFICGEN_DURATION = " +
+                        self.traffic_values['duration'] + "\n")
+            ofile.write("TRAFFICGEN_LOSSRATE = 0" + "\n")
+            ofile.write("TRAFFICGEN_PKT_SIZES = (" +
+                        self.traffic_values['pktsizes'] +
+                        ")" + "\n")
+            if self.main_values['tgen'] == "Trex":
+                ofile.write("TRAFFICGEN_TREX_HOST_IP_ADDR = '" +
+                            self.trex_values['hostip'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_TREX_USER = '" +
+                            self.trex_values['user'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_TREX_BASE_DIR = '" +
+                            self.trex_values['bdir'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_TREX_LINE_SPEED_GBPS = '" +
+                            self.trex_values['rate'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_TREX_PORT1 = '" +
+                            self.trex_values['pci1'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_TREX_PORT2 = '" +
+                            self.trex_values['pci2'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_TREX_PROMISCUOUS = " +
+                            self.trex_values['prom'] + "\n")
+                ofile.write("TRAFFICGEN_TREX_LATENCY_PPS = " +
+                            self.trex_values['lat'] + "\n")
+                ofile.write("TRAFFICGEN_TREX_RFC2544_BINARY_SEARCH_LOSS_VERIFICATION = " +
+                            self.trex_values['bslv'])
+                ofile.write("TRAFFICGEN_TREX_MAX_REPEAT = " +
+                            self.trex_values['maxrep'] + "\n")
+            elif self.main_values['tgen'] == "TestCenter":
+                ofile.write("TRAFFICGEN_STC_LAB_SERVER_ADDR = '" +
+                            self.stc_values['lab'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_LICENSE_SERVER_ADDR = '" +
+                            self.stc_values['lisc'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_EAST_CHASSIS_ADDR = '" +
+                            self.stc_values['eaddr'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_EAST_SLOT_NUM = '" +
+                            self.stc_values['eslot'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_EAST_PORT_NUM = '" +
+                            self.stc_values['eport'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_EAST_INTF_ADDR = '" +
+                            self.stc_values['eint'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_EAST_INTF_GATEWAY_ADDR = '" +
+                            self.stc_values['egw'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_WEST_CHASSIS_ADDR = '" +
+                            self.stc_values['waddr'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_WEST_SLOT_NUM = '" +
+                            self.stc_values['wslot'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_WEST_PORT_NUM = '" +
+                            self.stc_values['wport'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_WEST_INTF_ADDR = '" +
+                            self.stc_values['wint'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_WEST_INTF_GATEWAY_ADDR = '" +
+                            self.stc_values['wgw'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_STC_RFC2544_TPUT_TEST_FILE_NAME = '" +
+                            self.stc_values['script'] + "'" + "\n")
+            elif self.main_values['tgen'] == 'IxNet':
+                print("IXIA Trafficgen")
+                # Ixia/IxNet configuration
+                ofile.write("TRAFFICGEN_IXIA_CARD = '" +
+                            self.ixnet_values['card'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXIA_PORT1 = '" +
+                            self.ixnet_values['port1'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXIA_PORT2 = '" +
+                            self.ixnet_values['port2'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXIA_LIB_PATH = '" +
+                            self.ixnet_values['libp1'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXNET_LIB_PATH = '" +
+                            self.ixnet_values['libp2'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXIA_HOST = '" +
+                            self.ixnet_values['host'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXNET_MACHINE = '" +
+                            self.ixnet_values['machine'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXNET_PORT = '" +
+                            self.ixnet_values['port'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXNET_USER = '" +
+                            self.ixnet_values['user'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXNET_TESTER_RESULT_DIR = '" +
+                            self.ixnet_values['tdir'] + "'" + "\n")
+                ofile.write("TRAFFICGEN_IXNET_DUT_RESULT_DIR = '" +
+                            self.ixnet_values['rdir'] + "'" + "\n")
+            if self.main_values['guest'] == 'YES':
+                ofile.write("GUEST_IMAGE = ['" +
+                            self.guest_values['image'] + "']" + "\n")
+                ofile.write("GUEST_TESTPMD_FWD_MODE = ['" +
+                            self.guest_values['mode'] + "']" + "\n")
+                ofile.write("GUEST_SMP = ['" +
+                            self.guest_values['smp'] + "']" + "\n")
+                ofile.write("GUEST_CORE_BINDING = [" +
+                            self.guest_values['cores'] + ",]" + "\n")
+
+
+def signal_handler(signum, frame):
+    """
+    Signal Handler
+    """
+    print("\n You interrupted, No File will be generated!")
+    print(signum, frame)
+    sys.exit(0)
+
+
+def main():
+    """
+    The Main Function
+    """
+    try:
+        vwiz = VsperfWizard()
+        vwiz.run_dutwiz()
+        vwiz.run_mainwiz()
+        vwiz.run_vswitchwiz()
+        vwiz.run_trafficwiz()
+        vwiz.run_tgenwiz()
+        vwiz.run_guestwiz()
+        vwiz.prepare_conffile()
+    except (KeyboardInterrupt, MemoryError):
+        print("Some Error Occured, No file will be generated!")
+
+    print("Thanks for using the VSPERF-WIZARD, Please look for vsperf.conf " +
+          "file in the current folder")
+
+
+if __name__ == "__main__":
+    signal.signal(signal.SIGINT, signal_handler)
+    main()