Lab-28:Deploying Openstack Mitaka in VirtualBox

For a long time I wanted to deploy Openstack in a Virtual box this became true after I purchased a new laptop with sufficient RAM

Precondition:

My laptop has Windows 7 64-bit, 16 GB RAM.

Download CentOS 7 virtual box image from this link. I downloaded 7.1-1511. Images come with usrname:osboxes, password:osboxes.org and root passward:oxboxes.org

Download virtualBox from this link.Start VirtualBox with CentOS image, I have given it 4 GB RAM

vb_mitaka

I have not changed network setting in VirtualBox, it is using default NAT mode. My VM came up with interface enp0s3 and IP address 10.0.2.15.

vb_mitaka_2

Make sure you can ping internet using domain name.

Follow below steps to prepare machine for Openstack deployment

Install yum-utils on both nodes

$yum install -y yum-utils

Set SELINUX in permissive mode on both nodes , edit file /etc/selinux/config

SELINUX=permissive

Disable Network Manager on both nodes

$systemctl disable NetworkManager

Disable firewall on both nodes

$systemctl disable firewalld

Perform update on both nodes

$yum update -y

reboot VM

$reboot

Set hostname

$hostnamectl set-hostname mitaka

Edit /etc/hosts with fqdn

[root@controller ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.2.15  mitaka.cloud.net mitaka

Try this link or below commands to install packstack

$sudo yum install -y centos-release-openstack-mitaka
$sudo yum update -y
$sudo yum install -y openstack-packstack

Procedure:

Start packstack with allinone. Details can be found in Lab-13:Deploying Openstack using packstack allinone

$packstack --allinone

After around 15 min you will see this message which mean installation is successful

vb_mitaka_3

Install firefox and launch Openstack Dashboard http://10.0.2.15/dashboard

vb_mitaka_4

Delete router and network gui from . Try below commands to create networks and spin a Virtual Machine

#. keystonerc_admin

#nova flavor-create m2.nano auto 128 1 1
#neutron net-create public --router:external=True

#neutron subnet-create --disable-dhcp public 172.254.209.0/24 \
--name public_subnet --allocation-pool start=172.254.209.87,end=172.254.209.95 --gateway-ip 172.254.209.126

#. keystonerc_demo

#neutron net-create demo
#neutron subnet-create --name demo_subnet \
 --dns-nameserver 8.8.8.8 demo 192.168.11.0/24

#neutron router-create pub_router
#neutron router-gateway-set pub_router public
#neutron router-interface-add pub_router demo_subnet

#ssh-keygen -f demo -t rsa -b 2048 -N ''
#nova keypair-add --pub-key demo.pub demo

#neutron security-group-rule-create --protocol icmp default
#neutron security-group-rule-create --protocol tcp \
 --port-range-min 22 --port-range-max 22 default

#neutron net-list
#nova boot --poll --flavor m2.nano --image cirros \
 --nic net-id=338382fa-908f-40a9-9bbc-5b8e96da10a5 --key-name demo demo_vm --security-groups default

 

vb_mitaka_5

 

 

 

Lab-27:Getting to know Selenium

In this lab I will show how to install and automate web gui testing using Selenium.

Selenium is a browser testing tool. Webdriver is a component of Selenium which provides native support for various browser types like Firefox,Chrome,IE etc. Using webdriver API testers can automate website testing.

Precondition:

I am using Ubuntu 14.04 LTS for this lab, it comes with Python 2.7.

Install Selenium and required packages.

$sudo apt-get install pip
$sudo pip install selenium
$sudo apt-get install firefox

Procedure:

Try basic python script to make sure packages are installed properly. This script will open Firefox browser, launch google.com website , print website title and close the browser.

$sjakhwal@rtxl3rld05:~$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from selenium import webdriver
>>> driver = webdriver.Firefox()
>>> driver.get('https://www.google.com')
>>> print driver.title
Google
>>> driver.close()
>>>

Element locator

Element locator is an important aspect of Selenium automation. The idea is to uniquely locate an element in the web page. Before you automate the  click  or fill a form you need to first locate the right button or box to fill in, webdriver provides library of functions to uniquely locate an element in the web page. You can locate element by name,id,link text,tag name and xpath. You need to check how to uniquely locate an element using any one of these functions

There are tools to decompose website and get element name, id, xpath etc. I have installed ‘firebug’ plugin in Firefox browser it allows me to check details of each element in the web site.

How to install firebug

Click on ‘Open menu’ selenium_2 icon in Firefox, it is located on upper right hand then click on ‘Add-ons’. In the search box type ‘firebug’ and hit enter. Click install ‘firebug’. Now  you can right click on an element and select ‘Inspect Element with Firebug’

Let’s try to uniquely locate search box in google.com website using different methods. Detail info can be find here

In the google.com search box click right button and select ‘Inspect Element with Firebug’ you will see search box element highlighted in the button part of the screen.

selenium_5

By element name

The name of search box element is “q” (name=”q”).  Let’s try this to locate search box in python using webdriver API

This script locates element by name “q” and type search query “life divine” in the search box

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys
>>> driver = webdriver.Firefox()
>>> driver.get('https://www.google.com')
>>> print driver.title
Google
>>> search_element = driver.find_element_by_name("q")
>>> search_element.send_keys("life divine")
>>> search_element.send_keys(Keys.RETURN)
>>> driver.close()
>>>

By id

selenium_4

The id of search element is “lst-ib” (id=”lst-ib”).

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys

>>> driver = webdriver.Firefox() 
>>> driver.get('https://www.google.com') 
>>> print driver.title 
Google
>>> search_element = driver.find_element_by_id("lst-ib")
>>> search_element.send_keys("life divine")
>>> search_element.send_keys(Keys.RETURN)
>>> driver.close()

By link text

Link text is a visible text for a link. When you search for “life divine” on google the first link with link text is “The Life Divine: Sri Aurobindo: 9788170588443: Amazon.com: Books”. Below script uses this text to identify first link and click on it

If you don’t want to type whole link text, ‘find_element_by_partial_link_text’ can be used with partial string to match

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys

>>> driver = webdriver.Firefox() 
>>> driver.get("https://www.google.com")
>>> search_element = driver.find_element_by_id("lst-ib")
>>> search_element.send_keys("life divine")
>>> search_element.send_keys(Keys.RETURN)
>>> driver.find_element_by_link_text("The Life Divine: Sri Aurobindo: 9788170588443: Amazon.com: Books").click()
>>> print driver.title
The Life Divine: Sri Aurobindo: 9788170588443: Amazon.com: Books
>>> driver.close()

By Xpath

Below example of xpath locator, // means relative path

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys

>>> driver = webdriver.Firefox() 
>>> driver.get("https://www.google.com")
>>> search_element = driver.find_element_by_xpath("//input[@id='lst-ib']")
>>> search_element.send_keys("life divine")
>>> search_element.send_keys(Keys.RETURN)
>>> print driver.title
life divine - Google Search
>>> driver.close()

By css

In css locator ‘#’ represents element Id and ‘.’ represents element class.

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys

>>> driver = webdriver.Firefox() 
>>> driver.get("https://www.google.com")
>>> search_element = driver.find_element_by_css_selector('input#lst-ib')
>>> search_element.send_keys("life divine")
>>> search_element.send_keys(Keys.RETURN)
>>> print driver.title
life divine - Google Search
>>> driver.close()

or you can try css for class
>>> search_element = driver.find_element_by_css_selector('input.gsfi')

Headless browser

It is annoying and slow to have browser open every time you run the script. You can run browser in the background or headless by using PhantomJS.

$cd /usr/local/bin
$sudo wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
$sudo tar xjf phantomjs-2.1.1-linux-x86_64.tar.bz2
$sudo ln -s /usr/local/bin/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs

After phantomJS installed run script like this. The disadvantage of this approach is you rely on phantomJS browser you loose capability to test with different web browsers

sjakhwal@rtxl3rld05:~$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from selenium import webdriver
>>> driver = webdriver.PhantomJS()
>>> driver.set_window_size(1120, 550)
>>> driver.get('https://www.google.com')
>>> print driver.title
Google
>>> driver.close()

Remote webserver

Remote webserver provides capability to access a web gui from remote PC.

You need to download and install webserver sw on the machine where web gui resides.

Why you need webserver, in my case company firewall was blocking the port number (8443) of web gui  and I couldn’t launch it from my local machine. I had two options 1) run scripts on same machine where web gui was installed or 2) use webserver and run scripts from my local machine. I chose option 2.

Below are commands to install webserver. In this case I am running webserver in a CentOS 7 machine (my web gui application resides in this machine). The machine IP address is 172.254.211.167

$sudo wget http://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.0.jar
$yum install xorg-x11-server-Xvfb
$sudo yum install java-1.7.0-openjdk
$/usr/bin/Xvfb :1 -screen 0 1024x768x24 &
$export DISPLAY=:1     
$java -jar ~/selenium/selenium-server-standalone-2.53.0.jar

[root@localhost ~]# java -jar /home/labuser1/selenium-server-standalone-2.53.0.jar
12:58:47.562 INFO - Launching a standalone Selenium Server
12:58:47.587 INFO - Java: Oracle Corporation 25.60-b23
12:58:47.588 INFO - OS: Linux 3.10.0-123.el7.x86_64 amd64
12:58:47.596 INFO - v2.53.0, with Core v2.53.0. Built from revision 35ae25b
12:58:47.646 INFO - Driver provider org.openqa.selenium.ie.InternetExplorerDriver registration is skipped:
registration capabilities Capabilities [{ensureCleanSession=true, browserName=internet explorer, version=, platform=WINDOWS}] does not match the current platform LINUX
12:58:47.646 INFO - Driver provider org.openqa.selenium.edge.EdgeDriver registration is skipped:
registration capabilities Capabilities [{browserName=MicrosoftEdge, version=, platform=WINDOWS}] does not match the current platform LINUX
12:58:47.647 INFO - Driver class not found: com.opera.core.systems.OperaDriver
12:58:47.647 INFO - Driver provider com.opera.core.systems.OperaDriver is not registered
12:58:47.648 INFO - Driver provider org.openqa.selenium.safari.SafariDriver registration is skipped:
registration capabilities Capabilities [{browserName=safari, version=, platform=MAC}] does not match the current platform LINUX
12:58:47.648 INFO - Driver class not found: org.openqa.selenium.htmlunit.HtmlUnitDriver
12:58:47.648 INFO - Driver provider org.openqa.selenium.htmlunit.HtmlUnitDriver is not registered
12:58:47.690 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
12:58:47.690 INFO - Selenium Server is up and running

This is how to write script on your local machine to access remote web gui. My remote web server IP address is 172.254.211.167. You need to replace the web gui url

sjakhwal@rtxl3rld05:~$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from selenium import webdriver

>> driver = webdriver.Remote(desired_capabilities=webdriver.DesiredCapabilities.FIREFOX,\
command_executor='http://172.254.211.167:4444/wd/hub')
>>> driver.get('https://localhost:8443/virtuoranc/index.html')
>>> print driver.title
Virtuora NC
>>> driver.close()

Wait

If you get into a situation where website is not fully loaded yet and your script tries to locate element and eventually fails. You can either put a hard coded sleep in the script or use more intelligent wait mechanism. Selenium supports two types of waits 1)Explicit 2)Implicit. In case of explicit wait you tell webdriver to wait for a certain event and for certain time before proceeding. Detail explanation can be found here

Below example script is for Explicit wait. In this script webdriver waits for link text “Life Divine” to be present before clicking on the link. Script waits for 10 sec for the presence of  link text . Expected conditions link

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys
>>> from selenium.webdriver.support.ui import WebDriverWait
>>> from selenium.webdriver.support import expected_conditions as EC
>>> from selenium.webdriver.common.by import By
>>> driver = webdriver.Firefox() 
>>> driver.get("https://www.google.com") 
>>> search_element = driver.find_element_by_id("lst-ib") 
>>> search_element.send_keys("life divine") 
>>> search_element.send_keys(Keys.RETURN)
>>> try:
>>>     WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.PARTIAL_LINK_TEXT,"Life Divine")))
>>> finally:
>>>     driver.close()
>>>     exit 
>>> driver.find_element_by_partial_link_text("The Life Divine: Sri Aurobindo:").click() 
>>> print driver.title The Life Divine: Sri Aurobindo: 9788170588443: Amazon.com: Books 
>>> driver.close()

Below example script for implicit wait. Implicit wait is poll based, all find element APIs waits for implicit wait timer to timeout before proceeding to next step. Default implicit timer is 0.

In this case implicit timer is set to 10 sec

>>> from selenium import webdriver
>>> from selenium.webdriver.common.keys import Keys

>>> driver = webdriver.Firefox() 
>>> driver.implicitly_wait(10)
>>> driver.get("https://www.google.com") 
>>> search_element = driver.find_element_by_id("lst-ib") 
>>> search_element.send_keys("life divine") 
>>> search_element.send_keys(Keys.RETURN)
>>> driver.find_element_by_partial_link_text("The Life Divine: Sri Aurobindo:").click() 
>>> print driver.title 
The Life Divine: Sri Aurobindo: 9788170588443: Amazon.com: Books 
>>> driver.close()

Selenium IDE

Last but not least Firefox provides Selenium IDE  which can capture mouse clicks, keyboard actions, basically any action you perform in a website. You can save these actions as test cases and later replay them  or even export them as Python,Java or Ruby script .

Download Selenium IDE for Firefox

Go to this link and download/add Selenium IDE to your Firefox. Restart Firefox, you will see Selenium IDE under your tools menu. Click on Selenium IDE to start it

Click this link to watch a youtube video on it.

 

References:

https://www.seleniumeasy.com/selenium-tutorials

https://cse.google.com/cse?cx=partner-pub-4494420772031453:2717605672&ie=UTF-8&q=selenium&sa=Search&ref=www.softwaretestinghelp.com/#gsc.tab=0&gsc.q=selenium&gsc.page=1

 

 

 

Lab-26:Openstack Mitaka deployment using Packstack

In this lab I will deploy Openstack Mitaka release using packstack.I am using CentOS 7. This is a two machine setup, one machine acting as controller/network node and another as compute node. Try this link to check my openstack liberty lab

This is the physical connection picture. Both machines are connected to public network through enp1s0 and to each other through ens5 interface

openstack-mitaka_1

Here is my CentOS version. I have installed CentOS fresh on both machines

# cat /etc/*elease
CentOS Linux release 7.2.1511 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.2.1511 (Core)
CentOS Linux release 7.2.1511 (Core)

# hostnamectl
   Static hostname: controller
         Icon name: computer-desktop
           Chassis: desktop
        Machine ID: 6caa245df306434f834b611245c899a0
           Boot ID: 58195ec254e049d98c1eb5a19930e182
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-327.18.2.el7.x86_64
      Architecture: x86-64
[root@controller ~]#

Try below commands to prep for installation.

Login as root

$su -

Install yum-utils on both nodes

$yum install -y yum-utils

Set SELINUX in permissive mode on both nodes , edit file /etc/selinux/config

SELINUX=permissive

disable Network Manager on both nodes

$systemctl disable NetworkManager

Disable firewall on both nodes

$systemctl disable firewalld

Perform update on both nodes

$yum update -y

reboot both nodes

$reboot

Set hostname on controller and compute node. Set one machine as controller another as compute

$hostnamectl set-hostname controller
$hostnamectl set-hostname compute

Edit /etc/hosts on both nodes with fqdn

[root@controller ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.0.1  controller.cloud.net controller
10.10.0.10  compute.cloud.net compute

Set controller IP address as 10.10.0.1 and compute node IP as 10.10.0.10. This is my ens5 file dump from controller node

[root@controller network-scripts]# cat ifcfg-ens5
HWADDR=00:0A:CD:2A:14:08
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=no
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=ens5
UUID=4be61b9d-2daf-4497-a6dd-fe3a809e45e2
ONBOOT=yes
IPADDR=10.10.0.1
PREFIX=24

Try this link and below commands to install packstack

$sudo yum install -y centos-release-openstack-mitaka
$sudo yum update -y
$sudo yum install -y openstack-packstack

Generate answer file for packstack

$packstack --gen-answer-file=multi-node-mitaka.txt

Edit answer file to customize it. These are the changes I have made to my answer file, nothing fancy

CONFIG_CONTROLLER_HOST=10.10.0.1
CONFIG_COMPUTE_HOSTS=10.10.0.10
CONFIG_NETWORK_HOSTS=10.10.0.1
CONFIG_SWIFT_INSTALL=n
CONFIG_CINDER_INSTALL=n
CONFIG_CONTROLLER_HOST=10.10.0.1
CONFIG_COMPUTE_HOSTS=10.10.0.10
CONFIG_NETWORK_HOSTS=10.10.0.1
CONFIG_LBAAS_INSTALL=y
CONFIG_NEUTRON_FWAAS=y
CONFIG_NEUTRON_OVS_TUNNEL_IF=ens5

Start packstack with newly created answer file

$packstack --answer-file multi-node-mitaka.txt

##It takes about 15-20 min, on successful installation you will see this message

**** Installation completed successfully ******

Additional information:

 * Time synchronization installation was skipped. Please note that unsynchronized time on server instances might be problem for some OpenStack components.
 * File /root/keystonerc_admin has been created on OpenStack client host 10.10.0.1. To use the command line tools you need to source the file.
 * To access the OpenStack Dashboard browse to http://10.10.0.1/dashboard .
Please, find your login credentials stored in the keystonerc_admin in your home directory.
 * To use Nagios, browse to http://10.10.0.1/nagios username: nagiosadmin, password: f96c84b4884d45a4
 * The installation log file is available at: /var/tmp/packstack/20160516-184147-03uUsE/openstack-setup.log
 * The generated manifests are available at: /var/tmp/packstack/20160516-184147-03uUsE/manifests

On you browser point to http://10.10.0.1/dashboard, login to Horizon GUI using username ‘admin’ and password from file ‘keystaonerc_admin’ (packstack creates this file in the directory from where you started the packstack in my case under /root). First thing you need to do is  delete router and network, we will create router and network from scratch.

openstack-mitaka

On the terminal try below commands. I ran these commands from /root directory. Packstack created two resource files keystonetc_admin and keystonerc_demo

#source admin resource file
. keystonerc_admin

#create new flavor
nova flavor-create m2.nano auto 128 1 1

#create public network
neutron net-create public --router:external=True

#create public subnet 
neutron subnet-create --disable-dhcp public 172.254.209.0/24 \
--name public_subnet --allocation-pool start=172.254.209.87,end=172.254.209.95 --gateway-ip 172.254.209.126

#create public router
neutron router-create pub_router

#add router interface to public network
neutron router-gateway-set pub_router public

#create Tenant1
keystone tenant-create --name Tenant1

#source demo resource file
. keystonerc_demo

#create Tenant1 network
neutron net-create Tenant1_net

#create Tenant1 subnet
neutron subnet-create --name Tenant1_subnet \
   --dns-nameserver 8.8.8.8 Tenant1_net 192.168.11.0/24

#genrate ssh keypair
ssh-keygen -f tenant1_rsa -t rsa -b 2048 -N ''

#add keypair 
nova keypair-add --pub-key tenant1_rsa.pub tenant1

#create a new security group
neutron security-group-create mysec

#set rule to allow ssh & icmp
neutron security-group-rule-create --protocol icmp mysec
neutron security-group-rule-create --protocol tcp \
  --port-range-min 22 --port-range-max 22 mysec

#create a new instance, net-id is Tenant1 net-id
nova boot --poll --flavor m2.nano --image cirros \
   --nic net-id=535659e3-2c4d-4ccd-a05f-6b03cd29e9b0 --key-name tenant1 Tenant1_VM1 --security-groups mysec

#check if Tenant1 instance is running
[root@controller ~(keystone_demo)]# nova list
+--------------------------------------+-------------+--------+------------+-------------+--------------------------+
| ID                                   | Name        | Status | Task State | Power State | Networks                 |
+--------------------------------------+-------------+--------+------------+-------------+--------------------------+
| 7f95ec40-3945-445b-aeba-fcdbf5f8b99e | Tenant1_VM1 | ACTIVE | -          | Running     | Tenant1_net=192.168.11.3 |
+--------------------------------------+-------------+--------+------------+-------------+--------------------------+
[root@controller ~(keystone_demo)]#

Observations:

When I tried packstack with ceilometer disabled (CONFIG_CEILOMETER_INSTALL=n) it failed with this error but after changing CONFIG_CEILOMETER_INSTALL=y things worked fine (default is ‘y’). This is a known issue in Mitaka

167.254.209.85_mariadb.pp:                        [ ERROR ]
Applying Puppet manifests                         [ ERROR ]

ERROR : Error appeared during Puppet run: 167.254.209.85_mariadb.pp
Error: Could not find data item CONFIG_GNOCCHI_DB_PW in any Hiera data file and no default supplied at /var/tmp/packstack/45cb2ad222434ebe94634bcedb3510b5/manifests/167.254.209.85_mariadb.pp:121 on node controller.cloud.net

 

Lab-24:Lab infrastructure automation using CloudShell

I recently worked in a lab infrastructure automation project. Goal was to automate fiber connections between network elements (NE) and traffic generators, so to quickly spinoff different customer topology.

These are some of the issues we try to resolve using lab infrastructure automation:

  1. Reduce network re-configuration time. Too much time spend on re-configuring network, fibering, de-fibering , debugging wrong connections etc.
  2. Maximizing HW utilization. Groups hoarding the HW, not sharing HW fearing they will never get it back or they need to tear down and start from scratch
  3. Equipment sharing. Not knowing whether HW is activity used or not, difficult to share
  4. Remote development and testing support.

Walk around the lab and you will find these notes to shoo away engineers. Sometimes these notes remain hanging on the equipment  well after project is over, no one knows whether equipment is being actively used or sitting ideal.

cloudshell-1cloudshell-2

Let’s see what is needed to automate lab infrastructure.

Optical switch

The purpose of optical switch is to provide L1 connectivity between network elements and traffic generators. In our case it’s  an all optical switch (not electrical-optical-electrical) which using mirrors  directs light from one port to another port based on topology configuration. Optical switch avoids static fiber connections between NE and traffic generators and gives flexibility to change connections on demand without touching fibers, this is really beneficial  feature for remote teams they no longer depends on onsite team for lab support

We connected network elements and traffic generators to optical switch. Not all ports from network elements needs to be connected to optical switch. You need to decide which ports participate in network re-configuration only those needs to be connected to optical switch. Remaining connections can be static / hard wired.

Our optical switch is a passive switch it can take any signal rate with minimum power loss. In our case signals ranges from 1 Gig ,10Gig, 100 Gig (DWDM)

We used Calient S-series all optical switch, check this link to learn more about the switch

CloudShell

CloudShell  provides by Qualisystems is a lab infrastructure automation platform. It manages optical switch for you, keeps track of your resources (NEs) and give a gui based tool to create network topology. Check out more on CloudShell here

We used CloudShell resource management and lab management functions. It has built-in drivers to manage different vendors optical switches, in our case Calient switch. Resource management provides database for managed resources. Lab management provides GUI tool to build network topology . CloudShell comes with Python based API. Using API you can automate to create topology, create/release reservation and push topology to optical switch on demand.

CloudShell is optional but in that case you need build your own infrastructure to program optical switch, manage resources etc.

Here are the steps to create CloudShell based automation. I won’t go into detail how resources are managed.

Step-1:

Add all your HW resources into CloudShell RM (Resource Management). If you have existing database ClouldShell can integrate it or you can use ClouldShell RM. . You need to provide physical characteristics of your HW resources, like number of ports, unique identifier etc, this info is needed when you create topology

Step-2:

Connect  network elements and traffic generators ports  to optical switch and create a mapping table in CloudShell RM between network element and optical switch. Basically telling CloudShell which network element port connected to which optical switch port. This info is needed to build topology

Step-3

In the CloudShell lab management build your topology. This is a drag and drop GUI based tool. You drag your network elements & traffic generators  from CloudShell RM to a blank canvas and create links between ports. After you are done save the topology. At this point you can either reserve and activate topology manually or use automation. CloudShell comes with Python API to assist in topology reservation & activation. During reservation you specify how long the topology needs to be active. When activated CloudShell push topology connections details into optical switch which in turns creates internal cross connection between ports. At the expiry of timer topology is released and all cross connections on optical switch are cleared.

.

cloudshell

This is the logical diagram of our setup.Here we are creating a linear topology of 4 network elements  with traffic generators connected to two NEs. If required we can free up two NEs without any fiber re-configuration.

We have created two routines using CloudShell Python API 1)reserve & activate the topology  2)release the topology. These routines are part of our setup & teardown function.

Below is a sample Python code showing how to reserve  topology, activate topology and release topology

import getopt
import sys
from qualipy.api.cloudshell_api import CloudShellAPISession
def usage():
        print "Usage:"
        print "-d: [domain]                                     Domain name"
        print "-h:                                              help"
        print "-t: <topology>                                   Reserve"
        print "-r: <topology>                                   Release"
        print "lbaas -t <topology> -d global To reserve topology"
        print "lbaas -r <topology> -d global To release topology"


def get_reservationId(responseObject,topology):

        for attr, value in responseObject.__dict__.iteritems():
                for val in value:
                        topo1 = val.Topologies[0]
                        topo2 = topo1.split("/",2)
                        topo = topo2[2]
                        if topo == topology:
                                return val.Id

def release_topo(myTS,topology,username):

        responseInfo=myTS.GetCurrentReservations(reservationOwner=username)
        reservation_id = get_reservationId(responseInfo,topology)
        #print reservation_id
        myTS.EndReservation(reservation_id , unmap=0 )

def main(argv):
        cs_server='xxx.yyy.132.78'
        username='admin'
        password='admin'
        domain='Global'
        topologyFullPath='Topologies/'
        try:
                opts,args = getopt.getopt(argv,"d:ht:r:",["help","domain=","topology=","release="])

        except getopt.GetoptError:
                usage()
                sys.exit(2)

        if not opts:
                usage()
                sys.exit()

        for opt, arg in opts:
                if opt in ("-h","--help"):
                        usage()
                        sys.exit()
                elif opt in ("-d","--domain"):
                        domain= arg
                elif opt in ("-t","--topology"):
                        topology= arg
                elif opt in ("-r","--release"):
                        topology= arg
                        myTS=CloudShellAPISession(cs_server,username,password,domain)
                        release_topo(myTS,arg,username)
                        sys.exit()

        topologyWithPath= topologyFullPath + topology
        print "Topology=%s" % topology
        myTS=CloudShellAPISession(cs_server,username,password,domain)

        responseInfo=myTS.CreateImmediateReservation(reservationName=topology , owner=username , durationInMinutes=60 , notifyOnStart = False, notifyOnEnd = False, notificationMinutesBeforeEnd = 0)
        reservationId=responseInfo.Reservation.Id

        myTS.AddTopologyToReservation(reservationId , topologyWithPath , globalInputs = [], requirementsInputs = [], additionalInfoInputs = [])
        myTS.ActivateTopology(reservationId , topologyWithPath )

if __name__=="__main__":
    main(sys.argv[1:])

sjakhwal@rtxl3rld05:~/cloudshell$
sjakhwal@rtxl3rld05:~/cloudshell$ ./lbaas.py
Usage:
-d: [domain]                                    Domain name
-h:                                             help
-t: <topology>                                  Reserve
-r: <topology>                                  Release
lbaas -t <topology> -d global        To reserve topology
lbaas -r <topology> -d global        To release topology
sjakhwal@rtxl3rld05:~/cloudshell$