Initial checkin of EopenECOMP testsuite 27/727/1
authorDR695H <dr695h@att.com>
Fri, 17 Feb 2017 23:44:24 +0000 (18:44 -0500)
committerDR695H <dr695h@att.com>
Fri, 17 Feb 2017 23:44:41 +0000 (18:44 -0500)
Change-Id: I64a2b6d8cf66169829866b73b3d26a4ff59b0a42
Signed-off-by: DR695H <dr695h@att.com>
118 files changed:
.gitignore [new file with mode: 0644]
.project [new file with mode: 0644]
.pydevproject [new file with mode: 0644]
LICENSE.TXT [new file with mode: 0644]
README.md [new file with mode: 0644]
dnstraffic.sh [new file with mode: 0644]
docker/Dockerfile [new file with mode: 0644]
docker/lighttpd.conf [new file with mode: 0644]
docker/robot_vm_init.sh [new file with mode: 0644]
html/index.html [new file with mode: 0644]
red.xml [new file with mode: 0644]
robot/assets/asdc/.gitignore [new file with mode: 0644]
robot/assets/asdc/base_vfw/MANIFEST.json [new file with mode: 0644]
robot/assets/asdc/base_vfw/base_vfw.env [new file with mode: 0644]
robot/assets/asdc/base_vfw/base_vfw.yaml [new file with mode: 0644]
robot/assets/asdc/base_vlb/MANIFEST.json [new file with mode: 0644]
robot/assets/asdc/base_vlb/base_vlb.env [new file with mode: 0644]
robot/assets/asdc/base_vlb/base_vlb.yaml [new file with mode: 0644]
robot/assets/asdc/base_vlb/dnsscaling.env [new file with mode: 0644]
robot/assets/asdc/base_vlb/dnsscaling.yaml [new file with mode: 0644]
robot/assets/asdc/base_vvg/MANIFEST.json [new file with mode: 0644]
robot/assets/asdc/base_vvg/base_vvg.env [new file with mode: 0644]
robot/assets/asdc/base_vvg/base_vvg.yaml [new file with mode: 0644]
robot/assets/dcae/dcae_healthcheck.json [new file with mode: 0644]
robot/assets/keys/ecompdemo.pvt [new file with mode: 0644]
robot/assets/keys/robot_ssh_private_key.ppk [new file with mode: 0644]
robot/assets/keys/robot_ssh_private_key.pvt [new file with mode: 0644]
robot/assets/keys/robot_ssh_public_key.pub [new file with mode: 0644]
robot/assets/keys/robot_ssh_public_key.txt [new file with mode: 0644]
robot/assets/service_mappings.py [new file with mode: 0644]
robot/assets/templates/aai/add_cloud_region_body.template [new file with mode: 0644]
robot/assets/templates/aai/add_customer.template [new file with mode: 0644]
robot/assets/templates/aai/add_service_body.template [new file with mode: 0644]
robot/assets/templates/aai/add_tenant_body.template [new file with mode: 0644]
robot/assets/templates/aai/named_query.template [new file with mode: 0644]
robot/assets/templates/aai/service_subscription.template [new file with mode: 0644]
robot/assets/templates/aai/vlb_closed_loop_hack.template [new file with mode: 0644]
robot/assets/templates/appc/vnf_mount.template [new file with mode: 0644]
robot/assets/templates/asdc/action.template [new file with mode: 0644]
robot/assets/templates/asdc/catalog_resource.template [new file with mode: 0644]
robot/assets/templates/asdc/catalog_service.template [new file with mode: 0644]
robot/assets/templates/asdc/entitlement_pool.template [new file with mode: 0644]
robot/assets/templates/asdc/feature_group.template [new file with mode: 0644]
robot/assets/templates/asdc/key_group.template [new file with mode: 0644]
robot/assets/templates/asdc/license_agreement.template [new file with mode: 0644]
robot/assets/templates/asdc/license_model.template [new file with mode: 0644]
robot/assets/templates/asdc/resource_instance.template [new file with mode: 0644]
robot/assets/templates/asdc/software_product.template [new file with mode: 0644]
robot/assets/templates/asdc/user_remarks.template [new file with mode: 0644]
robot/assets/templates/cinder_add_volume.template [new file with mode: 0644]
robot/assets/templates/heat_add_stack.template [new file with mode: 0644]
robot/assets/templates/keystone_get_auth.template [new file with mode: 0644]
robot/assets/templates/neutron_add_network.template [new file with mode: 0644]
robot/assets/templates/neutron_add_subnet.template [new file with mode: 0644]
robot/assets/templates/nova_add_keypair.template [new file with mode: 0644]
robot/assets/templates/nova_add_server.template [new file with mode: 0644]
robot/assets/templates/policy/closedloop_configpolicy.template [new file with mode: 0644]
robot/assets/templates/policy/closedloop_createpolicy.template [new file with mode: 0644]
robot/assets/templates/policy/closedloop_deletepolicy.template [new file with mode: 0644]
robot/assets/templates/policy/closedloop_getconfigpolicy.template [new file with mode: 0644]
robot/assets/templates/policy/closedloop_opspolicy.template [new file with mode: 0644]
robot/assets/templates/policy/closedloop_pushpolicy.template [new file with mode: 0644]
robot/assets/templates/sdnc/dnsscaling_preload.template [new file with mode: 0644]
robot/assets/templates/sdnc/vfw_preload.template [new file with mode: 0644]
robot/assets/templates/sdnc/vlb_preload.template [new file with mode: 0644]
robot/assets/templates/sdnc/vvg_preload.template [new file with mode: 0644]
robot/assets/templates/template_example.template [new file with mode: 0644]
robot/assets/templates/vfw_pg_stream_enable.template [new file with mode: 0644]
robot/assets/templates/vfw_pg_streams_enable.template [new file with mode: 0644]
robot/resources/aaf_interface.robot [new file with mode: 0644]
robot/resources/aai/aai_interface.robot [new file with mode: 0644]
robot/resources/aai/create_customer.robot [new file with mode: 0644]
robot/resources/aai/create_service.robot [new file with mode: 0644]
robot/resources/aai/create_tenant.robot [new file with mode: 0644]
robot/resources/aai/network.robot [new file with mode: 0644]
robot/resources/aai/service_instance.robot [new file with mode: 0644]
robot/resources/aai/volume_group.robot [new file with mode: 0644]
robot/resources/appc_interface.robot [new file with mode: 0644]
robot/resources/asdc_interface.robot [new file with mode: 0644]
robot/resources/browser_setup.robot [new file with mode: 0644]
robot/resources/dcae_interface.robot [new file with mode: 0644]
robot/resources/global_properties.robot [new file with mode: 0644]
robot/resources/heatbridge.robot [new file with mode: 0644]
robot/resources/json_templater.robot [new file with mode: 0644]
robot/resources/mr_interface.robot [new file with mode: 0644]
robot/resources/mso_interface.robot [new file with mode: 0644]
robot/resources/openstack/cinder_interface.robot [new file with mode: 0644]
robot/resources/openstack/heat_interface.robot [new file with mode: 0644]
robot/resources/openstack/keystone_interface.robot [new file with mode: 0644]
robot/resources/openstack/neutron_interface.robot [new file with mode: 0644]
robot/resources/openstack/nova_interface.robot [new file with mode: 0644]
robot/resources/openstack/openstack_common.robot [new file with mode: 0644]
robot/resources/policy_interface.robot [new file with mode: 0644]
robot/resources/portal_interface.robot [new file with mode: 0644]
robot/resources/sdngc_interface.robot [new file with mode: 0644]
robot/resources/ssh/files.robot [new file with mode: 0644]
robot/resources/ssh/processes.robot [new file with mode: 0644]
robot/resources/stack_validation/darkstat_interface.robot [new file with mode: 0644]
robot/resources/stack_validation/packet_generator_interface.robot [new file with mode: 0644]
robot/resources/stack_validation/policy_check_vfw.robot [new file with mode: 0644]
robot/resources/stack_validation/validate_common.robot [new file with mode: 0644]
robot/resources/stack_validation/validate_dns_scaling.robot [new file with mode: 0644]
robot/resources/stack_validation/validate_vfw.robot [new file with mode: 0644]
robot/resources/stack_validation/validate_vlb.robot [new file with mode: 0644]
robot/resources/stack_validation/validate_vvg.robot [new file with mode: 0644]
robot/resources/test_templates/closedloop_test_template.robot [new file with mode: 0644]
robot/resources/test_templates/model_test_template.robot [new file with mode: 0644]
robot/resources/test_templates/vnf_orchestration_test_template.robot [new file with mode: 0644]
robot/resources/vid/create_service_instance.robot [new file with mode: 0644]
robot/resources/vid/create_vid_vnf.robot [new file with mode: 0644]
robot/resources/vid/teardown_vid.robot [new file with mode: 0644]
robot/resources/vid/vid_interface.robot [new file with mode: 0644]
robot/testsuites/closed-loop.robot [new file with mode: 0644]
robot/testsuites/health-check.robot [new file with mode: 0644]
robot/testsuites/model-distribution.robot [new file with mode: 0644]
robot/testsuites/vnf-orchestration.robot [new file with mode: 0644]
runTags.sh [new file with mode: 0644]
setup.sh [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..44bdbba
--- /dev/null
@@ -0,0 +1,8 @@
+/log.html
+/output.xml
+/report.html
+/selenium-screenshot-*.png
+*.pyc
+/libspecs/
+/geckodriver.log
+/robot/library/
\ No newline at end of file
diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..3eaf994
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>ete-testsuite</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.python.pydev.PyDevBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.robotframework.ide.eclipse.main.plugin.robotLibrariesBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.robotframework.ide.eclipse.main.plugin.robotNature</nature>
+               <nature>org.python.pydev.pythonNature</nature>
+       </natures>
+</projectDescription>
diff --git a/.pydevproject b/.pydevproject
new file mode 100644 (file)
index 0000000..ec77600
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/${PROJECT_DIR_NAME}/robot/library</path>
+</pydev_pathproperty>
+</pydev_project>
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644 (file)
index 0000000..4aa836c
--- /dev/null
@@ -0,0 +1,25 @@
+ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property.
+
+LICENSE.TXT file can be appended as follows:
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * 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.
+ * ============LICENSE_END============================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..1565912
--- /dev/null
+++ b/README.md
@@ -0,0 +1,114 @@
+# Getting Started
+## Development Environment Setup
+### Python Installation
+You should install 2.7.12: [https://www.python.org/downloads/release/python-2712](https://www.python.org/downloads/release/python-2712)
+
+
+### Pip Install
+Install pip with the get-pip.py file from [https://bootstrap.pypa.io/get-pip.py](https://bootstrap.pypa.io/get-pip.py)
+once downloaded run
+
+```
+python get-pip.py
+```
+let it install.
+
+From the desktop, right click the Computer icon.
+Choose Properties from the context menu.
+Click the Advanced system settings link.
+Click Environment Variables. In the section System Variables, click New.
+In the New System Variable window, set the name as 'HTTPS\_PROXY' then specify the value of the HTTPS_PROXY environment variable as your proxy. 
+Click OK. 
+Close all remaining windows by clicking OK.
+
+
+### Robot Install
+Reopen Command prompt window, and run below code to install robot.
+
+```
+pip install robotframework
+```
+
+
+### IDE Install
+Most further documents will use the RED environment for Robot.
+[https://github.com/nokia/RED/releases/download/0.7.0/RED\_0.7.0.20160914115048-win32.win32.x86_64.zip](https://github.com/nokia/RED/releases/download/0.7.0/RED\_0.7.0.20160914115048-win32.win32.x86_64.zip)
+
+Once you install that IDE you probably will want to have a python editor to edit python files better.
+Go to Help > Eclipse Marketplace and search for PyDev and click install on PyDev for Eclipse 5.2.0
+
+Once you install that IDE you will need EGit to check in git code.
+Go to Help > Eclipse Marketplace and search for Egit git team provider and click install on EGit Git Team Provider 4.5.0
+
+Once you install that IDE you will probably want a json editor to edit json better.
+Go to Help > Eclipse Marketplace and search for Json Tools and click install on Json Tools 1.1.0
+
+### Project Setup
+Note: You do not need to run these commands every time, only on a library update or initial checkout.
+
+```
+./setup.sh  
+```
+
+Note that this script will download the chromedriver for the current OS. The default is linux64 which will download the appropriate chromedriver to /usr/local/bin so that it will be in the execution PATH.
+
+Windows and Mac hosts will download into the current working directory. Windows and MAC users will need to ensure that the driver is 
+in the execution PATH.
+
+
+## Robot Project Structure
+### Overview
+ProjectName - robot
+
+```
+`-- robot
+    |-- assets - put anything you need as input like json files, cert keys, heat templates
+    |   |-- templates - put any json templates in here, you can include subfolders for each component
+    |-- library - put any python libraries need to run tests in here
+    |   |-- OpenECOMP - put any python code libraries we write in here
+    |-- resources - put any robot resource files aka libraries we write in here
+    |   |-- aai
+    |   `-- vid
+    `-- testsuites - put any robot test suites we write in here
+```    
+
+### Tag Strucutre
+Robot uses tags to seperate out test cases to run. below are the tags we use
+
+* garbage - use this for test cases that should be cleaned up before go live date
+* health - use this for test cases that perform a health check of the environment
+* smoke - use this for test cases that perform a basic check of a component
+* ete - use this for the test cases that are perofrming an end to end test
+
+## Branching Structure
+### Overview
+Repository Name: testsuite
+
+Branching strategy:
+```
+`-- testsuite
+    |-- master - the main branch and always the latest deployable code. Send a pull to here from feature and Dan or Jerry will approve.
+    |-- feature-[XXXXXX] - when you want to make changes you make them here, when you are satisfied send pull request to master
+```    
+
+## Executing ETE Testcases
+### Overview
+Two scripts have been provided in the root of the ete-testsuite project to enable test exectution
+
+* runTags.sh - This shell uses Robot [Tags] to drive which tests are executed and is designed for automated testing.
+* oneTest.sh - This shell is designed for unit testing of individual .robot files. It accepts a single argument identifying the .robot file in robot/testsuites to execute.
+  
+#### runTags.sh
+For further information on using Robot [Tags], see [http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#configuring-execution] and [http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#simple-patterns]
+
+When executing tests via tags, all of the robot files in the project are scanned for tests cases with the specified tags.
+
+There are 3 flavors of runTags.sh 
+* runTags.sh with no arguments. This defaults to the default tag or runTags.sh -i health
+* runTags.sh with a single include tag. In this case the -i or --include may be omitted. So runTags.sh ete is the same as runTags.sh -i ete
+* runTags.sh with multiple tags. In this case, tags must be accompanied by a -i/--include or -e/--exclude to properly identify the disposition of the tagged testcase.
+
+```
+runTags.sh -i health -i ete -e garbage
+```
+
diff --git a/dnstraffic.sh b/dnstraffic.sh
new file mode 100644 (file)
index 0000000..808a7b5
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+# This script is run by the policy closed loop to generate traffic (DNS packets) to the DNS
+#
+#           Usage:    dnstraffic.sh  <DNSIP> <RATE_PER_SEC> <ITERATIONS>
+#
+# The DNSIP is that of the DNS vLoadBalancer.
+# The RATE_PER_SEC is the approximate number of nslookup requests generated per second.
+# The ITERATIONS is roughly the number of seconds to run the test. Note that the Robot 
+# will kill this script after the validation is complete.
+#  
+# The validation portion of the script has done a successful lookup, so the point of 
+# these requests is to generate DNS packets. We do not care about the results. The timeout
+# of 1 second is to ensure we do not flood the process table with long waits 
+# on failed lookups.
+# 
+# We generate an approximate rate because we sleep for a full second so the RATE_PER_SEC 
+# should have some slop in it. We only need to drive this to 20+ per second, so a 35 
+# per second should fall within the range to trigger the polciy check and prvide enough
+# to validate even distribution without spawning a 3rd DNS
+#
+DNSIP=$1
+RATE_PER_SEC=$2
+ITERATIONS=$3
+ITERATIONS=${ITERATIONS:-300}
+
+for iter in `seq 1 $ITERATIONS`;
+do
+   for i in `seq 1 $RATE_PER_SEC`;
+   do
+        nslookup -timeout=1 host2.dnsdemo.openecomp.org $DNSIP >/dev/null 2>&1 &
+   done
+   sleep 1
+done
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644 (file)
index 0000000..d993e94
--- /dev/null
@@ -0,0 +1,38 @@
+FROM ubuntu
+## Be careful of Windows newlines
+
+MAINTAINER "OpenECOMP"
+
+LABEL name="Docker image for the OpenECOMP End-to-End Robot Framework"
+LABEL usage="docker run -e ROBOT_TEST=<testname> -ti openecompete"
+
+# Install Python Pip, Robot framework, firefox, lighttpd web server, wget
+RUN apt-get update && \
+    apt-get --assume-yes install python=2.7.11-1 && \
+    apt-get --assume-yes install python-pip dbus xvfb lighttpd wget git net-tools dnsutils unzip && \
+    apt-get --assume-yes install libxss1 libappindicator1 libindicator7 build-essential libssl-dev libffi-dev python-dev && \
+    pip install --upgrade pip && \
+    pip install robotframework  && \
+    python --version
+    
+# Install chrome
+RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
+    echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list  && \
+    apt-get update && \
+    apt-get --assume-yes install google-chrome-stable
+
+# Copy the robot code
+COPY OpenECOMP_ETE/ /var/opt/OpenECOMP_ETE/
+COPY lighttpd.conf /etc/lighttpd/lighttpd.conf      
+RUN chmod 777 /var/opt/OpenECOMP_ETE/setup.sh
+RUN chmod 777 /var/opt/OpenECOMP_ETE/runTags.sh
+RUN chmod 777 /var/opt/OpenECOMP_ETE/dnstraffic.sh
+
+# Update the ssh library so that it will run properly in the docker env
+RUN cd /var/opt/OpenECOMP_ETE && ./setup.sh
+RUN apt-get clean
+
+CMD ["lighttpd", "-D", "-f",  "/etc/lighttpd/lighttpd.conf"]
+
+
+
diff --git a/docker/lighttpd.conf b/docker/lighttpd.conf
new file mode 100644 (file)
index 0000000..850af40
--- /dev/null
@@ -0,0 +1,17 @@
+server.document-root = "/var/opt/OpenECOMP_ETE/html/"
+
+server.port = 88
+
+server.username = "www-data"
+server.groupname = "www-data"
+
+dir-listing.activate = "disable"
+
+mimetype.assign = (
+  ".html" => "text/html"
+)
+
+static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc", ".cgi" )
+index-file.names = ( "index.html" )
+
+
diff --git a/docker/robot_vm_init.sh b/docker/robot_vm_init.sh
new file mode 100644 (file)
index 0000000..582a3f2
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+NEXUS_USERNAME=$(cat /opt/config/nexus_username.txt)
+NEXUS_PASSWD=$(cat /opt/config/nexus_password.txt)
+NEXUS_DOCKER_REPO=$(cat /opt/config/nexus_docker_repo.txt)
+NEXUS_REPO=$(cat /opt/config/nexus_repo.txt)
+
+#
+# Deploy latest robot configuration 
+# 
+wget --user=$NEXUS_USERNAME --password=$NEXUS_PASSWD --no-check-certificate -O /opt/eteshare/config/robot_properties_ete.py  $NEXUS_REPO/org.openecomp.boot/robot_properties_ete.py
+wget --user=$NEXUS_USERNAME --password=$NEXUS_PASSWD --no-check-certificate -O /opt/eteshare/config/robot_preload_parameters.py  $NEXUS_REPO/org.openecomp.boot/robot_preload_parameters.py
+wget --user=$NEXUS_USERNAME --password=$NEXUS_PASSWD --no-check-certificate -O /opt/eteshare/config/vm_config2robot.sh  $NEXUS_REPO/org.openecomp.boot/vm_config2robot.sh
+/bin/bash /opt/eteshare/config/vm_config2robot.sh
+
+docker login -u $NEXUS_USERNAME -p $NEXUS_PASSWD $NEXUS_DOCKER_REPO
+docker pull $NEXUS_DOCKER_REPO/openecompete
+docker rm -f openecompete_container
+docker run -d --name openecompete_container -v /opt/eteshare:/share -p 88:88 $NEXUS_DOCKER_REPO/openecompete
diff --git a/html/index.html b/html/index.html
new file mode 100644 (file)
index 0000000..a47b4a8
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+<h1>Server is up.</h1>
+</body>
+</html>
\ No newline at end of file
diff --git a/red.xml b/red.xml
new file mode 100644 (file)
index 0000000..c8bb244
--- /dev/null
+++ b/red.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<projectConfiguration>
+    <configVersion>1.0</configVersion>
+    <relativeTo>PROJECT</relativeTo>
+    <referencedLibrary type="PYTHON" name="RequestsLibrary" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="RequestsClientCert" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="UUID" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="Selenium2Library" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="ExtendedSelenium2Library" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="SSHLibrary" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="HTTPUtils" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="JSONUtils" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="HttpLibrary" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="HttpLibrary.HTTP" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="StringTemplater" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="OpenstackLibrary" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="HEATUtils" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="OSUtils" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="DNSUtils" path="ete-testsuite/robot/library/eteutils"/>
+    <referencedLibrary type="PYTHON" name="ArchiveLibrary" path="ete-testsuite/robot/library"/>
+    <referencedLibrary type="PYTHON" name="HeatBridge" path="ete-testsuite/robot/library/heatbridge"/>
+    <pythonpath>
+        <path location="robot/library"/>
+    </pythonpath>
+    <classpath/>
+    <variableFiles path="ete-testsuite/ete-properties/dfw_robot_properties_local.py"/>
+    <variableFiles path="ete-testsuite/ete-properties/dfw_preload_parameters.py"/>
+    <variableFiles path="ete-testsuite/ete-properties/dfw_vm_properties.py"/>
+    <variableFiles path="ete-testsuite/robot/assets/service_mappings.py"/>
+    <excludedForValidation/>
+    <isValidatedFileSizeCheckingEnabled>true</isValidatedFileSizeCheckingEnabled>
+    <validatedFileMaxSize>1024</validatedFileMaxSize>
+    <isReferencedLibrariesAutoReloadEnabled>true</isReferencedLibrariesAutoReloadEnabled>
+    <isReferencedLibrariesAutoDiscoveringEnabled>true</isReferencedLibrariesAutoDiscoveringEnabled>
+    <isLibrariesAutoDiscoveringSummaryWindowEnabled>false</isLibrariesAutoDiscoveringSummaryWindowEnabled>
+</projectConfiguration>
diff --git a/robot/assets/asdc/.gitignore b/robot/assets/asdc/.gitignore
new file mode 100644 (file)
index 0000000..abe251a
--- /dev/null
@@ -0,0 +1 @@
+/temp
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vfw/MANIFEST.json b/robot/assets/asdc/base_vfw/MANIFEST.json
new file mode 100644 (file)
index 0000000..a4e5cfd
--- /dev/null
@@ -0,0 +1,17 @@
+{
+    "name": "virtualFireWall", 
+    "description": "robot ete manifest", 
+    "data": [
+        {
+            "file": "base_vfw.yaml", 
+            "type": "HEAT", 
+            "isBase": "true", 
+            "data": [
+                {
+                    "file": "base_vfw.env", 
+                    "type": "HEAT_ENV"
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vfw/base_vfw.env b/robot/assets/asdc/base_vfw/base_vfw.env
new file mode 100644 (file)
index 0000000..f7d2c80
--- /dev/null
@@ -0,0 +1,4 @@
+parameters:
+  vfw_image_name: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)
+  vfw_flavor_name: 4 GB General Purpose v1
+  public_net_id: 00000000-0000-0000-0000-000000000000
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vfw/base_vfw.yaml b/robot/assets/asdc/base_vfw/base_vfw.yaml
new file mode 100644 (file)
index 0000000..076a834
--- /dev/null
@@ -0,0 +1,423 @@
+heat_template_version: 2013-05-23
+
+description: Heat template to deploy vFirewall demo app for OpenECOMP
+
+parameters:
+  vfw_image_name:
+    type: string
+    label: Image name or ID
+    description: Image to be used for compute instance
+  vfw_flavor_name:
+    type: string
+    label: Flavor
+    description: Type of instance (flavor) to be used
+  public_net_id:
+    type: string
+    label: Public network name or ID
+    description: Public network that enables remote connection to VNF
+  unprotected_private_net_id:
+    type: string
+    label: Unprotected private network name or ID
+    description: Private network that connects vPacketGenerator with vFirewall
+  protected_private_net_id:
+    type: string
+    label: Protected private network name or ID
+    description: Private network that connects vFirewall with vSink
+  ecomp_private_net_id:
+    type: string
+    label: ECOMP management network name or ID
+    description: Private network that connects ECOMP component and the VNF
+  ecomp_private_subnet_id:
+    type: string
+    label: ECOMP management sub-network name or ID
+    description: Private sub-network that connects ECOMP component and the VNF
+  unprotected_private_net_cidr:
+    type: string
+    label: Unprotected private network CIDR
+    description: The CIDR of the unprotected private network
+  protected_private_net_cidr:
+    type: string
+    label: Protected private network CIDR
+    description: The CIDR of the protected private network
+  ecomp_private_net_cidr:
+    type: string
+    label: ECOMP private network CIDR
+    description: The CIDR of the protected private network
+  vfw_private_ip_0:
+    type: string
+    label: vFirewall private IP address towards the unprotected network
+    description: Private IP address that is assigned to the vFirewall to communicate with the vPacketGenerator
+  vfw_private_ip_1:
+    type: string
+    label: vFirewall private IP address towards the protected network
+    description: Private IP address that is assigned to the vFirewall to communicate with the vSink
+  vfw_private_ip_2:
+    type: string
+    label: vFirewall private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vFirewall to communicate with ECOMP components
+  vpg_private_ip_0:
+    type: string
+    label: vPacketGenerator private IP address towards the unprotected network
+    description: Private IP address that is assigned to the vPacketGenerator to communicate with the vFirewall
+  vpg_private_ip_1:
+    type: string
+    label: vPacketGenerator private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vPacketGenerator to communicate with ECOMP components
+  vsn_private_ip_0:
+    type: string
+    label: vSink private IP address towards the protected network
+    description: Private IP address that is assigned to the vSink to communicate with the vFirewall
+  vsn_private_ip_1:
+    type: string
+    label: vSink private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vSink to communicate with ECOMP components
+  vfw_name_0:
+    type: string
+    label: vFirewall name
+    description: Name of the vFirewall
+  vpg_name_0:
+    type: string
+    label: vPacketGenerator name
+    description: Name of the vPacketGenerator
+  vsn_name_0:
+    type: string
+    label: vSink name
+    description: Name of the vSink
+  vnf_id:
+    type: string
+    label: VNF ID
+    description: The VNF ID is provided by ECOMP
+  vf_module_id:
+    type: string
+    label: vFirewall module ID
+    description: The vFirewall Module ID is provided by ECOMP
+  webserver_ip:
+    type: string
+    label: Webserver IP address
+    description: IP address of the webserver that hosts the source code and binaries
+  dcae_collector_ip:
+    type: string
+    label: DCAE collector IP address
+    description: IP address of the DCAE collector
+  dcae_collector_port:
+    type: string
+    label: DCAE collector port
+    description: Port of the DCAE collector
+  key_name:
+    type: string
+    label: Key pair name
+    description: Public/Private key pair name
+  pub_key:
+    type: string
+    label: Public key
+    description: Public key to be installed on the compute instance
+  repo_user:
+    type: string
+    label: Repository username
+    description: Username to access the repository that hosts the demo packages
+  repo_passwd:
+    type: string
+    label: Repository password
+    description: Password to access the repository that hosts the demo packages
+  repo_url:
+    type: string
+    label: Repository URL
+    description: URL of the repository that hosts the demo packages
+
+resources:
+  my_keypair:
+    type: OS::Nova::KeyPair
+    properties:
+      name: { get_param: key_name }
+      public_key: { get_param: pub_key }
+      save_private_key: false
+
+  unprotected_private_network:
+    type: OS::Neutron::Net
+    properties:
+      name: { get_param: unprotected_private_net_id }
+
+  protected_private_network:
+    type: OS::Neutron::Net
+    properties:
+      name: { get_param: protected_private_net_id }
+
+  unprotected_private_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      network_id: { get_resource: unprotected_private_network }
+      cidr: { get_param: unprotected_private_net_cidr }
+
+  protected_private_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      network_id: { get_resource: protected_private_network }
+      cidr: { get_param: protected_private_net_cidr }
+
+  vfw_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vfw_image_name }
+      flavor: { get_param: vfw_flavor_name }
+      name: { get_param: vfw_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vfw_private_0_port }
+        - port: { get_resource: vfw_private_1_port }
+        - port: { get_resource: vfw_private_2_port }
+      metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __webserver__: { get_param: webserver_ip }
+            __dcae_collector_ip__ : { get_param: dcae_collector_ip }
+            __dcae_collector_port__ : { get_param: dcae_collector_port }
+            __repo_url__ : { get_param: repo_url }
+            __repo_user__ : { get_param: repo_user }
+            __repo_passwd__ : { get_param: repo_passwd }
+          template: |
+            #!/bin/bash
+
+            WEBSERVER_IP=__webserver__
+            DCAE_COLLECTOR_IP=__dcae_collector_ip__
+            DCAE_COLLECTOR_PORT=__dcae_collector_port__
+            REPO_URL=__repo_url__
+            REPO_USER=__repo_user__
+            REPO_PASSWD=__repo_passwd__
+
+            # Download required dependencies
+            add-apt-repository -y ppa:openjdk-r/ppa
+            apt-get update
+            apt-get install -y make wget openjdk-8-jdk gcc libcurl4-openssl-dev python-pip bridge-utils apt-transport-https ca-certificates
+            pip install jsonschema
+
+            # Install Nexus certificate
+            echo "$WEBSERVER_IP ecomp-nexus" >> /etc/hosts
+            keytool -printcert -sslserver $WEBSERVER_IP:8443 -rfc > nexus.crt
+            cp nexus.crt /usr/local/share/ca-certificates/
+            update-ca-certificates
+
+            # Download vFirewall code for virtual firewall
+            mkdir /opt/config
+            cd /opt
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/v_firewall_init.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vfirewall.sh  
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/VESvFW.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vpp.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/honeycomb.tar.gz
+            tar -zxvf VESvFW.tar.gz
+            tar -zxvf vpp.tar.gz
+            tar -zxvf honeycomb.tar.gz
+            rm *.tar.gz
+            chmod +x v_firewall_init.sh
+            chmod +x vfirewall.sh
+            echo $DCAE_COLLECTOR_IP > config/dcae_collector_ip.txt
+            echo $DCAE_COLLECTOR_PORT > config/dcae_collector_port.txt
+
+            # Install VPP
+            cd /opt/vpp/build-root/
+            dpkg -i vpp-lib_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dbg_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dev_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dpdk-dev_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-plugins_16.09-3~gc021053_amd64.deb
+            sleep 1
+
+            # Install VES
+            cd /opt/VES1.1/bldjobs/
+            make clean
+            make
+            sleep 1
+
+            # Run instantiation script
+            cd /opt
+            mv vfirewall.sh /etc/init.d
+            update-rc.d vfirewall.sh defaults
+            ./v_firewall_init.sh
+
+  vfw_private_0_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: unprotected_private_network }
+      fixed_ips: [{"subnet": { get_resource: unprotected_private_subnet }, "ip_address": { get_param: vfw_private_ip_0 }}]
+
+  vfw_private_1_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: protected_private_network }
+      fixed_ips: [{"subnet": { get_resource: protected_private_subnet }, "ip_address": { get_param: vfw_private_ip_1 }}]
+
+  vfw_private_2_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: ecomp_private_net_id }
+      fixed_ips: [{"subnet": { get_param: ecomp_private_subnet_id }, "ip_address": { get_param: vfw_private_ip_2 }}]
+
+  vpg_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vfw_image_name }
+      flavor: { get_param: vfw_flavor_name }
+      name: { get_param: vpg_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vpg_private_0_port }
+        - port: { get_resource: vpg_private_1_port }
+      metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __webserver__: { get_param: webserver_ip }
+            __fw_ipaddr__: { get_param: vfw_private_ip_0 }
+            __protected_net_cidr__: { get_param: protected_private_net_cidr }
+            __sink_ipaddr__: { get_param: vsn_private_ip_0 }
+            __repo_url__ : { get_param: repo_url }
+            __repo_user__ : { get_param: repo_user }
+            __repo_passwd__ : { get_param: repo_passwd }
+          template: |
+            #!/bin/bash
+
+            WEBSERVER_IP=__webserver__
+            FW_IPADDR=__fw_ipaddr__
+            PROTECTED_NET_CIDR=__protected_net_cidr__
+            SINK_IPADDR=__sink_ipaddr__
+            REPO_URL=__repo_url__
+            REPO_USER=__repo_user__
+            REPO_PASSWD=__repo_passwd__
+
+            # Download required dependencies
+            add-apt-repository -y ppa:openjdk-r/ppa
+            apt-get update
+            apt-get install -y make wget openjdk-8-jdk gcc libcurl4-openssl-dev python-pip bridge-utils apt-transport-https ca-certificates
+            pip install jsonschema
+
+            # Install Nexus certificate
+            echo "$WEBSERVER_IP ecomp-nexus" >> /etc/hosts
+            keytool -printcert -sslserver $WEBSERVER_IP:8443 -rfc > nexus.crt
+            cp nexus.crt /usr/local/share/ca-certificates/
+            update-ca-certificates
+
+            # Download vFirewall demo code for packet generator
+            mkdir /opt/config
+            cd /opt
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/v_packetgen_init.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vpacketgen.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vpp.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/honeycomb.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/pg_streams.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/run_traffic_fw_demo.sh
+            tar -zxvf vpp.tar.gz
+            tar -zxvf honeycomb.tar.gz
+            tar -zxvf pg_streams.tar.gz
+            rm *.tar.gz
+            chmod +x v_packetgen_init.sh
+            chmod +x vpacketgen.sh
+            echo $FW_IPADDR > config/fw_ipaddr.txt
+            echo $PROTECTED_NET_CIDR > config/protected_net_cidr.txt
+            echo $SINK_IPADDR > config/sink_ipaddr.txt
+
+            # Install VPP
+            cd /opt/vpp/build-root/
+            dpkg -i vpp-lib_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dbg_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dev_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dpdk-dev_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-plugins_16.09-3~gc021053_amd64.deb
+            sleep 1
+
+            # Run instantiation script
+            cd /opt
+            mv vpacketgen.sh /etc/init.d
+            update-rc.d vpacketgen.sh defaults
+            ./v_packetgen_init.sh
+
+  vpg_private_0_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: unprotected_private_network }
+      fixed_ips: [{"subnet": { get_resource: unprotected_private_subnet }, "ip_address": { get_param: vpg_private_ip_0 }}]
+
+  vpg_private_1_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: ecomp_private_net_id }
+      fixed_ips: [{"subnet": { get_param: ecomp_private_subnet_id }, "ip_address": { get_param: vpg_private_ip_1 }}]
+
+  vsn_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vfw_image_name }
+      flavor: { get_param: vfw_flavor_name }
+      name: { get_param: vsn_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vsn_private_0_port }
+        - port: { get_resource: vsn_private_1_port }
+      metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __webserver__: { get_param: webserver_ip }
+            __protected_net_gw__: { get_param: vfw_private_ip_1 }
+            __unprotected_net__: { get_param: unprotected_private_net_cidr }
+            __repo_url__ : { get_param: repo_url }
+            __repo_user__ : { get_param: repo_user }
+            __repo_passwd__ : { get_param: repo_passwd }
+          template: |
+            #!/bin/bash
+
+            WEBSERVER_IP=__webserver__
+            PROTECTED_NET_GW=__protected_net_gw__
+            UNPROTECTED_NET=__unprotected_net__
+            UNPROTECTED_NET=$(echo $UNPROTECTED_NET | cut -d'/' -f1)
+            REPO_URL=__repo_url__
+            REPO_USER=__repo_user__
+            REPO_PASSWD=__repo_passwd__
+
+            # Download required dependencies
+            add-apt-repository -y ppa:openjdk-r/ppa
+            apt-get update
+            apt-get install -y make wget openjdk-8-jdk apt-transport-https ca-certificates darkstat
+
+            # Configure and run darkstat
+            sed -i "s/START_DARKSTAT=.*/START_DARKSTAT=yes/g" /etc/darkstat/init.cfg
+            sed -i "s/INTERFACE=.*/INTERFACE=\"-i eth1\"/g" /etc/darkstat/init.cfg
+            /etc/init.d/darkstat start
+
+            # Install Nexus certificate
+            echo "$WEBSERVER_IP ecomp-nexus" >> /etc/hosts
+            keytool -printcert -sslserver $WEBSERVER_IP:8443 -rfc > nexus.crt
+            cp nexus.crt /usr/local/share/ca-certificates/
+            update-ca-certificates
+
+            mkdir /opt/config
+            cd /opt
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/v_sink_init.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vsink.sh
+            chmod +x v_sink_init.sh
+            chmod +x vsink.sh
+            echo $PROTECTED_NET_GW > config/protected_net_gw.txt
+            echo $UNPROTECTED_NET > config/unprotected_net.txt
+            mv vsink.sh /etc/init.d
+            update-rc.d vsink.sh defaults
+            ./v_sink_init.sh
+
+  vsn_private_0_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: protected_private_network }
+      fixed_ips: [{"subnet": { get_resource: protected_private_subnet }, "ip_address": { get_param: vsn_private_ip_0 }}]
+
+  vsn_private_1_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: ecomp_private_net_id }
+      fixed_ips: [{"subnet": { get_param: ecomp_private_subnet_id }, "ip_address": { get_param: vsn_private_ip_1 }}]
diff --git a/robot/assets/asdc/base_vlb/MANIFEST.json b/robot/assets/asdc/base_vlb/MANIFEST.json
new file mode 100644 (file)
index 0000000..bb8d70a
--- /dev/null
@@ -0,0 +1,28 @@
+{
+    "name": "virtualLoadBalancer", 
+    "description": "robot ete manifest", 
+    "data": [
+        {
+            "file": "base_vlb.yaml", 
+            "type": "HEAT", 
+            "isBase": "true", 
+            "data": [
+                {
+                    "file": "base_vlb.env", 
+                    "type": "HEAT_ENV"
+                }
+            ]
+        },
+        {
+            "file": "dnsscaling.yaml", 
+            "type": "HEAT", 
+            "isBase": "false", 
+            "data": [
+                {
+                    "file": "dnsscaling.env", 
+                    "type": "HEAT_ENV"
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vlb/base_vlb.env b/robot/assets/asdc/base_vlb/base_vlb.env
new file mode 100644 (file)
index 0000000..f18b001
--- /dev/null
@@ -0,0 +1,4 @@
+parameters:
+  vlb_image_name: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)
+  vlb_flavor_name: 4 GB General Purpose v1
+  public_net_id: 00000000-0000-0000-0000-000000000000
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vlb/base_vlb.yaml b/robot/assets/asdc/base_vlb/base_vlb.yaml
new file mode 100644 (file)
index 0000000..5dfc432
--- /dev/null
@@ -0,0 +1,330 @@
+heat_template_version: 2013-05-23
+
+description: Heat template to deploy vLoadBalancer/vDNS demo app for OpenECOMP
+
+parameters:
+  vlb_image_name:
+    type: string
+    label: Image name or ID
+    description: Image to be used for compute instance
+  vlb_flavor_name:
+    type: string
+    label: Flavor
+    description: Type of instance (flavor) to be used
+  public_net_id:
+    type: string
+    label: Public network name or ID
+    description: Public network that enables remote connection to VNF
+  vlb_private_net_id:
+    type: string
+    label: vLoadBalancer private network name or ID
+    description: Private network that connects vLoadBalancer with vDNSs
+  ecomp_private_net_id:
+    type: string
+    label: ECOMP management network name or ID
+    description: Private network that connects ECOMP component and the VNF
+  ecomp_private_subnet_id:
+    type: string
+    label: ECOMP management sub-network name or ID
+    description: Private sub-network that connects ECOMP component and the VNF
+  vlb_private_net_cidr:
+    type: string
+    label: vLoadBalancer private network CIDR
+    description: The CIDR of the vLoadBalancer private network
+  ecomp_private_net_cidr:
+    type: string
+    label: ECOMP private network CIDR
+    description: The CIDR of the protected private network
+  vlb_private_ip_0:
+    type: string
+    label: vLoadBalancer private IP address towards the private network
+    description: Private IP address that is assigned to the vLoadBalancer to communicate with the vDNSs
+  vlb_private_ip_1:
+    type: string
+    label: vLoadBalancer private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vLoadBalancer to communicate with ECOMP components
+  vdns_private_ip_0:
+    type: string
+    label: vDNS private IP address towards the private network
+    description: Private IP address that is assigned to the vDNS to communicate with the vLoadBalancer
+  vdns_private_ip_1:
+    type: string
+    label: vDNS private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vDNS to communicate with ECOMP components
+  vlb_name_0:
+    type: string
+    label: vLoadBalancer name
+    description: Name of the vLoadBalancer
+  vdns_name_0:
+    type: string
+    label: vDNS name
+    description: Name of the vDNS
+  vnf_id:
+    type: string
+    label: VNF ID
+    description: The VNF ID is provided by ECOMP
+  vf_module_id:
+    type: string
+    label: vFirewall module ID
+    description: The vLoadBalancer Module ID is provided by ECOMP
+  webserver_ip:
+    type: string
+    label: Webserver IP address
+    description: IP address of the webserver that hosts the source code and binaries
+  dcae_collector_ip:
+    type: string
+    label: DCAE collector IP address
+    description: IP address of the DCAE collector
+  dcae_collector_port:
+    type: string
+    label: DCAE collector port
+    description: Port of the DCAE collector
+  key_name:
+    type: string
+    label: Key pair name
+    description: Public/Private key pair name
+  pub_key:
+    type: string
+    label: Public key
+    description: Public key to be installed on the compute instance
+  repo_user:
+    type: string
+    label: Repository username
+    description: Username to access the repository that hosts the demo packages
+  repo_passwd:
+    type: string
+    label: Repository password
+    description: Password to access the repository that hosts the demo packages
+  repo_url:
+    type: string
+    label: Repository URL
+    description: URL of the repository that hosts the demo packages
+
+resources:
+  my_keypair:
+    type: OS::Nova::KeyPair
+    properties:
+      name: { get_param: key_name }
+      public_key: { get_param: pub_key }
+      save_private_key: false
+
+  vlb_private_network:
+    type: OS::Neutron::Net
+    properties:
+      name: { get_param: vlb_private_net_id }
+
+  vlb_private_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      name: { get_param: vlb_private_net_id }
+      network_id: { get_resource: vlb_private_network }
+      cidr: { get_param: vlb_private_net_cidr }
+
+  vlb_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vlb_image_name }
+      flavor: { get_param: vlb_flavor_name }
+      name: { get_param: vlb_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vlb_private_0_port }
+        - port: { get_resource: vlb_private_1_port }
+      metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __webserver__: { get_param: webserver_ip }
+            __dcae_collector_ip__: { get_param: dcae_collector_ip }
+            __dcae_collector_port__: { get_param: dcae_collector_port }
+            __local_private_ipaddr__: { get_param: vlb_private_ip_0 }
+            __repo_url__ : { get_param: repo_url }
+            __repo_user__ : { get_param: repo_user }
+            __repo_passwd__ : { get_param: repo_passwd }
+          template: |
+            #!/bin/bash
+
+            WEBSERVER_IP=__webserver__
+            DCAE_COLLECTOR_IP=__dcae_collector_ip__
+            DCAE_COLLECTOR_PORT=__dcae_collector_port__
+            LOCAL_PRIVATE_IPADDR=__local_private_ipaddr__
+            REPO_URL=__repo_url__
+            REPO_USER=__repo_user__
+            REPO_PASSWD=__repo_passwd__
+
+            # Download required dependencies
+            add-apt-repository -y ppa:openjdk-r/ppa
+            apt-get update
+            apt-get install -y make gcc wget openjdk-8-jdk bridge-utils libcurl4-openssl-dev apt-transport-https ca-certificates
+            sleep 1
+
+            # Install Nexus certificate
+            echo "$WEBSERVER_IP ecomp-nexus" >> /etc/hosts
+            keytool -printcert -sslserver $WEBSERVER_IP:8443 -rfc > nexus.crt
+            cp nexus.crt /usr/local/share/ca-certificates/
+            update-ca-certificates
+
+            # Download vLB demo code for load balancer
+            mkdir /opt/config
+            cd /opt
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/v_lb_init.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vlb.sh 
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vpp.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/DNSManager.tar.gz
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/VESvLB.tar.gz
+            tar -zxvf vpp.tar.gz
+            tar -zxvf DNSManager.tar.gz
+            tar -zxvf VESvLB.tar.gz
+            rm *.tar.gz
+            chmod +x v_lb_init.sh
+            chmod +x vlb.sh
+            echo $DCAE_COLLECTOR_IP > config/dcae_collector_ip.txt
+            echo $DCAE_COLLECTOR_PORT > config/dcae_collector_port.txt
+            echo $LOCAL_PRIVATE_IPADDR > config/local_private_ipaddr.txt
+            LOCAL_PUBLIC_IPADDR=$(ifconfig eth0 | grep "inet addr" | tr -s ' ' | cut -d' ' -f3 | cut -d':' -f2)
+            echo $LOCAL_PUBLIC_IPADDR > config/local_public_ipaddr.txt
+
+            # Install VPP
+            cd /opt/vpp/build-root/
+            dpkg -i vpp-lib_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dbg_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dev_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-dpdk-dev_16.09-3~gc021053_amd64.deb
+            dpkg -i vpp-plugins_16.09-3~gc021053_amd64.deb
+            sleep 1
+
+            # Install Failure Detector
+            cd /opt/DNSManager/src
+            javac -d ../bin/ *.java
+            cd /opt/DNSManager/bin
+            chmod +x dnsmembership.sh
+            chmod +x add_dns.sh
+            chmod +x remove_dns.sh
+            sleep 1
+
+            # Install VES
+            cd /opt/VES1.1/bldjobs/
+            make clean
+            make
+            sleep 1
+
+            # Run instantiation script
+            cd /opt            
+            mv vlb.sh /etc/init.d
+            update-rc.d vlb.sh defaults
+            ./v_lb_init.sh
+
+  vlb_private_0_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: vlb_private_network }
+      fixed_ips: [{"subnet": { get_resource: vlb_private_subnet }, "ip_address": { get_param: vlb_private_ip_0 }}]
+
+  vlb_private_1_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: ecomp_private_net_id }
+      fixed_ips: [{"subnet": { get_param: ecomp_private_subnet_id }, "ip_address": { get_param: vlb_private_ip_1 }}]
+
+  vdns_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vlb_image_name }
+      flavor: { get_param: vlb_flavor_name }
+      name: { get_param: vdns_name_0 }
+      key_name: { get_resource: my_keypair }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vdns_private_0_port }
+        - port: { get_resource: vdns_private_1_port }
+      metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __webserver__: { get_param: webserver_ip }
+            __lb_oam_int__ : { get_param: vlb_private_ip_1 }
+            __lb_private_ipaddr__: { get_param: vlb_private_ip_0 }
+            __local_private_ipaddr__: { get_param: vdns_private_ip_0 }
+            __repo_url__ : { get_param: repo_url }
+            __repo_user__ : { get_param: repo_user }
+            __repo_passwd__ : { get_param: repo_passwd }
+          template: |
+            #!/bin/bash
+
+            WEBSERVER_IP=__webserver__
+            LB_OAM_INT=__lb_oam_int__
+            LB_PRIVATE_IPADDR=__lb_private_ipaddr__
+            LOCAL_PRIVATE_IPADDR=__local_private_ipaddr__
+            REPO_URL=__repo_url__
+            REPO_USER=__repo_user__
+            REPO_PASSWD=__repo_passwd__
+
+            # Download required dependencies
+            add-apt-repository -y ppa:openjdk-r/ppa
+            apt-get update
+            apt-get install -y wget openjdk-8-jdk bind9 bind9utils bind9-doc apt-transport-https ca-certificates
+            sleep 1
+
+            # Install Nexus certificate
+            echo "$WEBSERVER_IP ecomp-nexus" >> /etc/hosts
+            keytool -printcert -sslserver $WEBSERVER_IP:8443 -rfc > nexus.crt
+            cp nexus.crt /usr/local/share/ca-certificates/
+            update-ca-certificates
+
+            # Download vDNS demo code for DNS Server
+            mkdir /opt/config
+            cd /opt
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/v_dns_init.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vdns.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/DNSClient.tar.gz
+            tar -zxvf DNSClient.tar.gz
+            rm *.tar.gz
+            chmod +x v_dns_init.sh
+            chmod +x vdns.sh
+            echo $LB_OAM_INT > config/lb_oam_int.txt
+            echo $LB_PRIVATE_IPADDR > config/lb_private_ipaddr.txt
+            echo $LOCAL_PRIVATE_IPADDR > config/local_private_ipaddr.txt
+
+            # Download Bind config files
+            cd /opt/config
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/db_dnsdemo_openecomp_org
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/named.conf.options
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/named.conf.local
+
+            # Configure Bind
+            modprobe ip_gre
+            mkdir /etc/bind/zones
+            sed -i "s/OPTIONS=.*/OPTIONS=\"-4 -u bind\"/g" /etc/default/bind9
+            cp /opt/config/db_dnsdemo_openecomp_org /etc/bind/zones/db.dnsdemo.openecomp.org
+            cp /opt/config/named.conf.local /etc/bind/
+            sleep 1
+
+            # Start Failure Detector
+            cd /opt/DNSClient/src
+            javac -d ../bin/ *.java
+            cd /opt/DNSClient/bin
+            chmod +x dnsclient.sh
+            chmod +x set_gre_tunnel.sh
+            sleep 1
+
+            # Run instantiation script
+            cd /opt
+            mv vdns.sh /etc/init.d
+            update-rc.d vdns.sh defaults
+            ./v_dns_init.sh
+
+  vdns_private_0_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: vlb_private_network }
+      fixed_ips: [{"subnet": { get_resource: vlb_private_subnet }, "ip_address": { get_param: vdns_private_ip_0 }}]
+
+  vdns_private_1_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: ecomp_private_net_id }
+      fixed_ips: [{"subnet": { get_param: ecomp_private_subnet_id }, "ip_address": { get_param: vdns_private_ip_1 }}]
diff --git a/robot/assets/asdc/base_vlb/dnsscaling.env b/robot/assets/asdc/base_vlb/dnsscaling.env
new file mode 100644 (file)
index 0000000..f18b001
--- /dev/null
@@ -0,0 +1,4 @@
+parameters:
+  vlb_image_name: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)
+  vlb_flavor_name: 4 GB General Purpose v1
+  public_net_id: 00000000-0000-0000-0000-000000000000
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vlb/dnsscaling.yaml b/robot/assets/asdc/base_vlb/dnsscaling.yaml
new file mode 100644 (file)
index 0000000..8f17723
--- /dev/null
@@ -0,0 +1,182 @@
+heat_template_version: 2013-05-23
+
+description: Heat template to deploy a vDNS for OpenECOMP (scaling-up scenario)
+
+parameters:
+  vlb_image_name:
+    type: string
+    label: Image name or ID
+    description: Image to be used for compute instance
+  vlb_flavor_name:
+    type: string
+    label: Flavor
+    description: Type of instance (flavor) to be used
+  public_net_id:
+    type: string
+    label: Public network name or ID
+    description: Public network that enables remote connection to VNF
+  vlb_private_net_id:
+    type: string
+    label: vLoadBalancer private network name or ID
+    description: Private network that connects vLoadBalancer with vDNSs
+  ecomp_private_net_id:
+    type: string
+    label: ECOMP management network name or ID
+    description: Private network that connects ECOMP component and the VNF
+  ecomp_private_subnet_id:
+    type: string
+    label: ECOMP management sub-network name or ID
+    description: Private sub-network that connects ECOMP component and the VNF
+  vlb_private_ip_0:
+    type: string
+    label: vLoadBalancer private IP address towards the private network
+    description: Private IP address that is assigned to the vLoadBalancer to communicate with the vDNSs
+  vlb_private_ip_1:
+    type: string
+    label: vLoadBalancer private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vLoadBalancer to communicate with ECOMP components
+  vdns_private_ip_0:
+    type: string
+    label: vDNS private IP address towards the private network
+    description: Private IP address that is assigned to the vDNS to communicate with the vLoadBalancer
+  vdns_private_ip_1:
+    type: string
+    label: vDNS private IP address towards the ECOMP management network
+    description: Private IP address that is assigned to the vDNS to communicate with ECOMP components
+  vdns_name_0:
+    type: string
+    label: vDNS name
+    description: Name of the vDNS
+  vnf_id:
+    type: string
+    label: VNF ID
+    description: The VNF ID is provided by ECOMP
+  vf_module_id:
+    type: string
+    label: vFirewall module ID
+    description: The vLoadBalancer Module ID is provided by ECOMP
+  webserver_ip:
+    type: string
+    label: Webserver IP address
+    description: IP address of the webserver that hosts the source code and binaries
+  key_name:
+    type: string
+    label: Key pair name
+    description: Public/Private key pair name
+  pub_key:
+    type: string
+    label: Public key
+    description: Public key to be installed on the compute instance
+  repo_user:
+    type: string
+    label: Repository username
+    description: Username to access the repository that hosts the demo packages
+  repo_passwd:
+    type: string
+    label: Repository password
+    description: Password to access the repository that hosts the demo packages
+  repo_url:
+    type: string
+    label: Repository URL
+    description: URL of the repository that hosts the demo packages
+
+resources:
+  vdns_0:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: vlb_image_name }
+      flavor: { get_param: vlb_flavor_name }
+      name: { get_param: vdns_name_0 }
+      key_name: { get_param: key_name }
+      networks:
+        - network: { get_param: public_net_id }
+        - port: { get_resource: vdns_private_0_port }
+        - port: { get_resource: vdns_private_1_port }
+      metadata: {vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          params:
+            __webserver__: { get_param: webserver_ip }
+            __lb_oam_int__ : { get_param: vlb_private_ip_1 }
+            __lb_private_ipaddr__: { get_param: vlb_private_ip_0 }
+            __local_private_ipaddr__: { get_param: vdns_private_ip_0 }
+            __repo_url__ : { get_param: repo_url }
+            __repo_user__ : { get_param: repo_user }
+            __repo_passwd__ : { get_param: repo_passwd }
+          template: |
+            #!/bin/bash
+
+            WEBSERVER_IP=__webserver__
+            LB_OAM_INT=__lb_oam_int__
+            LB_PRIVATE_IPADDR=__lb_private_ipaddr__
+            LOCAL_PRIVATE_IPADDR=__local_private_ipaddr__
+            REPO_URL=__repo_url__
+            REPO_USER=__repo_user__
+            REPO_PASSWD=__repo_passwd__
+
+            # Download required dependencies
+            add-apt-repository -y ppa:openjdk-r/ppa
+            apt-get update
+            apt-get install -y wget openjdk-8-jdk bind9 bind9utils bind9-doc apt-transport-https ca-certificates
+            sleep 1
+
+            # Install Nexus certificate
+            echo "$WEBSERVER_IP ecomp-nexus" >> /etc/hosts
+            keytool -printcert -sslserver $WEBSERVER_IP:8443 -rfc > nexus.crt
+            cp nexus.crt /usr/local/share/ca-certificates/
+            update-ca-certificates
+
+            # Download vDNS demo code for DNS Server
+            mkdir /opt/config
+            cd /opt
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/v_dns_init.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/vdns.sh
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/DNSClient.tar.gz
+            tar -zxvf DNSClient.tar.gz
+            rm *.tar.gz
+            chmod +x v_dns_init.sh
+            chmod +x vdns.sh
+            echo $LB_OAM_INT > config/lb_oam_int.txt
+            echo $LB_PRIVATE_IPADDR > config/lb_private_ipaddr.txt
+            echo $LOCAL_PRIVATE_IPADDR > config/local_private_ipaddr.txt
+
+            # Download Bind config files
+            cd /opt/config
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/db_dnsdemo_openecomp_org
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/named.conf.options
+            wget --user=$REPO_USER --password=$REPO_PASSWD $REPO_URL/named.conf.local
+
+            # Configure Bind
+            modprobe ip_gre
+            mkdir /etc/bind/zones
+            sed -i "s/OPTIONS=.*/OPTIONS=\"-4 -u bind\"/g" /etc/default/bind9
+            cp /opt/config/db_dnsdemo_openecomp_org /etc/bind/zones/db.dnsdemo.openecomp.org
+            cp /opt/config/named.conf.local /etc/bind/
+            sleep 1
+
+            # Start Failure Detector
+            cd /opt/DNSClient/src
+            javac -d ../bin/ *.java
+            cd /opt/DNSClient/bin
+            chmod +x dnsclient.sh
+            chmod +x set_gre_tunnel.sh
+            sleep 1
+
+            # Run instantiation script
+            cd /opt
+            mv vdns.sh /etc/init.d
+            update-rc.d vdns.sh defaults
+            ./v_dns_init.sh
+
+  vdns_private_0_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: vlb_private_net_id }
+      fixed_ips: [{"subnet": { get_param: vlb_private_net_id }, "ip_address": { get_param: vdns_private_ip_0 }}]
+
+  vdns_private_1_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: ecomp_private_net_id }
+      fixed_ips: [{"subnet": { get_param: ecomp_private_subnet_id }, "ip_address": { get_param: vdns_private_ip_1 }}]
diff --git a/robot/assets/asdc/base_vvg/MANIFEST.json b/robot/assets/asdc/base_vvg/MANIFEST.json
new file mode 100644 (file)
index 0000000..67312f2
--- /dev/null
@@ -0,0 +1,17 @@
+{
+    "name": "volumeGroup.yaml", 
+    "description": "robot ete manifest", 
+    "data": [
+        {
+            "file": "base_vvg.yaml", 
+            "type": "HEAT", 
+            "isBase": "true", 
+            "data": [
+                {
+                    "file": "base_vvg.env", 
+                    "type": "HEAT_ENV"
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vvg/base_vvg.env b/robot/assets/asdc/base_vvg/base_vvg.env
new file mode 100644 (file)
index 0000000..2b4e72b
--- /dev/null
@@ -0,0 +1,3 @@
+parameters:
+  volume_size: 100
+  nova_instance: 1234456
\ No newline at end of file
diff --git a/robot/assets/asdc/base_vvg/base_vvg.yaml b/robot/assets/asdc/base_vvg/base_vvg.yaml
new file mode 100644 (file)
index 0000000..c20d4e4
--- /dev/null
@@ -0,0 +1,22 @@
+heat_template_version: 2013-05-23
+description: create a Nova instance, a Cinder volume and attach the volume to the instance.
+
+parameters:
+  nova_instance:
+    type: string
+    label: Instance name or ID
+    description: ID of the vm to use for the disk to be attached too
+  volume_size:
+    type: number
+    label: GB
+    description: Size of the volume to be created.
+resources:
+  cinder_volume:
+    type: OS::Cinder::Volume
+    properties:
+      size: { get_param: volume_size }
+  volume_attachment:
+    type: OS::Cinder::VolumeAttachment
+    properties:
+      volume_id: { get_resource: cinder_volume }
+      instance_uuid: { get_param: nova_instance }
\ No newline at end of file
diff --git a/robot/assets/dcae/dcae_healthcheck.json b/robot/assets/dcae/dcae_healthcheck.json
new file mode 100644 (file)
index 0000000..d612b08
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "path": "/reports/dcae/service-instances",
+       "start": "-24hour",
+       "end": "now"
+}
\ No newline at end of file
diff --git a/robot/assets/keys/ecompdemo.pvt b/robot/assets/keys/ecompdemo.pvt
new file mode 100644 (file)
index 0000000..36d9e9c
--- /dev/null
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,E9DC8BE477D6D4AC
+
+4lYXpDswDU9oNh/OdB/0krK7AVN2OYnU98ZvYUfQIVWgrAty0vp0PDErOAAP7AOE
+tz+tQwvg/JVqZlBGCYIkwx5ADJ9YFXMyn/Ztla2jC90dxbjlra+MvuU9nMfjWhjP
+PiaOysIDaRIPZqjkjRQcslgsDYgVF4JC+2qRMJ62e5exk0dw4Cn3XeN53pByQ8HT
+OnTuszejFNb3/HA5LsPyJl3cZqMBlKOHToUBbF2JBuo+aDq5S+YgzILep/nTQadh
+kLfuJThhAwTJsQWVCSOggAwsjV6fP5yi2q9iCmF07kxDgRsByj0nl/7YDoZ69ZoE
+LHkZEoZ1JSX0SSOrOUyVcpf8+ofK1aMEoWRvLGYfBD7wDJb4nzi4k1fdJGnoDLms
+dr+mL7RB5zoC3xlumSAK2AP8hhIfURtaSC9hpiUB6yIXCmUjx4FIzroa4gBUsrlJ
+R6KGp+6b54bf7hwFeCjYENjGq5YJJ24Aur2mR045LCBNP452pFVi5SIfX0PO5ocd
+dBvPHQUqtCoUkQMSTtjy6T384BbPeA5s5zazq7WUoNrQD37khR7MojBpww0s3wEh
+U+XWlQ5bEjEjac5Q8RIJrB2Bp6/cUQFSlqNDKxK2y1WzvPjM/Fkn2H+hImn+we7n
+Cp5fzx6s4roeEc9WvVmb2+V3xV883pkktd1IiWGfleB14ZJ1vcGzdW+lBINgm9h1
+5xvxP5Xtqj8KGGoA3mEo3CbzR1XbkEp7/S4MN1OsXSCy3jZpiP+ctd4fwk5Ltcqz
+YEjM5cb2+joNYTd4JW5DTtz7qrMn/sotAOlgw2ozmXLfbbMuOZ9SX76npEr8SKd+
+065bxJ+YvN6MFzwG75nFfXcPWdNVntXaH+zOZfBGBNX84gX4p3ORF1u18brNcd9z
+0sv1OiGdO5NFVA/3YixP1P2zZxlGsi972PtHoQ8SHxbEfNMCqkNGrHh+KmaT42k6
+W5lscEhPDtIsiRmhTTrL6L5sFCbLL+8UZktK1/TU27QtCtywi5xfzO9NhJg27R5b
+hPvQs43V7KItpdc5LdWrft7hTnmc4jn5F6aE7l9bCaaRgAy1MH6lzyjuaLphFXmP
+GdPLD9GhMFiTRJNVCRkYPZwtGKdfG6/z6kRZGIi6XPYzI3FcHOdKTGgvGxlko6Lr
+4FG0kOwgi55o1gQnL3wsBVoNZ7PrkHLFSQhu03ggXPrf75oMN0Tsqai+iaf4OvMr
+fgk4O5+D/CX94R50V1xUymUrRIAzKG3k+jebFcTzkb7B/e1bPwr8ZRUk31nZrgYp
+3qKJT77/Vz+tyL3H+U3YdvzxhG6+onXDkAvO8WAcfsKpEJ3thv8NOqXZeKCY2m1G
+wrQ8vfl6MddOvlI5EKbnwesXIznO9Gl+RoCm18I/M8bETTAOMJXb3cp4GiBffXbI
+8kbYwVeHGscXizHdkuqjbN1NLg5KPZV10KRchg0g85PWgDr59wY5kMplFNUrkxY2
+1ETYOZsmOa3/Afcq2dgxEw1t1t+ZRR5dh6OdQXKCvsHHugQisnPi5NAb8gkZbRJI
+yHNInMegrG2S17n75P0o+GM+XItc74ygnv/KedJFW9uBaOr7sXtB4A==
+-----END RSA PRIVATE KEY-----
diff --git a/robot/assets/keys/robot_ssh_private_key.ppk b/robot/assets/keys/robot_ssh_private_key.ppk
new file mode 100644 (file)
index 0000000..0a327c2
--- /dev/null
@@ -0,0 +1,26 @@
+PuTTY-User-Key-File-2: ssh-rsa
+Encryption: none
+Comment: rsa-key-20161026
+Public-Lines: 6
+AAAAB3NzaC1yc2EAAAABJQAAAQEAqqnA9BAiMLtjOPSYBfhzLu4CiBolWoskDg4K
+VwhTJVTTeB6CqrQNcadlGXxOHhCYuNCKkUmIVF4WTOisVOJ75Z1c4OMoZLL85xVP
+KSIeH63kgVugwgPYQu55NbbWX+rsbUha3LnElDhNviMM3iTPbD5nnhKixNERAJMT
+LKXvZZZGqxW94bREknYPQTT2qrk3YRqwldncopp6Nkgv3AnSJz2gc9tjxnWF0poT
+QnQm/3D6hiJICrzKfAV0EaPN0KdtYjPhKrYoy6Qb/tKOVaaqsvwfKBJGrT9LfcA7
+D7M/yj292RT1XN63hI84WC383LsaPJ6eWdDTE6zUP1eGTWCoOw==
+Private-Lines: 14
+AAABAGoWftznbzMMs0zrEmSThd7m+qehjNdrP+0PpZAMGAJy//6PgahiFjHkmMqn
+N3p5BP1DXQ40oNp/rP9gM8YQPy3eXFRxh8/k4mYiAMaK1HSOsKNwTyx+7jdxpUrn
+Rv1arqTMHM5lo7YVKWha+ik5egUEMpKxo3NtNBUdJ5hLeSN4EzbS0xq6dYA0EU33
+kjmkoqtj2qMhwZQmTUCyqvtae6t9I7YTP9DbkG+kyuWSLCrbIFN3SPU7jsLBxI45
+cdUiAKBbd6WjPYauSyhTenZvqjxDV0w/QUPKv3vxpqPvLfdA/gQfvhFLkNMStdb9
+DKB4ni8uiAPtM5AVYlgEpC7Nuw0AAACBANa5Wi9KvsPp5ltbiwrLeoVTPmFwAhJP
+w+B+OEoRN4oMqstIBOZiYz1+WV/nA3WR1gOd/TbDL4kzXL9SYl/y8QmFjrc7B4vI
+GLhWnDBjl1l/wvYhxMXbfHEN2VqZVICSoEVICphx6SPflFH53kmGrIiBs9GWFv9c
+AVGHi1j52rvRAAAAgQDLeCWfKS24gUcSfn/UHlc9EGgyNayeC3eX4K2xV9yMSXub
+uQVvxiuBXd6OWW9I/CQyNVoLN3tboAzRl61ds15Ml+V/uLMjxrXJXDWkEiQHsOMX
+BhREWZL0T3hlFZsyfVZPPH5BavZzA4PB1/BF+t06N10pnASXB4kcKjQD0JQCSwAA
+AIBfQ7PZM1KuL0zpD6imxUgyNNSXdGTfM9XUSY5L8e2xWqjnZT+Cj1bUGVYMxrpC
+8bpfGGTyBv/v6N7NxPep1QeyM9E0o0z0ID9ybRpX4ErYSp1sLZBNlBXdAAL9nexo
+XbZDpN0zdBE5wnAMjcjHTp9PMSDeWt4/r2aiNde3VFwnWg==
+Private-MAC: 50d4bf08bffb34c3aba06d57afb241242ca9e242
diff --git a/robot/assets/keys/robot_ssh_private_key.pvt b/robot/assets/keys/robot_ssh_private_key.pvt
new file mode 100644 (file)
index 0000000..17c17a3
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEoQIBAAKCAQEAqqnA9BAiMLtjOPSYBfhzLu4CiBolWoskDg4KVwhTJVTTeB6C
+qrQNcadlGXxOHhCYuNCKkUmIVF4WTOisVOJ75Z1c4OMoZLL85xVPKSIeH63kgVug
+wgPYQu55NbbWX+rsbUha3LnElDhNviMM3iTPbD5nnhKixNERAJMTLKXvZZZGqxW9
+4bREknYPQTT2qrk3YRqwldncopp6Nkgv3AnSJz2gc9tjxnWF0poTQnQm/3D6hiJI
+CrzKfAV0EaPN0KdtYjPhKrYoy6Qb/tKOVaaqsvwfKBJGrT9LfcA7D7M/yj292RT1
+XN63hI84WC383LsaPJ6eWdDTE6zUP1eGTWCoOwIBJQKCAQBqFn7c528zDLNM6xJk
+k4Xe5vqnoYzXaz/tD6WQDBgCcv/+j4GoYhYx5JjKpzd6eQT9Q10ONKDaf6z/YDPG
+ED8t3lxUcYfP5OJmIgDGitR0jrCjcE8sfu43caVK50b9Wq6kzBzOZaO2FSloWvop
+OXoFBDKSsaNzbTQVHSeYS3kjeBM20tMaunWANBFN95I5pKKrY9qjIcGUJk1Asqr7
+WnurfSO2Ez/Q25BvpMrlkiwq2yBTd0j1O47CwcSOOXHVIgCgW3eloz2GrksoU3p2
+b6o8Q1dMP0FDyr978aaj7y33QP4EH74RS5DTErXW/QygeJ4vLogD7TOQFWJYBKQu
+zbsNAoGBANa5Wi9KvsPp5ltbiwrLeoVTPmFwAhJPw+B+OEoRN4oMqstIBOZiYz1+
+WV/nA3WR1gOd/TbDL4kzXL9SYl/y8QmFjrc7B4vIGLhWnDBjl1l/wvYhxMXbfHEN
+2VqZVICSoEVICphx6SPflFH53kmGrIiBs9GWFv9cAVGHi1j52rvRAoGBAMt4JZ8p
+LbiBRxJ+f9QeVz0QaDI1rJ4Ld5fgrbFX3IxJe5u5BW/GK4Fd3o5Zb0j8JDI1Wgs3
+e1ugDNGXrV2zXkyX5X+4syPGtclcNaQSJAew4xcGFERZkvRPeGUVmzJ9Vk88fkFq
+9nMDg8HX8EX63To3XSmcBJcHiRwqNAPQlAJLAoGAdBEp1F/BD/QN0ISCgmAmjUHA
+2rkV4GJ3t54sQ7ZHiORApTuvnyBs/qUpZEWFVE7UjFVmRx1lzZ85DXij4NZYxuBo
+0b8K/3MUR/d3BWZD+QbKP9rm532PX7R1fRScYSypqOiryAY41R7oY6molnJPbGHI
++6sTWZmELBHqdUjJQu0CgYEAuvjIoBgAgAgXy84wRmER5RX+4gfPDcVZI8eK2lC8
+0/B/bICBiU5RfcvhRImI20iP9sk9/HgsKq6/q9d8tvfaHN6bih9Ygb2Ec9gxSqji
+1qKLfPDUWnvTJbDPf3ujXtQKH0xYV8oS5jqUv/bcyq8sJ6h/H1EY+XyL1LEo4Oku
+D/ECgYBfQ7PZM1KuL0zpD6imxUgyNNSXdGTfM9XUSY5L8e2xWqjnZT+Cj1bUGVYM
+xrpC8bpfGGTyBv/v6N7NxPep1QeyM9E0o0z0ID9ybRpX4ErYSp1sLZBNlBXdAAL9
+nexoXbZDpN0zdBE5wnAMjcjHTp9PMSDeWt4/r2aiNde3VFwnWg==
+-----END RSA PRIVATE KEY-----
diff --git a/robot/assets/keys/robot_ssh_public_key.pub b/robot/assets/keys/robot_ssh_public_key.pub
new file mode 100644 (file)
index 0000000..934c60a
--- /dev/null
@@ -0,0 +1,9 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: "rsa-key-20161026"
+AAAAB3NzaC1yc2EAAAABJQAAAQEAqqnA9BAiMLtjOPSYBfhzLu4CiBolWoskDg4K
+VwhTJVTTeB6CqrQNcadlGXxOHhCYuNCKkUmIVF4WTOisVOJ75Z1c4OMoZLL85xVP
+KSIeH63kgVugwgPYQu55NbbWX+rsbUha3LnElDhNviMM3iTPbD5nnhKixNERAJMT
+LKXvZZZGqxW94bREknYPQTT2qrk3YRqwldncopp6Nkgv3AnSJz2gc9tjxnWF0poT
+QnQm/3D6hiJICrzKfAV0EaPN0KdtYjPhKrYoy6Qb/tKOVaaqsvwfKBJGrT9LfcA7
+D7M/yj292RT1XN63hI84WC383LsaPJ6eWdDTE6zUP1eGTWCoOw==
+---- END SSH2 PUBLIC KEY ----
diff --git a/robot/assets/keys/robot_ssh_public_key.txt b/robot/assets/keys/robot_ssh_public_key.txt
new file mode 100644 (file)
index 0000000..43a61cd
--- /dev/null
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAqqnA9BAiMLtjOPSYBfhzLu4CiBolWoskDg4KVwhTJVTTeB6CqrQNcadlGXxOHhCYuNCKkUmIVF4WTOisVOJ75Z1c4OMoZLL85xVPKSIeH63kgVugwgPYQu55NbbWX+rsbUha3LnElDhNviMM3iTPbD5nnhKixNERAJMTLKXvZZZGqxW94bREknYPQTT2qrk3YRqwldncopp6Nkgv3AnSJz2gc9tjxnWF0poTQnQm/3D6hiJICrzKfAV0EaPN0KdtYjPhKrYoy6Qb/tKOVaaqsvwfKBJGrT9LfcA7D7M/yj292RT1XN63hI84WC383LsaPJ6eWdDTE6zUP1eGTWCoOw== rsa-key-20161026
\ No newline at end of file
diff --git a/robot/assets/service_mappings.py b/robot/assets/service_mappings.py
new file mode 100644 (file)
index 0000000..9e7a2cc
--- /dev/null
@@ -0,0 +1,29 @@
+GLOBAL_SERVICE_FOLDER_MAPPING = {"vFW" : ['base_vfw'], \
+                                 "vLB" : ['base_vlb'], \
+                                 "vVG" : ['base_vvg'], \
+                                 }
+                                 
+GLOBAL_SERVICE_TEMPLATE_MAPPING = {"vFW" : [{"isBase" : "true", "template" : "vfw_preload.template", "name_pattern": "base_vfw"}], \
+                                 "vLB" : [{"isBase" : "true", "template" : "vlb_preload.template", "name_pattern": "base_vlb"},
+                                          {"isBase" : "false", "template" : "dnsscaling_preload.template", "name_pattern": "dnsscaling", "prefix" : "vDNS_"}],
+                                 "vVG" : [{"isBase" : "true", "template" : "vvg_preload.template", "name_pattern": "base_vvg"}], \
+                                 }
+
+
+##
+## The following identifies the stack parameter names for the oam_ecomp network IPS
+## In stantiated by the stack. During stack teardown, we need to ensure that 
+## These ports are deleted due to latency in rackspace to free these ports.
+## This is just a workaround to enable respinning a VM as soon as possible
+GLOBAL_SERVICE_ECOMP_IP_MAPPING = {"vFW" : ['vpg_private_ip_1', 'vfw_private_ip_2','vsn_private_ip_1'], \
+                                 "vLB" : ['vlb_private_ip_1', 'vdns_private_ip_1'],
+                                 "vVG" : [], \
+                                 }
+
+
+## 
+## Used by the Heatbridge Validate Query to A&AI to locate the vserver name
+GLOBAL_VALIDATE_NAME_MAPPING = {"vFW" : 'vfw_name_0',
+                                 "vLB" : 'vlb_name_0',
+                                 "vVG" : '' 
+                                 }
diff --git a/robot/assets/templates/aai/add_cloud_region_body.template b/robot/assets/templates/aai/add_cloud_region_body.template
new file mode 100644 (file)
index 0000000..95b2525
--- /dev/null
@@ -0,0 +1,15 @@
+{
+        "cloud-owner": "${cloud_owner}",
+        "cloud-region-id": "${cloud_region_id}",
+        "cloud-type": "${cloud_type}",
+        "owner-defined-type": "${owner_defined_type}",
+        "cloud-region-version": "${cloud_region_version}",
+        "cloud-zone": "${cloud_zone}",
+        "tenants": {
+                "tenant": [{
+                        "tenant-id": "${tenant_id}",
+                        "tenant-name": "${tenant_name}"
+
+                }]
+        }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/aai/add_customer.template b/robot/assets/templates/aai/add_customer.template
new file mode 100644 (file)
index 0000000..d0ae174
--- /dev/null
@@ -0,0 +1,25 @@
+{
+         "global-customer-id": "${global_customer_id}",
+         "subscriber-name": "${subscriber_name}",
+         "subscriber-type": "${subscriber_type}",
+         "service-subscriptions": {
+                 "service-subscription": [{
+                         "service-type": "${service1}",
+                         "relationship-list": {
+                                 "relationship": [{
+                                         "related-to": "tenant",
+                                         "relationship-data": [{
+                                                 "relationship-key": "cloud-region.cloud-owner",
+                                                 "relationship-value": "${cloud_owner1}"
+                                         }, {
+                                                 "relationship-key": "cloud-region.cloud-region-id",
+                                                 "relationship-value": "${cloud_region_id1}"
+                                         }, {
+                                                 "relationship-key": "tenant.tenant-id",
+                                                 "relationship-value": "${tenant_id1}"
+                                         }]
+                                 }]
+                         }
+                 }]
+         }
+      }
\ No newline at end of file
diff --git a/robot/assets/templates/aai/add_service_body.template b/robot/assets/templates/aai/add_service_body.template
new file mode 100644 (file)
index 0000000..ca32fd5
--- /dev/null
@@ -0,0 +1,6 @@
+{
+   "service-id": "${UUID}",
+   "service-description": "${service_type}"
+}
+
+
diff --git a/robot/assets/templates/aai/add_tenant_body.template b/robot/assets/templates/aai/add_tenant_body.template
new file mode 100644 (file)
index 0000000..a3cea10
--- /dev/null
@@ -0,0 +1,17 @@
+{
+        "cloud-owner": "${cloud_owner}",
+        "cloud-region-id": "${cloud_region_id}",
+        "cloud-type": "${cloud_type}",
+        "owner-defined-type": "${owner_defined_type}",
+        "cloud-region-version": "${cloud_region_version}",
+        "cloud-zone": "${cloud_zone}",
+        "tenants": {
+                "tenant": [{
+                        "tenant-id": "${tenant_id}",
+                        "tenant-name": "${tenant_name}"
+
+                }]
+        }
+}
+
+
diff --git a/robot/assets/templates/aai/named_query.template b/robot/assets/templates/aai/named_query.template
new file mode 100644 (file)
index 0000000..de3f21f
--- /dev/null
@@ -0,0 +1,17 @@
+{ 
+    "query-parameters": { 
+        "named-query": { 
+            "named-query-uuid": "f199cb88-5e69-4b1f-93e0-6f257877d066" 
+        } 
+    }, 
+    "instance-filters": { 
+        "instance-filter": [ 
+            { 
+                "vserver": 
+                { 
+                    "vserver-name": "${vserver_name}" 
+                }
+            } 
+        ] 
+    } 
+}
\ No newline at end of file
diff --git a/robot/assets/templates/aai/service_subscription.template b/robot/assets/templates/aai/service_subscription.template
new file mode 100644 (file)
index 0000000..8570358
--- /dev/null
@@ -0,0 +1,19 @@
+{
+   "service-subscription":[
+      {
+         "service-type":"{$service_type}",
+         "resource-version":"1473866861",
+         "service-instances":{
+            "service-instance":[
+               {
+                  "service-instance-id":"d3f9a631-e280-4a87-846d-9ccd7a265980",
+                  "service-instance-name":"VIV+IST+ezNew+Oct6",
+                  "persona-model-id":"e6f1d393-6432-4820-ab86-7a10ba4b31ac",
+                  "persona-model-version":"1.0",
+                  "resource-version":"1475807447"
+               }
+            ]
+         }
+      }
+   ]
+}
\ No newline at end of file
diff --git a/robot/assets/templates/aai/vlb_closed_loop_hack.template b/robot/assets/templates/aai/vlb_closed_loop_hack.template
new file mode 100644 (file)
index 0000000..27f9c96
--- /dev/null
@@ -0,0 +1,7 @@
+{
+       "is-base-vf-module": false,
+       "persona-model-id": "${persona_model_id}",
+       "persona-model-version": "1.0",
+       "vf-module-id": "${vf_module_id}",
+       "vf-module-name": "${vf_module_id}"                                                              
+}
diff --git a/robot/assets/templates/appc/vnf_mount.template b/robot/assets/templates/appc/vnf_mount.template
new file mode 100644 (file)
index 0000000..8ad1135
--- /dev/null
@@ -0,0 +1,16 @@
+<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
+   <node-id>${nodeid}</node-id>
+   <host xmlns="urn:opendaylight:netconf-node-topology">${host}</host>
+   <port xmlns="urn:opendaylight:netconf-node-topology">${port}</port>
+   <username xmlns="urn:opendaylight:netconf-node-topology">${username}</username>
+   <password xmlns="urn:opendaylight:netconf-node-topology">${password}</password>
+   <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
+   <!-- non-mandatory fields with default values, you can safely remove these if you do not wish to override any of these values-->
+   <reconnect-on-changed-schema xmlns="urn:opendaylight:netconf-node-topology">false</reconnect-on-changed-schema>
+   <connection-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">20000</connection-timeout-millis>
+   <max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">0</max-connection-attempts>
+   <between-attempts-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">2000</between-attempts-timeout-millis>
+   <sleep-factor xmlns="urn:opendaylight:netconf-node-topology">1.5</sleep-factor>
+   <!-- keepalive-delay set to 0 turns off keepalives-->
+   <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">120</keepalive-delay>
+</node>
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/action.template b/robot/assets/templates/asdc/action.template
new file mode 100644 (file)
index 0000000..4d417c9
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "action": "${action}"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/catalog_resource.template b/robot/assets/templates/asdc/catalog_resource.template
new file mode 100644 (file)
index 0000000..fcc17ce
--- /dev/null
@@ -0,0 +1,43 @@
+{
+  "artifacts": {},
+  "toscaArtifacts": {},
+  "contactId": "cs0008",
+  "categories": [
+    {
+      "name": "Generic",
+      "normalizedName": "generic",
+      "uniqueId": "resourceNewCategory.generic",
+      "subcategories": [
+        {
+          "name": "Abstract",
+          "normalizedName": "abstract",
+          "uniqueId": "resourceNewCategory.generic.abstract",
+          "icons": [
+            "database"
+          ]
+        }
+      ]
+    }
+  ],
+  "description": "vendor software product",
+  "icon": "defaulticon",
+  "componentInstancesProperties": {},
+  "componentInstancesAttributes": {},
+  "name": "${software_product_name}",
+  "tags": [
+    "${software_product_name}"
+  ],
+  "capabilities": {},
+  "requirements": {},
+  "deploymentArtifacts": {},
+  "componentType": "RESOURCE",
+  "vendorName": "${vendor_name}",
+  "vendorRelease": "1.0",
+  "componentInstances": [],
+  "properties": [],
+  "attributes": [],
+  "groups": [],
+  "resourceType": "VF",
+  "csarUUID": "${software_product_id}",
+  "csarVersion": "1.0"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/catalog_service.template b/robot/assets/templates/asdc/catalog_service.template
new file mode 100644 (file)
index 0000000..e7ffdea
--- /dev/null
@@ -0,0 +1,34 @@
+{
+  "artifacts": {},
+  "toscaArtifacts": {},
+  "contactId": "cs0008",
+  "categories": [
+    {
+      "name": "Network L1-3",
+      "normalizedName": "network l1-3",
+      "uniqueId": "serviceNewCategory.network l1-3",
+      "icons": [
+        "network_l_1-3"
+      ]
+    }
+  ],
+  "description": "catalog service description",
+  "icon": "network_l_1-3",
+  "componentInstancesProperties": {},
+  "componentInstancesAttributes": {},
+  "name": "${service_name}",
+  "tags": [
+    "robot-ete",
+    "${service_name}"
+  ],
+  "capabilities": {},
+  "requirements": {},
+  "deploymentArtifacts": {},
+  "componentType": "SERVICE",
+  "projectCode": "123456",
+  "componentInstances": [],
+  "properties": [],
+  "attributes": [],
+  "groups": [],
+  "serviceApiArtifacts": {}
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/entitlement_pool.template b/robot/assets/templates/asdc/entitlement_pool.template
new file mode 100644 (file)
index 0000000..bcb04d2
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  "name": "${entitlement_pool_name}",
+  "description": "vendor entitlement pool",
+  "thresholdValue": "99",
+  "thresholdUnits": "Absolute",
+  "entitlementMetric": {
+    "choice": "CPU",
+    "other": ""
+  },
+  "increments": "robot",
+  "aggregationFunction": {
+    "choice": "Peak",
+    "other": ""
+  },
+  "operationalScope": {
+    "choices": [
+      "Availability_Zone"
+    ],
+    "other": ""
+  },
+  "time": {
+    "choice": "Hour",
+    "other": ""
+  },
+  "manufacturerReferenceNumber": "robot12345"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/feature_group.template b/robot/assets/templates/asdc/feature_group.template
new file mode 100644 (file)
index 0000000..3d87b04
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "name": "${feature_group_name}",
+  "description": "vendor feature group",
+  "partNumber": "123abc456",
+  "addedLicenseKeyGroupsIds": [
+    "${key_group_id}"
+  ],
+  "addedEntitlementPoolsIds": [
+    "${entitlement_pool_id}"
+  ]
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/key_group.template b/robot/assets/templates/asdc/key_group.template
new file mode 100644 (file)
index 0000000..2081261
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "name": "${key_group_name}",
+  "description": "vendor license key group",
+  "operationalScope": {
+    "choices": [
+      "Tenant"
+    ],
+    "other": ""
+  },
+  "type": "Universal"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/license_agreement.template b/robot/assets/templates/asdc/license_agreement.template
new file mode 100644 (file)
index 0000000..6324d14
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "name": "${license_agreement_name}",
+  "description": "vendor license agreement",
+  "requirementsAndConstrains": "abcdef",
+  "licenseTerm": {
+    "choice": "Fixed_Term",
+    "other": ""
+  },
+  "addedFeatureGroupsIds": [
+    "${feature_group_id}"
+  ]
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/license_model.template b/robot/assets/templates/asdc/license_model.template
new file mode 100644 (file)
index 0000000..45fc83f
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "vendorName": "${vendor_name}",
+  "description": "vendor license model",
+  "iconRef": "icon"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/resource_instance.template b/robot/assets/templates/asdc/resource_instance.template
new file mode 100644 (file)
index 0000000..215f828
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "uniqueId": "${catalog_resource_id}${milli_timestamp}",
+  "posX": 406,
+  "posY": 248,
+  "name": "${catalog_resource_name}",
+  "componentVersion": "1.0",
+  "originType": "VF",
+  "icon": "defaulticon",
+  "componentUid": "${catalog_resource_id}"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/software_product.template b/robot/assets/templates/asdc/software_product.template
new file mode 100644 (file)
index 0000000..f8a4752
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "name": "${software_product_name}",
+  "description": "vendor software product",
+  "category": "resourceNewCategory.generic",
+  "subCategory": "resourceNewCategory.generic.abstract",
+  "licensingVersion": "1.0",
+  "vendorName": "${vendor_name}",
+  "vendorId": "${vendor_id}",
+  "icon": "icon",
+  "licensingData": {
+    "licenseAgreement": "${license_agreement_id}",
+    "featureGroups": [
+      "${feature_group_id}"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/asdc/user_remarks.template b/robot/assets/templates/asdc/user_remarks.template
new file mode 100644 (file)
index 0000000..465115e
--- /dev/null
@@ -0,0 +1 @@
+{"userRemarks":"${user_remarks}"}
\ No newline at end of file
diff --git a/robot/assets/templates/cinder_add_volume.template b/robot/assets/templates/cinder_add_volume.template
new file mode 100644 (file)
index 0000000..544f41e
--- /dev/null
@@ -0,0 +1,9 @@
+{
+    "volume": {
+        "display_name": "${name}",
+        "display_description": "${description}",
+        "size": ${size},
+        "volume_type": "${type}",
+        "availability_zone": "${availability_zone}"
+    }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/heat_add_stack.template b/robot/assets/templates/heat_add_stack.template
new file mode 100644 (file)
index 0000000..c3af317
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "files": {},
+    "disable_rollback": true,
+    "stack_name": "${stack_name}",
+    "parameters": 
+        ${parameters}
+    ,
+    "template":  
+        ${template}
+    ,
+    "timeout_mins": 60
+}
\ No newline at end of file
diff --git a/robot/assets/templates/keystone_get_auth.template b/robot/assets/templates/keystone_get_auth.template
new file mode 100644 (file)
index 0000000..255f8ff
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "auth": {
+    "passwordCredentials": {
+      "username": "${username}",
+      "password": "${password}"
+    }
+  }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/neutron_add_network.template b/robot/assets/templates/neutron_add_network.template
new file mode 100644 (file)
index 0000000..36382d4
--- /dev/null
@@ -0,0 +1,7 @@
+{
+ "network":
+  {
+    "name": "${name}",
+    "admin_state_up": false
+  }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/neutron_add_subnet.template b/robot/assets/templates/neutron_add_subnet.template
new file mode 100644 (file)
index 0000000..5a4264f
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "subnet": {
+        "network_id": "${network_id}",
+        "ip_version": 4,
+        "name":"${subnet_name}",
+        "cidr": "${cidr}"
+    }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/nova_add_keypair.template b/robot/assets/templates/nova_add_keypair.template
new file mode 100644 (file)
index 0000000..52e2b06
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    "keypair": {
+        "name": "${name}",
+        "public_key": "${publickey}"
+    }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/nova_add_server.template b/robot/assets/templates/nova_add_server.template
new file mode 100644 (file)
index 0000000..8157839
--- /dev/null
@@ -0,0 +1,17 @@
+{
+    "server": {
+        "name": "${name}",
+        "imageRef": "${imageRef}",
+        "flavorRef": "${flavorRef}",
+        "config_drive": true,
+        "OS-DCF:diskConfig": "MANUAL",
+        "metadata": {
+            "${name}": "Server for attaching VVG"
+        },
+        "networks": [
+            {
+                "uuid": "00000000-0000-0000-0000-000000000000"
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/policy/closedloop_configpolicy.template b/robot/assets/templates/policy/closedloop_configpolicy.template
new file mode 100644 (file)
index 0000000..e14b615
--- /dev/null
@@ -0,0 +1,31 @@
+{
+                "service": "TcaMetrics",
+                "location": "SampleServiceLocation",
+                "uuid": "/services/cdap-tca-hi-lo/instances/demo/configuration/metricsPerFunctionalRole/vFireWall",
+                "policyName": "${policy_name}",
+                "description": "vFirewall configuration Policy@CreatedBy:demo@CreatedBy:@ModifiedBy:demo@ModifiedBy:",
+                "configName": "SampleConfigName",
+                "templateVersion": "OpenSource.version.1",
+                "version": "1.0.0.5",
+                "priority": "1",
+                "policyScope": "resource=SampleResource,service=SampleService,type=SampleType,closedLoopControlName=SampleClosedLoop",
+                "content": {
+                                "thresholds": [{
+                                                "severity": "MAJOR",
+                                                "fieldPath": "$$.event.measurementsForVfScalingFields.vNicUsageArray[*].packetsIn",
+                                                "thresholdValue": "300",
+                                                "closedLoopControlName": "CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8",
+                                                "version": "1.0.2",
+                                                "direction": "LESS_OR_EQUAL"
+                                }, {
+                                                "severity": "CRITICAL",
+                                                "fieldPath": "$$.event.measurementsForVfScalingFields.vNicUsageArray[*].packetsIn",
+                                                "thresholdValue": "800",
+                                                "closedLoopControlName": "CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8",
+                                                "version": "1.0.2",
+                                                "direction": "GREATER_OR_EQUAL"
+                                }],
+                                "functionalRole": "vFirewall",
+                                "name": "0"
+                }
+}
diff --git a/robot/assets/templates/policy/closedloop_createpolicy.template b/robot/assets/templates/policy/closedloop_createpolicy.template
new file mode 100644 (file)
index 0000000..7c693e8
--- /dev/null
@@ -0,0 +1,21 @@
+{
+       "policyConfigType": "BRMS_PARAM",
+       "policyName": "${policy_name}",
+       "policyDescription": "Create BRMS Param policy",
+       "attributes": {
+               "RULE": {
+                       "templateName": "ClosedLoopDemo_closedLoopControlName",
+                       "aaiNamedQueryUUID": "2",
+                       "aaiPassword": "2",
+                       "aaiPatternMatch": "2",
+                       "aaiURL": "2",
+                       "actor": "2",
+                       "appcTopic": "2",
+                       "closedLoopControlName": "2",
+                       "msoPassword": "2",
+                       "msoURL": "2",
+                       "msoUsername": "2",
+                       "aaiUsername": "3"
+               }
+       }
+}
diff --git a/robot/assets/templates/policy/closedloop_deletepolicy.template b/robot/assets/templates/policy/closedloop_deletepolicy.template
new file mode 100644 (file)
index 0000000..5551010
--- /dev/null
@@ -0,0 +1,5 @@
+{
+    "pdpGroup": "default",
+    "policyComponent": "PDP",
+    "policyName": "${policy_name}"
+}
diff --git a/robot/assets/templates/policy/closedloop_getconfigpolicy.template b/robot/assets/templates/policy/closedloop_getconfigpolicy.template
new file mode 100644 (file)
index 0000000..34145e5
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "configAttributes" : {
+    },
+    "configName" : ".*",
+    "ecompName" : "DCAE",
+    "policyName" : "${config_policy_name}",
+    "unique" : true
+}
\ No newline at end of file
diff --git a/robot/assets/templates/policy/closedloop_opspolicy.template b/robot/assets/templates/policy/closedloop_opspolicy.template
new file mode 100644 (file)
index 0000000..722c9dc
--- /dev/null
@@ -0,0 +1,25 @@
+
+{ 
+       "policyConfigType": "BRMS_PARAM", 
+       "policyName": "${policy_name}", 
+       "policyDescription": "Create BRMS Param policy for vFW", 
+       "attributes": { 
+               "RULE": { 
+                       "templateName": "ControlLoopDemo__closedLoopControlName", 
+                       "closedLoopControlName": "CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8", 
+                       "policyVersion": "v1.0", 
+                       "aaiNamedQueryUUID": "null", 
+                       "aaiPassword": "null", 
+                       "aaiURL": "null", 
+                       "actor": "APPC", 
+                       "appcTopic": "APPC-CL", 
+                       "msoPassword": "null", 
+                       "msoURL": "null", 
+                       "msoUsername": "null", 
+                       "aaiUsername": "null", 
+                       "notificationTopic": "POLICY-CL-MGT", 
+                       "aaiPatternMatch": 1 
+               } 
+       } 
+}
+
diff --git a/robot/assets/templates/policy/closedloop_pushpolicy.template b/robot/assets/templates/policy/closedloop_pushpolicy.template
new file mode 100644 (file)
index 0000000..ce1d485
--- /dev/null
@@ -0,0 +1,5 @@
+{
+    "policyName" : "${policy_name}",
+    "policyType" : "${policy_type}",
+    "pdpGroup" : "default"
+}
\ No newline at end of file
diff --git a/robot/assets/templates/sdnc/dnsscaling_preload.template b/robot/assets/templates/sdnc/dnsscaling_preload.template
new file mode 100644 (file)
index 0000000..cf988d5
--- /dev/null
@@ -0,0 +1,96 @@
+{
+    "input": {
+        "vnf-topology-information": {
+            "vnf-topology-identifier": {
+                "service-type": "${service_type}",
+                "vnf-name": "${vf_module_name}",
+                "vnf-type": "${vf_module_type}",
+                "generic-vnf-name": "${generic_vnf_name}",
+                "generic-vnf-type": "${generic_vnf_type}"
+            },
+            "vnf-assignments": {
+                "availability-zones": [],
+                "vnf-networks": [],
+                "vnf-vms": []
+            },
+             "vnf-parameters": [
+                {
+                    "vnf-parameter-name": "repo_url",
+                    "vnf-parameter-value": "${repo_url}"
+                },
+                {
+                    "vnf-parameter-name": "repo_user",
+                    "vnf-parameter-value": "${repo_user}"
+                },
+                {
+                    "vnf-parameter-name": "repo_passwd",
+                    "vnf-parameter-value": "${repo_passwd}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_net_id",
+                    "vnf-parameter-value": "${ecomp_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_subnet_id",
+                    "vnf-parameter-value": "${ecomp_private_subnet_id}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_net_cidr",
+                    "vnf-parameter-value": "${ecomp_private_net_cidr}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_net_id",
+                    "vnf-parameter-value": "${vlb_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_ip_0",
+                    "vnf-parameter-value": "${vlb_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_ip_1",
+                    "vnf-parameter-value": "${vlb_private_ip_1}"
+                },
+                 {
+                    "vnf-parameter-name": "vdns_private_ip_0",
+                    "vnf-parameter-value": "${vdns_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vdns_private_ip_1",
+                    "vnf-parameter-value": "${vdns_private_ip_1}"
+                },
+                {
+                    "vnf-parameter-name": "vdns_name_0",
+                    "vnf-parameter-value": "${scaling_vdns_name_0}"
+                },
+                {
+                    "vnf-parameter-name": "webserver_ip",
+                    "vnf-parameter-value": "${webserver_ip}"
+                },
+                {
+                    "vnf-parameter-name": "dcae_collector_ip",
+                    "vnf-parameter-value": "${dcae_collector_ip}"
+                },
+                {
+                    "vnf-parameter-name": "key_name",
+                    "vnf-parameter-value": "${key_name}"
+                },
+                {
+                    "vnf-parameter-name": "pub_key",
+                    "vnf-parameter-value": "${pub_key}"
+                }
+            ]
+        },
+        "request-information": {
+            "request-id": "robot12",
+            "order-version": "1",
+            "notification-url": "openecomp.org",
+            "order-number": "1",
+            "request-action": "PreloadVNFRequest"
+        },
+        "sdnc-request-header": {
+            "svc-request-id": "robot12",
+            "svc-notification-url": "http:\/\/openecomp.org:8080\/adapters\/rest\/SDNCNotify",
+            "svc-action": "reserve"
+        }
+    }    
+}
\ No newline at end of file
diff --git a/robot/assets/templates/sdnc/vfw_preload.template b/robot/assets/templates/sdnc/vfw_preload.template
new file mode 100644 (file)
index 0000000..c94c565
--- /dev/null
@@ -0,0 +1,132 @@
+{
+    "input": {
+        "vnf-topology-information": {
+            "vnf-topology-identifier": {
+                "service-type": "${service_type}",
+                "vnf-name": "${vf_module_name}",
+                "vnf-type": "${vf_module_type}",
+                "generic-vnf-name": "${generic_vnf_name}",
+                "generic-vnf-type": "${generic_vnf_type}"
+            },
+            "vnf-assignments": {
+                "availability-zones": [],
+                "vnf-networks": [],
+                "vnf-vms": []
+            },
+             "vnf-parameters": [
+                {
+                    "vnf-parameter-name": "repo_url",
+                    "vnf-parameter-value": "${repo_url}"
+                },
+                {
+                    "vnf-parameter-name": "repo_user",
+                    "vnf-parameter-value": "${repo_user}"
+                },
+                {
+                    "vnf-parameter-name": "repo_passwd",
+                    "vnf-parameter-value": "${repo_passwd}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_net_id",
+                    "vnf-parameter-value": "${ecomp_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_subnet_id",
+                    "vnf-parameter-value": "${ecomp_private_subnet_id}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_net_cidr",
+                    "vnf-parameter-value": "${ecomp_private_net_cidr}"
+                },
+                {
+                    "vnf-parameter-name": "unprotected_private_net_id",
+                    "vnf-parameter-value": "${unprotected_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "protected_private_net_id",
+                    "vnf-parameter-value": "${protected_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "protected_private_net_cidr",
+                    "vnf-parameter-value": "${protected_private_net_cidr}"
+                },
+                {
+                    "vnf-parameter-name": "unprotected_private_net_cidr",
+                    "vnf-parameter-value": "${unprotected_private_net_cidr}"
+                },
+                {
+                    "vnf-parameter-name": "vfw_private_ip_0",
+                    "vnf-parameter-value": "${vfw_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vfw_private_ip_1",
+                    "vnf-parameter-value": "${vfw_private_ip_1}"
+                },
+                {
+                    "vnf-parameter-name": "vfw_private_ip_2",
+                    "vnf-parameter-value": "${vfw_private_ip_2}"
+                },
+                {
+                    "vnf-parameter-name": "vpg_private_ip_0",
+                    "vnf-parameter-value": "${vpg_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vpg_private_ip_1",
+                    "vnf-parameter-value": "${vpg_private_ip_1}"
+                },
+                {
+                    "vnf-parameter-name": "vsn_private_ip_0",
+                    "vnf-parameter-value": "${vsn_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vsn_private_ip_1",
+                    "vnf-parameter-value": "${vsn_private_ip_1}"
+                },
+                {
+                    "vnf-parameter-name": "vfw_name_0",
+                    "vnf-parameter-value": "${vfw_name_0}"
+                },
+                {
+                    "vnf-parameter-name": "vpg_name_0",
+                    "vnf-parameter-value": "${vpg_name_0}"
+                },
+                {
+                    "vnf-parameter-name": "vsn_name_0",
+                    "vnf-parameter-value": "${vsn_name_0}"
+                },
+                {
+                    "vnf-parameter-name": "webserver_ip",
+                    "vnf-parameter-value": "${webserver_ip}"
+                },
+                {
+                    "vnf-parameter-name": "dcae_collector_ip",
+                    "vnf-parameter-value": "${dcae_collector_ip}"
+                },
+                {
+                    "vnf-parameter-name": "dcae_collector_port",
+                    "vnf-parameter-value": "${dcae_collector_port}"
+                },
+                {
+                    "vnf-parameter-name": "key_name",
+                    "vnf-parameter-value": "${key_name}"
+                },
+                {
+                    "vnf-parameter-name": "pub_key",
+                    "vnf-parameter-value": "${pub_key}"
+                }
+            ]
+        },
+        "request-information": {
+            "request-id": "robot12",
+            "order-version": "1",
+            "notification-url": "openecomp.org",
+            "order-number": "1",
+            "request-action": "PreloadVNFRequest"
+        },
+        "sdnc-request-header": {
+            "svc-request-id": "robot12",
+            "svc-notification-url": "http:\/\/openecomp.org:8080\/adapters\/rest\/SDNCNotify",
+            "svc-action": "reserve"
+        }
+    }    
+}
\ No newline at end of file
diff --git a/robot/assets/templates/sdnc/vlb_preload.template b/robot/assets/templates/sdnc/vlb_preload.template
new file mode 100644 (file)
index 0000000..736f790
--- /dev/null
@@ -0,0 +1,108 @@
+{
+    "input": {
+        "vnf-topology-information": {
+            "vnf-topology-identifier": {
+                "service-type": "${service_type}",
+                "vnf-name": "${vf_module_name}",
+                "vnf-type": "${vf_module_type}",
+                "generic-vnf-name": "${generic_vnf_name}",
+                "generic-vnf-type": "${generic_vnf_type}"
+            },
+            "vnf-assignments": {
+                "availability-zones": [],
+                "vnf-networks": [],
+                "vnf-vms": []
+            },
+             "vnf-parameters": [
+                {
+                    "vnf-parameter-name": "repo_url",
+                    "vnf-parameter-value": "${repo_url}"
+                },
+                {
+                    "vnf-parameter-name": "repo_user",
+                    "vnf-parameter-value": "${repo_user}"
+                },
+                {
+                    "vnf-parameter-name": "repo_passwd",
+                    "vnf-parameter-value": "${repo_passwd}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_net_id",
+                    "vnf-parameter-value": "${ecomp_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_subnet_id",
+                    "vnf-parameter-value": "${ecomp_private_subnet_id}"
+                },
+                {
+                    "vnf-parameter-name": "ecomp_private_net_cidr",
+                    "vnf-parameter-value": "${ecomp_private_net_cidr}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_net_id",
+                    "vnf-parameter-value": "${vlb_private_net_id}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_net_cidr",
+                    "vnf-parameter-value": "${vlb_private_net_cidr}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_ip_0",
+                    "vnf-parameter-value": "${vlb_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_private_ip_1",
+                    "vnf-parameter-value": "${vlb_private_ip_1}"
+                },
+                 {
+                    "vnf-parameter-name": "vdns_private_ip_0",
+                    "vnf-parameter-value": "${vdns_private_ip_0}"
+                },
+                {
+                    "vnf-parameter-name": "vdns_private_ip_1",
+                    "vnf-parameter-value": "${vdns_private_ip_1}"
+                },
+                {
+                    "vnf-parameter-name": "vlb_name_0",
+                    "vnf-parameter-value": "${vlb_name_0}"
+                },
+                {
+                    "vnf-parameter-name": "vdns_name_0",
+                    "vnf-parameter-value": "${vdns_name_0}"
+                },
+                {
+                    "vnf-parameter-name": "webserver_ip",
+                    "vnf-parameter-value": "${webserver_ip}"
+                },
+                {
+                    "vnf-parameter-name": "dcae_collector_ip",
+                    "vnf-parameter-value": "${dcae_collector_ip}"
+                },
+                {
+                    "vnf-parameter-name": "dcae_collector_port",
+                    "vnf-parameter-value": "${dcae_collector_port}"
+                },
+                {
+                    "vnf-parameter-name": "key_name",
+                    "vnf-parameter-value": "${key_name}"
+                },
+                {
+                    "vnf-parameter-name": "pub_key",
+                    "vnf-parameter-value": "${pub_key}"
+                }
+            ]
+        },
+        "request-information": {
+            "request-id": "robot12",
+            "order-version": "1",
+            "notification-url": "openecomp.org",
+            "order-number": "1",
+            "request-action": "PreloadVNFRequest"
+        },
+        "sdnc-request-header": {
+            "svc-request-id": "robot12",
+            "svc-notification-url": "http:\/\/openecomp.org:8080\/adapters\/rest\/SDNCNotify",
+            "svc-action": "reserve"
+        }
+    }    
+}
\ No newline at end of file
diff --git a/robot/assets/templates/sdnc/vvg_preload.template b/robot/assets/templates/sdnc/vvg_preload.template
new file mode 100644 (file)
index 0000000..83095e9
--- /dev/null
@@ -0,0 +1,36 @@
+{
+    "input": {
+        "vnf-topology-information": {
+            "vnf-topology-identifier": {
+                "service-type": "${service_type}",
+                "vnf-name": "${vf_module_name}",
+                "vnf-type": "${vf_module_type}",
+                "generic-vnf-name": "${generic_vnf_name}",
+                "generic-vnf-type": "${generic_vnf_type}"
+            },
+            "vnf-assignments": {
+                "availability-zones": [],
+                "vnf-networks": [],
+                "vnf-vms": []
+            },
+             "vnf-parameters": [
+                               {
+                    "vnf-parameter-name": "nova_instance",
+                    "vnf-parameter-value": "${nova_instance}"
+                }
+            ]
+        },
+        "request-information": {
+            "request-id": "robot12",
+            "order-version": "1",
+            "notification-url": "openecomp.org",
+            "order-number": "1",
+            "request-action": "PreloadVNFRequest"
+        },
+        "sdnc-request-header": {
+            "svc-request-id": "robot12",
+            "svc-notification-url": "http:\/\/openecomp.org:8080\/adapters\/rest\/SDNCNotify",
+            "svc-action": "reserve"
+        }
+    }    
+}
\ No newline at end of file
diff --git a/robot/assets/templates/template_example.template b/robot/assets/templates/template_example.template
new file mode 100644 (file)
index 0000000..42583f1
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "requestReferences": {
+    "instanceId": "${instanceId}",
+    "requestId": "${requestId}"
+  }
+}
\ No newline at end of file
diff --git a/robot/assets/templates/vfw_pg_stream_enable.template b/robot/assets/templates/vfw_pg_stream_enable.template
new file mode 100644 (file)
index 0000000..c503633
--- /dev/null
@@ -0,0 +1,4 @@
+                       {
+                               "id" : "${stream}",
+                               "is-enabled" : "true"
+                       }
diff --git a/robot/assets/templates/vfw_pg_streams_enable.template b/robot/assets/templates/vfw_pg_streams_enable.template
new file mode 100644 (file)
index 0000000..8f5fec6
--- /dev/null
@@ -0,0 +1,7 @@
+{
+       "pg-streams" : {
+               "pg-stream" : [
+${pgstreams}
+               ]
+       }
+}
diff --git a/robot/resources/aaf_interface.robot b/robot/resources/aaf_interface.robot
new file mode 100644 (file)
index 0000000..57d4aab
--- /dev/null
@@ -0,0 +1,29 @@
+*** Settings ***
+Documentation    The main interface for interacting with AAF. It handles low level stuff like managing the http request library and AAF required fields
+Library                  RequestsClientCert
+Library              RequestsLibrary
+Library                  UUID      
+
+Resource          global_properties.robot
+
+*** Variables ***
+${AAF_HEALTH_CHECK_PATH}        /authz/nss/org.openecomp
+
+*** Keywords ***
+Run AAF Health Check
+     [Documentation]    Runs AAF Health check
+     ${resp}=    Run AAF Get Request    ${AAF_HEALTH_CHECK_PATH}    
+     Should Be Equal As Strings        ${resp.status_code}     200
+     Should Contain    ${resp.json()}    ns
+         
+Run AAF Get Request
+     [Documentation]    Runs AAF Get request
+     [Arguments]    ${data_path}
+     ${auth}=  Create List  ${GLOBAL_AAF_USERNAME}    ${GLOBAL_AAF_PASSWORD}
+     ${session}=    Create Session     aaf     ${GLOBAL_AAF_SERVER}    auth=${auth}
+     ${uuid}=    Generate UUID
+     ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+     ${resp}=  Get Request     aaf     ${data_path}     headers=${headers}
+     Log    Received response from aaf ${resp.text}
+     [Return]    ${resp}
+
diff --git a/robot/resources/aai/aai_interface.robot b/robot/resources/aai/aai_interface.robot
new file mode 100644 (file)
index 0000000..4345180
--- /dev/null
@@ -0,0 +1,58 @@
+*** Settings ***
+Documentation     The main interface for interacting with A&AI. It handles low level stuff like managing the http request library and A&AI required fields
+Library              RequestsLibrary
+Library                  UUID      
+Resource            ../global_properties.robot
+
+*** Variables ***
+${AAI_HEALTH_PATH}  /aai/util/echo?action=long
+
+*** Keywords ***
+Run A&AI Health Check
+    [Documentation]    Runs an A&AI health check
+    ${resp}=    Run A&AI Get Request    ${AAI_HEALTH_PATH}    
+    Should Be Equal As Strings         ${resp.status_code}     200
+
+Run A&AI Get Request
+    [Documentation]    Runs an A&AI get request
+    [Arguments]    ${data_path}
+    ${auth}=  Create List  ${GLOBAL_AAI_USERNAME}    ${GLOBAL_AAI_PASSWORD}
+    ${session}=    Create Session      aai     ${GLOBAL_AAI_SERVER_URL}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     aai     ${data_path}     headers=${headers}
+    Log    Received response from aai ${resp.text}
+    [Return]    ${resp}
+    
+Run A&AI Put Request
+    [Documentation]    Runs an A&AI put request
+    [Arguments]    ${data_path}    ${data}
+    ${auth}=  Create List  ${GLOBAL_AAI_USERNAME}    ${GLOBAL_AAI_PASSWORD}
+    ${session}=    Create Session      aai     ${GLOBAL_AAI_SERVER_URL}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Put Request     aai     ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from aai ${resp.text}
+    [Return]    ${resp}
+
+Run A&AI Post Request
+    [Documentation]    Runs an A&AI Post request
+    [Arguments]    ${data_path}    ${data}
+    ${auth}=  Create List  ${GLOBAL_AAI_USERNAME}    ${GLOBAL_AAI_PASSWORD}
+    ${session}=    Create Session      aai     ${GLOBAL_AAI_SERVER_URL}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Post Request    aai     ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from aai ${resp.text}
+    [Return]    ${resp}
+    
+Run A&AI Delete Request
+    [Documentation]    Runs an A&AI delete request
+    [Arguments]    ${data_path}    ${resource_version}
+    ${auth}=  Create List  ${GLOBAL_AAI_USERNAME}    ${GLOBAL_AAI_PASSWORD}
+    ${session}=    Create Session      aai     ${GLOBAL_AAI_SERVER_URL}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Delete Request  aai     ${data_path}?resource-version=${resource_version}       headers=${headers}
+    Log    Received response from aai ${resp.text}
+    [Return]    ${resp}
\ No newline at end of file
diff --git a/robot/resources/aai/create_customer.robot b/robot/resources/aai/create_customer.robot
new file mode 100644 (file)
index 0000000..7ebda39
--- /dev/null
@@ -0,0 +1,41 @@
+*** Settings ***
+Documentation    Create A&AI Customer API.
+...
+...                  Create A&AI Customer API
+
+Resource   aai_interface.robot
+Resource   ../json_templater.robot
+Library    Collections
+Library    OperatingSystem
+
+
+*** Variables ***
+${INDEX PATH}     /aai/v8 
+${ROOT_CUSTOMER_PATH}  /business/customers/customer/
+${SYSTEM USER}    robot-ete
+${A&AI ADD CUSTOMER BODY}    robot/assets/templates/aai/add_customer.template
+
+*** Keywords ***    
+Create Customer
+    [Documentation]    Creates a customer in A&AI      
+    [Arguments]    ${customer_name}  ${customer_id}  ${customer_type}    ${service_type}      ${clouder_owner}    ${cloud_region_id}    ${tenant_id}  
+    ${data_template}=    OperatingSystem.Get File    ${A&AI ADD CUSTOMER BODY}  
+    ${arguments}=    Create Dictionary    subscriber_name=${customer_name}    global_customer_id=${customer_id}    subscriber_type=${customer_type}     cloud_owner1=${clouder_owner}  cloud_region_id1=${cloud_region_id}    tenant_id1=${tenant_id}    service1=${service_type}       
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}         
+       ${put_resp}=    Run A&AI Put Request     ${INDEX PATH}${ROOT_CUSTOMER_PATH}${customer_id}    ${data}
+    Should Be Equal As Strings         ${put_resp.status_code}         201
+       [Return]  ${put_resp.status_code}
+
+*** Keywords ***    
+Delete Customer
+    [Documentation]    Deletes a customer in A&AI      
+    [Arguments]    ${customer_id}
+    ${get_resp}=    Run A&AI Get Request     ${INDEX PATH}${ROOT_CUSTOMER_PATH}${customer_id}    
+       Run Keyword If    '${get_resp.status_code}' == '200'    Delete Customer Exists    ${customer_id}    ${get_resp.json()['resource-version']}
+          
+*** Keywords ***    
+Delete Customer Exists
+    [Documentation]    Deletes a customer in A&AI      
+    [Arguments]    ${customer_id}    ${resource_version_id}   
+    ${put_resp}=    Run A&AI Delete Request    ${INDEX PATH}${ROOT_CUSTOMER_PATH}${customer_id}    ${resource_version_id}
+    Should Be Equal As Strings         ${put_resp.status_code}         204  
diff --git a/robot/resources/aai/create_service.robot b/robot/resources/aai/create_service.robot
new file mode 100644 (file)
index 0000000..38aef3f
--- /dev/null
@@ -0,0 +1,75 @@
+*** Settings ***
+Documentation    Create A&AI Customer API.
+...
+...                  Create A&AI Customer API
+
+Resource    ../json_templater.robot
+Resource    aai_interface.robot
+Library    OperatingSystem
+Library    Collections
+Library    UUID
+
+
+
+*** Variables ***
+${INDEX PATH}     /aai/v8 
+${ROOT_SERVICE_PATH}  /service-design-and-creation/services
+
+${SYSTEM USER}    robot-ete
+${AAI_ADD_SERVICE_BODY}=    robot/assets/templates/aai/add_service_body.template
+
+*** Keywords ***    
+Create Service If Not Exists
+    [Documentation]    Creates a service in A&AI if it doesn't exist   
+    [Arguments]    ${service_type}
+    ${dict}=    Get Services
+    ${status}    ${value}=    Run Keyword And Ignore Error    Dictionary Should Contain Key    ${dict}    ${service_type} 
+    Run Keyword If    '${status}' == 'FAIL'    Create Service    ${service_type}
+    
+Create Service
+    [Documentation]    Creates a service in A&AI       
+    [Arguments]    ${service_type}
+    ${uuid}=    Generate UUID 
+    ${data_template}=    OperatingSystem.Get File    ${AAI_ADD_SERVICE_BODY}  
+    ${arguments}=    Create Dictionary    service_type=${service_type}    UUID=${uuid}       
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}
+    ${fullpath}=    Catenate         ${INDEX PATH}${ROOT_SERVICE_PATH}/service/${uuid}
+       ${put_resp}=    Run A&AI Put Request     ${fullpath}    ${data}
+    Should Be Equal As Strings         ${put_resp.status_code}         201
+       [Return]  ${put_resp.status_code}
+
+    
+Delete Service If Exists
+    [Documentation]    Deletes a service in A&AI if it exists  
+    [Arguments]    ${service_type}
+    ${dict}=    Get Services
+    ${status}    ${value}=    Run Keyword And Ignore Error    Dictionary Should Contain Key    ${dict}    ${service_type} 
+    Run Keyword If    '${status}' == 'PASS'    Delete Service    ${dict['${service_type}']}
+
+Delete Service
+    [Documentation]    Delete  passed service in A&AI  
+    [Arguments]    ${dict}
+    ${uuid}=    Get From Dictionary    ${dict}     service-id 
+    ${resource_version}=    Get From Dictionary    ${dict}     resource-version
+    ${fullpath}=    Catenate         ${INDEX PATH}${ROOT_SERVICE_PATH}/service/${uuid}
+       ${resp}=    Run A&AI Delete Request    ${fullpath}    ${resource_version}    
+    Should Be Equal As Strings         ${resp.status_code}     204
+
+    
+Get Services
+    [Documentation]    Creates a service in A&AI       
+       ${resp}=    Run A&AI Get Request     ${INDEX PATH}${ROOT_SERVICE_PATH}
+       ${dict}=    Create Dictionary    
+    ${status}    ${value}=    Run Keyword And Ignore Error    Should Be Equal As Strings       ${resp.status_code}     200
+    Run Keyword If    '${status}' == 'PASS'    Update Service Dictionary    ${dict}    ${resp.json()}      
+       [Return]  ${dict}
+
+Update Service Dictionary
+    [Arguments]    ${dict}    ${json}
+    ${list}=    Evaluate    ${json}['service']
+    :for   ${map}    in    @{list}
+    \    ${status}    ${service_type}=     Run Keyword And Ignore Error    Get From Dictionary    ${map}    service-description
+    \    Run Keyword If    '${status}' == 'PASS'    Set To Dictionary    ${dict}    ${service_type}=${map}    
+    Log    ${dict}
+
+
diff --git a/robot/resources/aai/create_tenant.robot b/robot/resources/aai/create_tenant.robot
new file mode 100644 (file)
index 0000000..da21ac9
--- /dev/null
@@ -0,0 +1,79 @@
+*** Settings ***
+Documentation    Create A&AI Customer API.
+...
+...                  Create A&AI Customer API
+
+Resource    ../json_templater.robot
+Resource    aai_interface.robot
+Library    OperatingSystem
+Library    Collections
+
+
+
+*** Variables ***
+${INDEX PATH}     /aai/v8 
+${ROOT_TENANT_PATH}  /cloud-infrastructure/cloud-regions/cloud-region/
+
+${SYSTEM USER}    robot-ete
+${AAI_ADD_TENANT_BODY}=    robot/assets/templates/aai/add_tenant_body.template
+
+*** Keywords ***    
+Inventory Tenant If Not Exists
+    [Documentation]    Creates a service in A&AI if it doesn't exist   
+    [Arguments]    ${cloud_owner}  ${cloud_region_id}  ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}    ${tenant_id}    ${tenant_name}
+    ${dict}=    Get Tenants    ${cloud_owner}   ${cloud_region_id}
+    ${status}    ${value}=    Run Keyword And Ignore Error    Dictionary Should Contain Key    ${dict}    ${tenant_id} 
+    Run Keyword If    '${status}' == 'FAIL'    Inventory Tenant    ${cloud_owner}  ${cloud_region_id}  ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}    ${tenant_id}    ${tenant_name}
+        
+Inventory Tenant
+    [Documentation]    Inventorys a Tenant in A&AI     
+    [Arguments]    ${cloud_owner}  ${cloud_region_id}  ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}    ${tenant_id}    ${tenant_name}       
+    ${data_template}=    OperatingSystem.Get File    ${AAI_ADD_TENANT_BODY}
+    ${arguments}=    Create Dictionary     cloud_owner=${cloud_owner}  cloud_region_id=${cloud_region_id}  cloud_type=${cloud_type}    owner_defined_type=${owner_defined_type}    cloud_region_version=${cloud_region_version}    cloud_zone=${cloud_zone}    tenant_id=${tenant_id}    tenant_name=${tenant_name}       
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}        
+       ${put_resp}=    Run A&AI Put Request     ${INDEX PATH}${ROOT_TENANT_PATH}${cloud_owner}/${cloud_region_id}     ${data}
+    Should Be Equal As Strings         ${put_resp.status_code}         201   
+       [Return]  ${put_resp.status_code}
+
+Delete Tenant
+    [Documentation]    Removes both Tenant 
+    [Arguments]    ${tenant_id}    ${cloud_owner}    ${cloud_region_id}
+    ${get_resp}=    Run A&AI Get Request     ${INDEX PATH}${ROOT_TENANT_PATH}${cloud_owner}/${cloud_region_id}/tenants/tenant/${tenant_id}      
+    Run Keyword If    '${get_resp.status_code}' == '200'    Delete Tenant Exists    ${tenant_id}    ${cloud_owner}    ${cloud_region_id}    ${get_resp.json()['resource-version']}
+
+Delete Tenant Exists
+    [Arguments]    ${tenant_id}    ${cloud_owner}    ${cloud_region_id}    ${resource_version}
+    ${put_resp}=    Run A&AI Delete Request    ${INDEX PATH}${ROOT_TENANT_PATH}${cloud_owner}/${cloud_region_id}/tenants/tenant/${tenant_id}    ${resource_version} 
+    Should Be Equal As Strings         ${put_resp.status_code}         204   
+  
+Delete Cloud Region
+    [Documentation]    Removes both Tenant and Cloud Region in A&AI
+    [Arguments]    ${tenant_id}    ${cloud_owner}    ${cloud_region_id}
+    ${get_resp}=    Run A&AI Get Request     ${INDEX PATH}${ROOT_TENANT_PATH}${cloud_owner}/${cloud_region_id}    
+       Run Keyword If    '${get_resp.status_code}' == '200'    Delete Cloud Region Exists   ${tenant_id}    ${cloud_owner}    ${cloud_region_id}    ${get_resp.json()['resource-version']}
+       
+Delete Cloud Region Exists
+    [Arguments]    ${tenant_id}    ${cloud_owner}    ${cloud_region_id}    ${resource_version}
+    ${put_resp}=    Run A&AI Delete Request    ${INDEX PATH}${ROOT_TENANT_PATH}${cloud_owner}/${cloud_region_id}   ${resource_version}
+    Should Be Equal As Strings         ${put_resp.status_code}         204     
+    
+Get Tenants
+    [Documentation]   Return list of tenants for this cloud owner/region    
+    [Arguments]    ${cloud_owner}    ${cloud_region_id}        
+       ${resp}=    Run A&AI Get Request     ${INDEX PATH}${ROOT_TENANT_PATH}${cloud_owner}/${cloud_region_id}/tenants
+       ${dict}=    Create Dictionary    
+    ${status}    ${value}=    Run Keyword And Ignore Error    Should Be Equal As Strings       ${resp.status_code}     200
+    Run Keyword If    '${status}' == 'PASS'    Update Tenant Dictionary    ${dict}    ${resp.json()}      
+       [Return]  ${dict}
+
+Update Tenant Dictionary
+    [Arguments]    ${dict}    ${json}
+    ${list}=    Evaluate    ${json}['tenant']
+    :for   ${map}    in    @{list}
+    \    ${status}    ${tenant_id}=     Run Keyword And Ignore Error    Get From Dictionary    ${map}    tenant-id
+    \    Run Keyword If    '${status}' == 'PASS'    Set To Dictionary    ${dict}    ${tenant_id}=${map}    
+    Log    ${dict}
+    
+    
+
+    
\ No newline at end of file
diff --git a/robot/resources/aai/network.robot b/robot/resources/aai/network.robot
new file mode 100644 (file)
index 0000000..a42461e
--- /dev/null
@@ -0,0 +1,42 @@
+*** Settings ***
+Documentation    Validate A&AI Serivce Instance
+...
+...                  Validate A&AI Serivce Instance
+
+Resource          aai_interface.robot
+Library    Collections
+Library    OperatingSystem
+Library    RequestsLibrary
+Library    JSONUtils
+Library    HttpLibrary.HTTP
+
+Resource          ../json_templater.robot
+
+*** Variables ***
+${INDEX PATH}     /aai/v8
+${GENERIC_QUERY_PATH}  /search/generic-query?
+${SYSTEM USER}    robot-ete
+${CUSTOMER SPEC PATH}    /business/customers/customer/
+${SERVICE SUBSCRIPTIONS}    /service-subscriptions/service-subscription/
+${SERVICE INSTANCE}    /service-instances?service-instance-name=
+${SERVCE INSTANCE TEMPLATE}    robot/assets/templates/aai/service_subscription.template    
+
+*** Keywords ***    
+Validate Network
+    [Documentation]    Query and Validates A&AI Service Instance       
+    [Arguments]    ${service_instance_name}    ${service_type}  ${customer_id}   
+       ${resp}=    Run A&AI Get Request      ${INDEX PATH}${CUSTOMER SPEC PATH}${CUSTOMER ID}${SERVICE SUBSCRIPTIONS}${service_type}${SERVICE INSTANCE}${service_instance_name}
+    Dictionary Should Contain Value    ${resp.json()['service-instance'][0]}    ${service_instance_name}
+          
+       
+
+*** Keywords ***    
+Create Network
+    [Documentation]    Query and Validates A&AI Service Instance       
+    [Arguments]    ${CUSTOMER ID}    
+    ${json_string}=    Catenate     { "service-type": "VDNS" , "service-subscriptions":[{"service-instance-id":"instanceid123","service-instance-name":"VDNS"}]}
+       ${put_resp}=    Run A&AI Put Request     ${INDEX PATH}${CUSTOMER SPEC PATH}${CUSTOMER ID}${SERVICE SUBSCRIPTIONS}/VDNS    ${json_string}
+    Should Be Equal As Strings         ${put_resp.status_code}         201
+       [Return]  ${put_resp.status_code}       
+       
+       
\ No newline at end of file
diff --git a/robot/resources/aai/service_instance.robot b/robot/resources/aai/service_instance.robot
new file mode 100644 (file)
index 0000000..c9fdadd
--- /dev/null
@@ -0,0 +1,82 @@
+*** Settings ***
+Documentation    Validate A&AI Serivce Instance
+...
+...                  Validate A&AI Serivce Instance
+
+Resource          aai_interface.robot
+Library    Collections
+Library    OperatingSystem
+Library    RequestsLibrary
+Library    JSONUtils
+Library    HttpLibrary.HTTP
+Library    StringTemplater
+Resource          ../json_templater.robot
+Resource          ../stack_validation/validate_vlb.robot
+Resource          ../stack_validation/validate_vfw.robot
+Resource          ../stack_validation/validate_vvg.robot
+
+*** Variables ***
+${INDEX PATH}     /aai/v8
+${GENERIC_QUERY_PATH}  /search/generic-query?
+${SYSTEM USER}    robot-ete
+${CUSTOMER SPEC PATH}    /business/customers/customer/
+${SERVICE SUBSCRIPTIONS}    /service-subscriptions/service-subscription/
+${SERVICE INSTANCE}    /service-instances?service-instance-id=
+${SERVCE INSTANCE TEMPLATE}    robot/assets/templates/aai/service_subscription.template    
+
+${GENERIC_VNF_PATH_TEMPLATE}   /network/generic-vnfs/generic-vnf/\${vnf_id}/vf-modules/vf-module/\${vf_module_id}
+${VLB_CLOSED_LOOP_HACK_BODY}    robot/assets/templates/aai/vlb_closed_loop_hack.template
+
+*** Keywords ***    
+Validate Service Instance
+    [Documentation]    Query and Validates A&AI Service Instance       
+    [Arguments]    ${service_instance_name}    ${service_type}  ${customer_name}
+    ${cust_resp}=    Run A&AI Get Request      ${INDEX PATH}/business/customers?subscriber-name=${customer_name}  
+       ${resp}=    Run A&AI Get Request      ${INDEX PATH}${CUSTOMER SPEC PATH}${cust_resp.json()['customer'][0]['global-customer-id']}${SERVICE SUBSCRIPTIONS}${service_type}${SERVICE INSTANCE}${service_instance_name}
+    Dictionary Should Contain Value    ${resp.json()['service-instance'][0]}    ${service_instance_name}
+    Dictionary Should Contain Key      ${resp.json()['service-instance'][0]}    persona-model-id
+    Dictionary Should Contain Key      ${resp.json()['service-instance'][0]}    persona-model-version
+          
+Validate Generic VNF
+    [Documentation]    Query and Validates A&AI Service Instance       
+    [Arguments]    ${vnf_name}  ${vnf_type}    ${service_instance_id}    
+    ${generic_vnf}=    Run A&AI Get Request      ${INDEX PATH}/network/generic-vnfs/generic-vnf?vnf-name=${vnf_name}   
+    Dictionary Should Contain Value    ${generic_vnf.json()}    ${vnf_name}
+    ${returned_vnf_type}=    Get From Dictionary    ${generic_vnf.json()}    vnf-type
+    Should Contain     ${returned_vnf_type}    ${vnf_type}
+    [Return]    ${generic_vnf.json()}
+    
+VLB Closed Loop Hack
+    [Arguments]    ${service}    ${generic_vnf}   ${closedloop_vf_module}  
+    Return From Keyword If    '${service}' != 'vLB'
+    ${vnf_id}=     Get From Dictionary    ${generic_vnf}    vnf-id
+    ${vf_modules}=    Get From Dictionary    ${generic_vnf}    vf-modules
+    ${list}=    Get From Dictionary    ${vf_modules}   vf-module
+    ${vfmodule}=    Get From List    ${list}    0
+    ${persona_model_id}=    Get From Dictionary    ${closedloop_vf_module}    invariantUUID
+    ${persona_model_version}=   Get From Dictionary    ${closedloop_vf_module}    version
+    ${dict}=    Create Dictionary   vnf_id=${vnf_id}   vf_module_id=dummy   persona_model_id=${persona_model_id}   persona_model_version=${persona_model_version}    
+    ${datapath}=    Template String    ${GENERIC_VNF_PATH_TEMPLATE}    ${dict}
+    ${data}=   Fill JSON Template File    ${VLB_CLOSED_LOOP_HACK_BODY}    ${dict}    
+       ${put_resp}=    Run A&AI Put Request     ${INDEX PATH}${datapath}   ${data}
+    ${status_string}=    Convert To String    ${put_resp.status_code}
+    Should Match Regexp    ${status_string}    ^(201|412)$     
+               
+    
+Validate VF Module
+    [Documentation]    Query and Validates A&AI Service Instance       
+    [Arguments]    ${vf_module_name}    ${stack_type}
+       Run Keyword If    '${stack_type}'=='vLB'    Validate vLB Stack    ${vf_module_name}             
+       Run Keyword If    '${stack_type}'=='vFW'    Validate Firewall Stack    ${vf_module_name}        
+       Run Keyword If    '${stack_type}'=='vVG'    Validate vVG Stack    ${vf_module_name}             
+
+*** Keywords ***    
+Create AAI Service Instance
+    [Documentation]    Query and Validates A&AI Service Instance       
+    [Arguments]    ${customer_id}    ${service_type}    ${service_instance_id}    ${service_instance_name}    
+    ${json_string}=    Catenate     { "service-type": "VDNS" , "service-subscriptions":[{"service-instance-id":"instanceid123","service-instance-name":"VDNS"}]}
+       ${put_resp}=    Run A&AI Put Request     ${INDEX PATH}${CUSTOMER SPEC PATH}${CUSTOMER ID}${SERVICE SUBSCRIPTIONS}/{service_type}   ${json_string}
+    Should Be Equal As Strings         ${put_resp.status_code}         201
+       [Return]  ${put_resp.status_code}       
+       
+       
\ No newline at end of file
diff --git a/robot/resources/aai/volume_group.robot b/robot/resources/aai/volume_group.robot
new file mode 100644 (file)
index 0000000..9582201
--- /dev/null
@@ -0,0 +1,31 @@
+*** Settings ***
+Documentation    Validate A&AI Serivce Instance
+...
+...                  Validate A&AI Serivce Instance
+
+Resource          aai_interface.robot
+Library    Collections
+Library    OperatingSystem
+Library    RequestsLibrary
+Library    JSONUtils
+Library    HttpLibrary.HTTP
+
+Resource          ../json_templater.robot
+
+*** Variables ***
+${INDEX PATH}     /aai/v8
+${GENERIC_QUERY_PATH}  /search/generic-query?
+${SYSTEM USER}    robot-ete
+${CUSTOMER SPEC PATH}    /business/customers/customer/
+${SERVICE SUBSCRIPTIONS}    /service-subscriptions/service-subscription/
+${SERVICE INSTANCE}    /service-instances?service-instance-name=
+${SERVCE INSTANCE TEMPLATE}    robot/assets/templates/aai/service_subscription.template    
+
+*** Keywords ***    
+Validate Volume Group  
+    [Arguments]    ${service_instance_name}    ${service_type}  ${customer_id}   
+       ${resp}=    Run A&AI Get Request      ${INDEX PATH}${CUSTOMER SPEC PATH}${CUSTOMER ID}${SERVICE SUBSCRIPTIONS}${service_type}${SERVICE INSTANCE}${service_instance_name}
+    Dictionary Should Contain Value    ${resp.json()['service-instance'][0]}    ${service_instance_name}
+
+       
+       
\ No newline at end of file
diff --git a/robot/resources/appc_interface.robot b/robot/resources/appc_interface.robot
new file mode 100644 (file)
index 0000000..2dbd979
--- /dev/null
@@ -0,0 +1,54 @@
+*** Settings ***
+Documentation     The main interface for interacting with APP-C. It handles low level stuff like managing the http request library and APP-C required fields
+Library              RequestsLibrary
+Library                  UUID      
+Library           OperatingSystem
+Library           StringTemplater
+Resource          global_properties.robot
+
+*** Variables ***
+${APPC_INDEX_PATH}    /restconf
+${APPC_HEALTHCHECK_OPERATION_PATH}  /operations/SLI-API:healthcheck
+${APPC_CREATE_MOUNTPOINT_PATH}  /config/network-topology:network-topology/topology/topology-netconf/node/
+${APPC_MOUNT_XML}    robot/assets/templates/appc/vnf_mount.template
+
+*** Keywords ***
+Run APPC Health Check
+    [Documentation]    Runs an APPC healthcheck
+       ${resp}=    Run APPC Post Request     ${APPC_INDEX PATH}${APPC_HEALTHCHECK_OPERATION_PATH}     ${None}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    Should Be Equal As Strings         ${resp.json()['output']['response-code']}       200   
+
+Run APPC Post Request
+    [Documentation]    Runs an APPC post request
+    [Arguments]    ${data_path}    ${data}    ${content}=json
+    ${auth}=  Create List  ${GLOBAL_APPC_USERNAME}    ${GLOBAL_APPC_PASSWORD}
+    Log    Creating session ${GLOBAL_APPC_SERVER}
+    ${session}=    Create Session      appc    ${GLOBAL_APPC_SERVER}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/${content}    Content-Type=application/${content}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Post Request    appc    ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from appc ${resp.text}
+    [Return]    ${resp}
+
+Run APPC Put Request
+    [Documentation]    Runs an APPC post request
+    [Arguments]    ${data_path}    ${data}    ${content}=xml
+    ${auth}=  Create List  ${GLOBAL_APPC_USERNAME}    ${GLOBAL_APPC_PASSWORD}
+    Log    Creating session ${GLOBAL_APPC_SERVER}
+    ${session}=    Create Session      appc    ${GLOBAL_APPC_SERVER}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/${content}    Content-Type=application/${content}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Put Request     appc    ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from appc ${resp.text}
+    [Return]    ${resp}
+    
+Create Mount Point In APPC
+    [Documentation]     Go tell APPC about the PGN we just spun up...
+    [Arguments]    ${nodeid}    ${host}    ${port}=${GLOBAL_PGN_PORT}    ${username}=admin    ${password}=admin
+    ${dict}=    Create Dictionary    nodeid=${nodeid}    host=${host}    port=${port}    username=${username}    password=${password}
+    ${template}=    OperatingSystem.Get File    ${APPC_MOUNT_XML}
+    ${data}=    Template String    ${template}    ${dict}   
+    ${resp}=    Run APPC Put Request     ${APPC_INDEX PATH}${APPC_CREATE_MOUNTPOINT_PATH}${nodeid}     ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]     ${resp}    
\ No newline at end of file
diff --git a/robot/resources/asdc_interface.robot b/robot/resources/asdc_interface.robot
new file mode 100644 (file)
index 0000000..35fdecf
--- /dev/null
@@ -0,0 +1,462 @@
+*** Settings ***
+Documentation     The main interface for interacting with ASDC. It handles low level stuff like managing the http request library and DCAE required fields
+Library              RequestsLibrary
+Library                  UUID      
+Library                  JSONUtils      
+Library           OperatingSystem
+Library           Collections
+Library              ExtendedSelenium2Library
+Resource          global_properties.robot
+Resource          browser_setup.robot
+Resource          json_templater.robot
+*** Variables ***
+${ASDC_DESIGNER_USER_ID}    cs0008
+${ASDC_TESTER_USER_ID}    jm0007
+${ASDC_GOVERNOR_USER_ID}    gv0001
+${ASDC_OPS_USER_ID}    op0001
+${ASDC_HEALTH_CHECK_PATH}    /sdc1/rest/healthCheck
+${ASDC_VENDOR_LICENSE_MODEL_PATH}    /onboarding-api/v1.0/vendor-license-models
+${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}    /onboarding-api/v1.0/vendor-software-products
+${ASDC_VENDOR_KEY_GROUP_PATH}    /license-key-groups
+${ASDC_VENDOR_ENTITLEMENT_POOL_PATH}    /entitlement-pools
+${ASDC_VENDOR_FEATURE_GROUP_PATH}    /feature-groups
+${ASDC_VENDOR_LICENSE_AGREEMENT_PATH}    /license-agreements
+${ASDC_VENDOR_ACTIONS_PATH}    /actions
+${ASDC_VENDOR_SOFTWARE_UPLOAD_PATH}    /upload
+${ASDC_CATALOG_RESOURCES_PATH}    /sdc2/rest/v1/catalog/resources
+${ASDC_CATALOG_SERVICES_PATH}    /sdc2/rest/v1/catalog/services
+${ASDC_CATALOG_INACTIVE_RESOURCES_PATH}    /sdc2/rest/v1/inactiveComponents/resource
+${ASDC_CATALOG_INACTIVE_SERVICES_PATH}    /sdc2/rest/v1/inactiveComponents/service
+${ASDC_CATALOG_LIFECYCLE_PATH}    /lifecycleState
+${ASDC_CATALOG_SERVICE_RESOURCE_INSTANCE_PATH}    /resourceInstance
+${ASDC_CATALOG_SERVICE_DISTRIBUTION_STATE_PATH}    /distribution-state
+${ASDC_CATALOG_SERVICE_DISTRIBUTION_PATH}    /distribution
+${ASDC_DISTRIBUTION_STATE_APPROVE_PATH}    /approve
+${ASDC_CATALOG_SERVICE_DISTRIBUTION_ACTIVATE_PATH}    /distribution/PROD/activate
+${ASDC_LICENSE_MODEL_TEMPLATE}    robot/assets/templates/asdc/license_model.template
+${ASDC_KEY_GROUP_TEMPLATE}    robot/assets/templates/asdc/key_group.template
+${ASDC_ENTITLEMENT_POOL_TEMPLATE}    robot/assets/templates/asdc/entitlement_pool.template
+${ASDC_FEATURE_GROUP_TEMPLATE}    robot/assets/templates/asdc/feature_group.template
+${ASDC_LICENSE_AGREEMENT_TEMPLATE}    robot/assets/templates/asdc/license_agreement.template
+${ASDC_ACTION_TEMPLATE}    robot/assets/templates/asdc/action.template
+${ASDC_SOFTWARE_PRODUCT_TEMPLATE}    robot/assets/templates/asdc/software_product.template
+${ASDC_CATALOG_RESOURCE_TEMPLATE}    robot/assets/templates/asdc/catalog_resource.template
+${ASDC_USER_REMARKS_TEMPLATE}    robot/assets/templates/asdc/user_remarks.template
+${ASDC_CATALOG_SERVICE_TEMPLATE}    robot/assets/templates/asdc/catalog_service.template
+${ASDC_RESOURCE_INSTANCE_TEMPLATE}    robot/assets/templates/asdc/resource_instance.template
+*** Keywords ***
+Distribute Model From ASDC
+    [Documentation]    goes end to end creating all the asdc objects based ona  model and distributing it to the systems. it then returns the service name, vf name and vf module name
+    [Arguments]    ${model_zip_path}
+    ${catalog_service_id}=    Add ASDC Catalog Service
+    ${catalog_resource_ids}=    Create List
+    : FOR    ${zip}     IN     @{model_zip_path}
+    \    ${loop_catalog_resource_id}=    Setup ASDC Catalog Resource    ${zip}
+    \    Append To List    ${catalog_resource_ids}   ${loop_catalog_resource_id}     
+    \    ${loop_catalog_resource_resp}=    Get ASDC Catalog Resource    ${loop_catalog_resource_id}
+    \    Add ASDC Resource Instance    ${catalog_service_id}    ${loop_catalog_resource_id}    ${loop_catalog_resource_resp['name']}
+    ${catalog_service_resp}=    Get ASDC Catalog Service    ${catalog_service_id}
+    Checkin ASDC Catalog Service    ${catalog_service_id}
+    Request Certify ASDC Catalog Service    ${catalog_service_id}
+    Start Certify ASDC Catalog Service    ${catalog_service_id}
+    # on certify it gets a new id
+    ${catalog_service_id}=    Certify ASDC Catalog Service    ${catalog_service_id}
+    Approve ASDC Catalog Service    ${catalog_service_id}
+       Distribute ASDC Catalog Service    ${catalog_service_id}
+       ${catalog_service_resp}=    Get ASDC Catalog Service    ${catalog_service_id}
+       ${vf_module}=    Find Element In Array    ${loop_catalog_resource_resp['groups']}    type    org.openecomp.groups.VfModule
+    [Return]    ${catalog_service_resp['name']}    ${loop_catalog_resource_resp['name']}    ${vf_module}   ${catalog_resource_ids}    ${catalog_service_id}
+       Check Catalog Service Distributed    ${catalog_service_resp['uuid']}
+Setup ASDC Catalog Resource
+    [Documentation]    Creates all the steps a vf needs for an asdc catalog resource and returns the id
+    [Arguments]    ${model_zip_path}
+    ${license_model_id}=    Add ASDC License Model
+    ${key_group_id}=    Add ASDC License Group    ${license_model_id}
+    ${pool_id}=    Add ASDC Entitlement Pool    ${license_model_id}
+    ${feature_group_id}=    Add ASDC Feature Group    ${license_model_id}    ${key_group_id}    ${pool_id}
+    ${license_agreement_id}=    Add ASDC License Agreement    ${license_model_id}    ${feature_group_id}
+    Checkin ASDC License Model    ${license_model_id}
+    Submit ASDC License Model    ${license_model_id}
+    ${license_model_resp}=    Get ASDC License Model    ${license_model_id}  
+    ${software_product_id}=    Add ASDC Software Product    ${license_agreement_id}    ${feature_group_id}    ${license_model_resp['vendorName']}    ${license_model_id}
+    Upload ASDC Heat Package    ${software_product_id}    ${model_zip_path}
+    Checkin ASDC Software Product    ${software_product_id}
+    Submit ASDC Software Product    ${software_product_id}
+    Package ASDC Software Product    ${software_product_id}
+    ${software_product_resp}=    Get ASDC Software Product    ${software_product_id}  
+    ${catalog_resource_id}=    Add ASDC Catalog Resource     ${license_agreement_id}    ${software_product_resp['name']}    ${license_model_resp['vendorName']}    ${software_product_id}
+    Checkin ASDC Catalog Resource    ${catalog_resource_id}
+    Request Certify ASDC Catalog Resource    ${catalog_resource_id}
+    Start Certify ASDC Catalog Resource    ${catalog_resource_id}
+    # on certify it gets a new id
+    [Return]    ${catalog_resource_id}
+    ${catalog_resource_id}=    Certify ASDC Catalog Resource    ${catalog_resource_id}
+Add ASDC License Model
+    [Documentation]    Creates an asdc license model and returns its id
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    vendor_name=${shortened_uuid}
+    ${data}=   Fill JSON Template File    ${ASDC_LICENSE_MODEL_TEMPLATE}    ${map}
+    ${resp}=    Run ASDC Post Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}    ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['value']}
+Get ASDC License Model
+    [Documentation]    gets an asdc license model by its id
+    [Arguments]    ${id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${id}
+    [Return]    ${resp.json()}
+Checkin ASDC License Model
+    [Documentation]    checksin an asdc license model by its id
+    [Arguments]    ${id}
+    ${map}=    Create Dictionary    action=Checkin
+    ${data}=   Fill JSON Template File    ${ASDC_ACTION_TEMPLATE}    ${map}
+    ${resp}=    Run ASDC Put Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${id}${ASDC_VENDOR_ACTIONS_PATH}    ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Submit ASDC License Model
+    [Documentation]    submits an asdc license model by its id
+    [Arguments]    ${id}
+    ${map}=    Create Dictionary    action=Submit
+    ${data}=   Fill JSON Template File    ${ASDC_ACTION_TEMPLATE}    ${map}
+    ${resp}=    Run ASDC Put Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${id}${ASDC_VENDOR_ACTIONS_PATH}    ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Checkin ASDC Software Product
+    [Documentation]    checksin an asdc Software Product by its id
+    [Arguments]    ${id}
+    ${map}=    Create Dictionary    action=Checkin
+    ${data}=   Fill JSON Template File    ${ASDC_ACTION_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Put Request    ${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}/${id}${ASDC_VENDOR_ACTIONS_PATH}    ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Submit ASDC Software Product
+    [Documentation]    submits an asdc Software Product by its id
+    [Arguments]    ${id}
+    ${map}=    Create Dictionary    action=Submit
+    ${data}=   Fill JSON Template File    ${ASDC_ACTION_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Put Request    ${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}/${id}${ASDC_VENDOR_ACTIONS_PATH}    ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Package ASDC Software Product
+    [Documentation]    creates_package on an asdc Software Product by its id
+    [Arguments]    ${id}
+    ${map}=    Create Dictionary    action=Create_Package
+    ${data}=   Fill JSON Template File    ${ASDC_ACTION_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Put Request    ${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}/${id}${ASDC_VENDOR_ACTIONS_PATH}    ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}    
+Add ASDC Entitlement Pool
+    [Documentation]    Creates an asdc Entitlement Pool and returns its id
+    [Arguments]    ${license_model_id}
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    entitlement_pool_name=${shortened_uuid}
+    ${data}=   Fill JSON Template File    ${ASDC_ENTITLEMENT_POOL_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_ENTITLEMENT_POOL_PATH}     ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['value']}
+Get ASDC Entitlement Pool
+    [Documentation]    gets an asdc Entitlement Pool by its id
+    [Arguments]    ${license_model_id}    ${pool_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_ENTITLEMENT_POOL_PATH}/${pool_id}
+    [Return]    ${resp.json()}
+Add ASDC License Group
+    [Documentation]    Creates an asdc license group and returns its id
+    [Arguments]    ${license_model_id}
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    key_group_name=${shortened_uuid}
+    ${data}=   Fill JSON Template File    ${ASDC_KEY_GROUP_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_KEY_GROUP_PATH}     ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['value']}
+Get ASDC License Group
+    [Documentation]    gets an asdc license group by its id
+    [Arguments]    ${license_model_id}    ${group_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_KEY_GROUP_PATH}/${group_id}
+    [Return]    ${resp.json()}
+Add ASDC Feature Group
+    [Documentation]    Creates an asdc Feature Group and returns its id
+    [Arguments]    ${license_model_id}    ${key_group_id}    ${entitlement_pool_id}
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    feature_group_name=${shortened_uuid}    key_group_id=${key_group_id}    entitlement_pool_id=${entitlement_pool_id}
+    ${data}=   Fill JSON Template File    ${ASDC_FEATURE_GROUP_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_FEATURE_GROUP_PATH}     ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['value']}
+Get ASDC Feature Group
+    [Documentation]    gets an asdc Feature Group by its id
+    [Arguments]    ${license_model_id}    ${group_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_FEATURE_GROUP_PATH}/${group_id}
+    [Return]    ${resp.json()}
+Add ASDC License Agreement
+    [Documentation]    Creates an asdc License Agreement and returns its id
+    [Arguments]    ${license_model_id}    ${feature_group_id}
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    license_agreement_name=${shortened_uuid}    feature_group_id=${feature_group_id}
+    ${data}=   Fill JSON Template File    ${ASDC_LICENSE_AGREEMENT_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_LICENSE_AGREEMENT_PATH}     ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['value']}
+Get ASDC License Agreement
+    [Documentation]    gets an asdc License Agreement by its id
+    [Arguments]    ${license_model_id}    ${agreement_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_VENDOR_LICENSE_MODEL_PATH}/${license_model_id}${ASDC_VENDOR_LICENSE_AGREEMENT_PATH}/${agreement_id}
+    [Return]    ${resp.json()}
+Add ASDC Software Product
+    [Documentation]    Creates an asdc Software Product and returns its id
+    [Arguments]    ${license_agreement_id}    ${feature_group_id}    ${license_model_name}    ${license_model_id}
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    software_product_name=${shortened_uuid}    feature_group_id=${feature_group_id}    license_agreement_id=${license_agreement_id}    vendor_name=${license_model_name}    vendor_id=${license_model_id}
+    ${data}=   Fill JSON Template File    ${ASDC_SOFTWARE_PRODUCT_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}     ${data}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['vspId']}
+Get ASDC Software Product
+    [Documentation]    gets an asdc Software Product by its id
+    [Arguments]    ${software_product_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}/${software_product_id}
+    [Return]    ${resp.json()}
+Add ASDC Catalog Resource
+    [Documentation]    Creates an asdc Catalog Resource and returns its id
+    [Arguments]    ${license_agreement_id}    ${software_product_name}    ${license_model_name}    ${software_product_id}
+    ${map}=    Create Dictionary    software_product_id=${software_product_id}    software_product_name=${software_product_name}    license_agreement_id=${license_agreement_id}    vendor_name=${license_model_name}
+    ${data}=   Fill JSON Template File    ${ASDC_CATALOG_RESOURCE_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_RESOURCES_PATH}     ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     201
+    [Return]    ${resp.json()['uniqueId']}
+Mark ASDC Catalog Resource Inactive
+    [Documentation]    deletes an asdc Catalog Resource
+    [Arguments]    ${catalog_resource_id}
+    ${resp}=    Run ASDC Delete Request    ${ASDC_CATALOG_RESOURCES_PATH}/${catalog_resource_id}     ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     204
+    [Return]    ${resp}
+Delete Inactive ASDC Catalog Resources
+    [Documentation]    delete all asdc Catalog Resources that are inactive
+    ${resp}=    Run ASDC Delete Request    ${ASDC_CATALOG_INACTIVE_RESOURCES_PATH}     ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Get ASDC Catalog Resource
+    [Documentation]    gets an asdc Catalog Resource by its id
+    [Arguments]    ${catalog_resource_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_CATALOG_RESOURCES_PATH}/${catalog_resource_id}    ${ASDC_DESIGNER_USER_ID}
+    [Return]    ${resp.json()}
+Checkin ASDC Catalog Resource
+    [Documentation]    checksin an asdc Catalog Resource by its id
+    [Arguments]    ${catalog_resource_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_RESOURCES_PATH}/${catalog_resource_id}${ASDC_CATALOG_LIFECYCLE_PATH}/checkin    ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Request Certify ASDC Catalog Resource
+    [Documentation]    requests certify on an asdc Catalog Resource by its id
+    [Arguments]    ${catalog_resource_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_RESOURCES_PATH}/${catalog_resource_id}${ASDC_CATALOG_LIFECYCLE_PATH}/certificationRequest    ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Start Certify ASDC Catalog Resource
+    [Documentation]    start certify an asdc Catalog Resource by its id
+    [Arguments]    ${catalog_resource_id}
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_RESOURCES_PATH}/${catalog_resource_id}${ASDC_CATALOG_LIFECYCLE_PATH}/startCertification    ${None}    ${ASDC_TESTER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Certify ASDC Catalog Resource
+    [Documentation]    start certify an asdc Catalog Resource by its id and returns the new id
+    [Arguments]    ${catalog_resource_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_RESOURCES_PATH}/${catalog_resource_id}${ASDC_CATALOG_LIFECYCLE_PATH}/certify    ${data}    ${ASDC_TESTER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['uniqueId']}
+Upload ASDC Heat Package
+    [Documentation]    Creates an asdc Software Product and returns its id
+    [Arguments]    ${software_product_id}    ${file_path}
+    ${file}=    Get Binary File     ${file_path}
+    ${files}=     Create Dictionary     upload=${file}
+    ${resp}=    Run ASDC Post Files Request    ${ASDC_VENDOR_SOFTWARE_PRODUCT_PATH}/${software_product_id}${ASDC_VENDOR_SOFTWARE_UPLOAD_PATH}     ${files}    ${ASDC_DESIGNER_USER_ID}
+       Should Be Equal As Strings      ${resp.status_code}     200    
+Add ASDC Catalog Service
+    [Documentation]    Creates an asdc Catalog Service and returns its id
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:23]    
+    ${map}=    Create Dictionary    service_name=${shortened_uuid}
+    ${data}=   Fill JSON Template File    ${ASDC_CATALOG_SERVICE_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}     ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     201
+    [Return]    ${resp.json()['uniqueId']}
+Mark ASDC Catalog Service Inactive
+    [Documentation]    Deletes an asdc Catalog Service
+    [Arguments]    ${catalog_service_id}
+    ${resp}=    Run ASDC Delete Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}     ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     204
+    [Return]    ${resp}
+Delete Inactive ASDC Catalog Services
+    [Documentation]    delete all asdc Catalog Serivces that are inactive
+    ${resp}=    Run ASDC Delete Request    ${ASDC_CATALOG_INACTIVE_SERVICES_PATH}     ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Get ASDC Catalog Service
+    [Documentation]    gets an asdc Catalog Service by its id
+    [Arguments]    ${catalog_service_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}    ${ASDC_DESIGNER_USER_ID}
+    [Return]    ${resp.json()}
+Checkin ASDC Catalog Service
+    [Documentation]    checksin an asdc Catalog Service by its id
+    [Arguments]    ${catalog_service_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_LIFECYCLE_PATH}/checkin    ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Request Certify ASDC Catalog Service
+    [Documentation]    requests certify on an asdc Catalog Service by its id
+    [Arguments]    ${catalog_service_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_LIFECYCLE_PATH}/certificationRequest    ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Start Certify ASDC Catalog Service
+    [Documentation]    start certify an asdc Catalog Service by its id
+    [Arguments]    ${catalog_service_id}
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_LIFECYCLE_PATH}/startCertification    ${None}    ${ASDC_TESTER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Certify ASDC Catalog Service
+    [Documentation]    start certify an asdc Catalog Service by its id and returns the new id
+    [Arguments]    ${catalog_service_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_LIFECYCLE_PATH}/certify    ${data}    ${ASDC_TESTER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()['uniqueId']}
+Approve ASDC Catalog Service
+    [Documentation]    approve an asdc Catalog Service by its id
+    [Arguments]    ${catalog_service_id}
+    ${map}=    Create Dictionary    user_remarks=Robot remarks
+    ${data}=   Fill JSON Template File    ${ASDC_USER_REMARKS_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_SERVICE_DISTRIBUTION_STATE_PATH}${ASDC_DISTRIBUTION_STATE_APPROVE_PATH}    ${data}    ${ASDC_GOVERNOR_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Distribute ASDC Catalog Service
+    [Documentation]    distribute an asdc Catalog Service by its id
+    [Arguments]    ${catalog_service_id}
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_SERVICE_DISTRIBUTION_ACTIVATE_PATH}    ${None}    ${ASDC_OPS_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Add ASDC Resource Instance
+    [Documentation]    Creates an asdc Resource Instance and returns its id
+    [Arguments]    ${catalog_service_id}    ${catalog_resource_id}    ${catalog_resource_name}
+    ${milli_timestamp}=    Generate MilliTimestamp UUID
+    ${map}=    Create Dictionary    catalog_resource_id=${catalog_resource_id}    catalog_resource_name=${catalog_resource_name}    milli_timestamp=${milli_timestamp}
+    ${data}=   Fill JSON Template File    ${ASDC_RESOURCE_INSTANCE_TEMPLATE}    ${map} 
+    ${resp}=    Run ASDC Post Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_id}${ASDC_CATALOG_SERVICE_RESOURCE_INSTANCE_PATH}     ${data}    ${ASDC_DESIGNER_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     201
+    [Return]    ${resp.json()['uniqueId']}
+Get Catalog Service Distribution
+    [Documentation]    gets an asdc catalog Service distrbution
+    [Arguments]    ${catalog_service_uuid}
+    ${resp}=    Run ASDC Get Request    ${ASDC_CATALOG_SERVICES_PATH}/${catalog_service_uuid}${ASDC_CATALOG_SERVICE_DISTRIBUTION_PATH}    ${ASDC_OPS_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Check Catalog Service Distributed
+    [Documentation]    gets an asdc catalog Service distrbution
+    [Arguments]    ${catalog_service_uuid}
+    ${dist_resp}=    Get Catalog Service Distribution    ${catalog_service_uuid}
+    Should Be Equal As Strings         ${dist_resp['distributionStatusOfServiceList'][0]['deployementStatus']}         Distributed
+    ${det_resp}=    Get Catalog Service Distribution Details    ${dist_resp['distributionStatusOfServiceList'][0]['distributionID']}
+    @{ITEMS}=    Copy List    ${det_resp['distributionStatusList']}
+    :FOR    ${ELEMENT}    IN    @{ITEMS}
+    \    Log    ${ELEMENT['status']}
+    \    Should Match Regexp    ${ELEMENT['status']}    ^(DEPLOY_OK|NOTIFIED|DOWNLOAD_OK|NOT_NOTIFIED)$     
+Get Catalog Service Distribution Details
+    [Documentation]    gets an asdc catalog Service distrbution details
+    [Arguments]    ${catalog_service_distribution_id}
+    ${resp}=    Run ASDC Get Request    ${ASDC_CATALOG_SERVICES_PATH}${ASDC_CATALOG_SERVICE_DISTRIBUTION_PATH}/${catalog_service_distribution_id}    ${ASDC_OPS_USER_ID}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    [Return]    ${resp.json()}
+Run ASDC Health Check
+    [Documentation]    Runs a ASDC health check
+    ${session}=    Create Session      asdc    ${GLOBAL_ASDC_SERVER}:${GLOBAL_ASDC_FE_PORT}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     asdc    ${ASDC_HEALTH_CHECK_PATH}     headers=${headers}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    @{ITEMS}=    Copy List    ${resp.json()['componentsInfo']}
+    :FOR    ${ELEMENT}    IN    @{ITEMS}
+    \    Log    ${ELEMENT['healthCheckStatus']}
+    \    Should Be Equal As Strings    ${ELEMENT['healthCheckStatus']}         UP
+Run ASDC Get Request
+    [Documentation]    Runs an ASDC get request
+    [Arguments]    ${data_path}    ${user}=${ASDC_DESIGNER_USER_ID}
+    ${auth}=  Create List  ${GLOBAL_ASDC_BE_USERNAME}    ${GLOBAL_ASDC_BE_PASSWORD}
+    Log    Creating session ${GLOBAL_ASDC_SERVER}
+    ${session}=    Create Session      asdc    ${GLOBAL_ASDC_SERVER}:${GLOBAL_ASDC_BE_PORT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    USER_ID=${user}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     asdc    ${data_path}     headers=${headers}
+    Log    Received response from asdc ${resp.text}
+    [Return]    ${resp}
+Run ASDC Put Request
+    [Documentation]    Runs an ASDC put request
+    [Arguments]    ${data_path}    ${data}    ${user}=${ASDC_DESIGNER_USER_ID}
+    ${auth}=  Create List  ${GLOBAL_ASDC_BE_USERNAME}    ${GLOBAL_ASDC_BE_PASSWORD}
+    Log    Creating session ${GLOBAL_ASDC_SERVER}
+    ${session}=    Create Session      asdc    ${GLOBAL_ASDC_SERVER}:${GLOBAL_ASDC_BE_PORT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    USER_ID=${user}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Put Request     asdc    ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from asdc ${resp.text}
+    [Return]    ${resp}
+Run ASDC Post Files Request
+    [Documentation]    Runs an ASDC post request
+    [Arguments]    ${data_path}    ${files}    ${user}=${ASDC_DESIGNER_USER_ID}
+    ${auth}=  Create List  ${GLOBAL_ASDC_BE_USERNAME}    ${GLOBAL_ASDC_BE_PASSWORD}
+    Log    Creating session ${GLOBAL_ASDC_SERVER}
+    ${session}=    Create Session      asdc    ${GLOBAL_ASDC_SERVER}:${GLOBAL_ASDC_BE_PORT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=multipart/form-data    USER_ID=${user}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Post Request    asdc    ${data_path}     files=${files}    headers=${headers}
+    Log    Received response from asdc ${resp.text}
+    [Return]    ${resp} 
+Run ASDC Post Request
+    [Documentation]    Runs an ASDC post request
+    [Arguments]    ${data_path}    ${data}    ${user}=${ASDC_DESIGNER_USER_ID}
+    ${auth}=  Create List  ${GLOBAL_ASDC_BE_USERNAME}    ${GLOBAL_ASDC_BE_PASSWORD}
+    Log    Creating session ${GLOBAL_ASDC_SERVER}
+    ${session}=    Create Session      asdc    ${GLOBAL_ASDC_SERVER}:${GLOBAL_ASDC_BE_PORT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    USER_ID=${user}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Post Request    asdc    ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from asdc ${resp.text}
+    [Return]    ${resp} 
+Run ASDC Delete Request
+    [Documentation]    Runs an ASDC delete request
+    [Arguments]    ${data_path}    ${user}=${ASDC_DESIGNER_USER_ID}
+    ${auth}=  Create List  ${GLOBAL_ASDC_BE_USERNAME}    ${GLOBAL_ASDC_BE_PASSWORD}
+    Log    Creating session ${GLOBAL_ASDC_SERVER}
+    ${session}=    Create Session      asdc    ${GLOBAL_ASDC_SERVER}:${GLOBAL_ASDC_BE_PORT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    USER_ID=${user}    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Delete Request  asdc    ${data_path}        headers=${headers}
+    Log    Received response from asdc ${resp.text}
+    [Return]    ${resp}   
+Open ASDC GUI
+    [Documentation]   Logs in to ASDC GUI
+    [Arguments]    ${PATH}
+    ## Setup Browever now being managed by the test case
+    ##Setup Browser
+    Go To    ${GLOBAL_ASDC_SERVER}${PATH}
+    Maximize Browser Window
+    Set Selenium Speed    ${GLOBAL_SELENIUM_DELAY}
+    Set Browser Implicit Wait    ${GLOBAL_SELENIUM_BROWSER_IMPLICIT_WAIT}
+    Log    Logging in to ${GLOBAL_ASDC_SERVER}${PATH}
+    Title Should Be    ASDC
+    Wait Until Page Contains Element    xpath=//div/a[text()='SDC']    ${GLOBAL_SELENIUM_BROWSER_WAIT_TIMEOUT}    
+    Log    Logged in to ${GLOBAL_PORTAL_SERVER}${PATH}
diff --git a/robot/resources/browser_setup.robot b/robot/resources/browser_setup.robot
new file mode 100644 (file)
index 0000000..6ef4f72
--- /dev/null
@@ -0,0 +1,43 @@
+*** Settings ***
+Documentation     The main interface for interacting with VID. It handles low level stuff like managing the selenium request library and VID required steps
+Library           Collections
+Library           OSUtils
+Library           OperatingSystem
+Library           ExtendedSelenium2Library
+Resource          global_properties.robot
+
+*** Variables ***
+
+*** Keywords ***
+Setup Browser
+    [Documentation]   Sets up browser based upon the value of ${GLOBAL_SELENIUM_BROWSER}
+    Run Keyword If    '${GLOBAL_SELENIUM_BROWSER}' == 'firefox'    Setup Browser Firefox
+    Run Keyword If    '${GLOBAL_SELENIUM_BROWSER}' == 'chrome'    Setup Browser Chrome
+    Log    Running with ${GLOBAL_SELENIUM_BROWSER}
+    
+Setup Browser Firefox
+    ${dc}   Evaluate    sys.modules['selenium.webdriver'].DesiredCapabilities.FIREFOX  sys, selenium.webdriver
+    Set To Dictionary   ${dc}   elementScrollBehavior    1 
+    Create Webdriver    Firefox    desired_capabilities=${dc}
+    Set Global Variable    ${GLOBAL_SELENIUM_BROWSER_CAPABILITIES}    ${dc}
+           
+ Setup Browser Chrome
+    ${os}=   Get Normalized Os 
+    Log    Normalized OS=${os}
+    ${chrome options}=    Evaluate    sys.modules['selenium.webdriver'].ChromeOptions()    sys
+    Call Method    ${chrome options}    add_argument    no-sandbox
+    ${dc}   Evaluate    sys.modules['selenium.webdriver'].DesiredCapabilities.CHROME  sys, selenium.webdriver
+    Set To Dictionary   ${dc}   elementScrollBehavior    1
+    Create Webdriver    Chrome   chrome_options=${chrome_options}    desired_capabilities=${dc}  
+    Set Global Variable    ${GLOBAL_SELENIUM_BROWSER_CAPABILITIES}    ${dc}       
+
+Handle Proxy Warning    
+    [Documentation]    Handle Intermediate Warnings from Proxies
+    ${status}    ${data}=    Run Keyword And Ignore Error   Variable Should Exist    \${GLOBAL_PROXY_WARNING_TITLE}           
+    Return From Keyword if    '${status}' != 'PASS'
+    ${status}    ${data}=    Run Keyword And Ignore Error   Variable Should Exist    \${GLOBAL_PROXY_WARNING_CONTINUE_XPATH}          
+    Return From Keyword if    '${status}' != 'PASS'
+    Return From Keyword if    "${GLOBAL_PROXY_WARNING_TITLE}" == ''
+    Return From Keyword if    "${GLOBAL_PROXY_WARNING_CONTINUE_XPATH}" == ''
+    ${test}    ${value}=    Run keyword and ignore error    Title Should Be     ${GLOBAL_PROXY_WARNING_TITLE}
+    Run keyword If    '${test}' == 'PASS'    Click Element    xpath=${GLOBAL_PROXY_WARNING_CONTINUE_XPATH}
\ No newline at end of file
diff --git a/robot/resources/dcae_interface.robot b/robot/resources/dcae_interface.robot
new file mode 100644 (file)
index 0000000..1c1ba44
--- /dev/null
@@ -0,0 +1,57 @@
+*** Settings ***
+Documentation     The main interface for interacting with DCAE. It handles low level stuff like managing the http request library and DCAE required fields
+Library              RequestsLibrary
+Library                  UUID      
+Library           OperatingSystem
+Library           Collections
+Resource          global_properties.robot
+
+*** Variables ***
+${DCAE_HEALTH_CHECK_BODY}    robot/assets/dcae/dcae_healthcheck.json
+${DCAE_HEALTH_CHECK_PATH}    /gui
+
+*** Keywords ***
+Run DCAE Health Check
+    [Documentation]    Runs a DCAE health check
+    ${auth}=  Create List  ${GLOBAL_DCAE_USERNAME}    ${GLOBAL_DCAE_PASSWORD}
+    Log    Creating session ${GLOBAL_DCAE_SERVER}
+    ${session}=    Create Session      dcae    ${GLOBAL_DCAE_SERVER}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${data}=    OperatingSystem.Get File    ${DCAE_HEALTH_CHECK_BODY}
+    ${headers}=  Create Dictionary     action=getTable    Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Put Request     dcae    ${DCAE_HEALTH_CHECK_PATH}     data=${data}    headers=${headers}
+    Log    Received response from dcae ${resp.json()}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    Check DCAE Results    ${resp.json()}
+    
+Check DCAE Results
+    [Documentation]    Parse DCAE JSON response and make sure all rows have healthTestStatus=GREEN
+    [Arguments]    ${json}
+    @{rows}=    Get From Dictionary    ${json['returns']}    rows
+    @{headers}=    Get From Dictionary    ${json['returns']}    columns
+    
+    # Retrieve column names from headers
+    ${columns}=    Create List
+    :for    ${header}    in    @{headers}
+    \    ${colName}=    Get From Dictionary    ${header}    colName 
+    \    Append To List    ${columns}    ${colName}
+    
+    # Process each row making sure status=GREEN          
+    :for    ${row}    in    @{rows}
+    \    ${cells}=    Get From Dictionary    ${row}    cells
+    \    ${dict}=    Make A Dictionary    ${cells}    ${columns} 
+    \    Dictionary Should Contain Item    ${dict}    healthTestStatus    GREEN
+
+        
+Make A Dictionary
+    [Documentation]    Given a list of column names and a list of dictionaries, map columname=value
+    [Arguments]     ${columns}    ${names}    ${valuename}=value
+    ${dict}=    Create Dictionary
+    ${collength}=    Get Length    ${columns} 
+    ${namelength}=    Get Length    ${names} 
+    :for    ${index}    in range    0   ${collength}
+    \    ${name}=    Evaluate     ${names}[${index}]
+    \    ${valued}=    Evaluate     ${columns}[${index}]
+    \    ${value}=    Get From Dictionary    ${valued}    ${valueName}
+    \    Set To Dictionary    ${dict}   ${name}    ${value}     
+    [Return]     ${dict}            
\ No newline at end of file
diff --git a/robot/resources/global_properties.robot b/robot/resources/global_properties.robot
new file mode 100644 (file)
index 0000000..819f56a
--- /dev/null
@@ -0,0 +1,22 @@
+*** Settings ***
+Documentation        store all properties that can change or are used in multiple places here
+...                    format is all caps with underscores between words and prepended with GLOBAL
+...                   make sure you prepend them with GLOBAL so that other files can easily see it is from this file.
+
+
+*** Variables ***
+${GLOBAL_APPLICATION_ID}           robot-ete
+${GLOBAL_MSO_STATUS_PATH}    /ecomp/mso/infra/orchestrationRequests/v2/
+${GLOBAL_SELENIUM_BROWSER}        chrome
+${GLOBAL_SELENIUM_BROWSER_CAPABILITIES}        Create Dictionary
+${GLOBAL_SELENIUM_DELAY}          0
+${GLOBAL_SELENIUM_BROWSER_IMPLICIT_WAIT}        5
+${GLOBAL_SELENIUM_BROWSER_WAIT_TIMEOUT}        15
+${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    orchestration
+${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE}    volume
+${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    compute
+${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    network
+${GLOBAL_OPENSTACK_GLANCE_SERVICE_TYPE}    image
+${GLOBAL_OPENSTACK_KEYSTONE_SERVICE_TYPE}    identity
+${GLOBAL_AAI_CLOUD_OWNER}    Rackspace
+${GLOBAL_BUILD_NUMBER}    0
\ No newline at end of file
diff --git a/robot/resources/heatbridge.robot b/robot/resources/heatbridge.robot
new file mode 100644 (file)
index 0000000..eb6a9ed
--- /dev/null
@@ -0,0 +1,148 @@
+*** Settings ***
+Library     HeatBridge
+Library     Collections
+Library     StringTemplater
+Library     OperatingSystem
+Library     UUID
+
+Resource    openstack/keystone_interface.robot
+Resource    openstack/heat_interface.robot
+Resource    openstack/nova_interface.robot
+Resource    aai/aai_interface.robot
+
+*** Variables ***
+${VERSIONED_INDEX_PATH}     /aai/v8
+${MULTIPART_PATH}  /bulkadd
+${NAMED_QUERY_PATH}  /aai/search/named-query
+${NAMED_QUERY_TEMPLATE}    robot/assets/templates/aai/named_query.template    
+${REVERSE_HEATBRIDGE}
+
+
+*** Keywords ***
+Execute Heatbridge
+    [Documentation]   Run the Heatbridge against the stack to generate the bulkadd message
+    ...    Execute the build add
+    ...    Validate the add results by running the named query 
+    [Arguments]    ${stack_name}    ${service_instance_id}    ${service} 
+    Return From Keyword If    '${service}' == 'vVG'   
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${tenant_id}=   Get From Dictionary    ${stack_info}    OS::project_id
+    ${vnf_id}=    Get From Dictionary    ${stack_info}    vnf_id
+    ${openstack_identity_url}=    Catenate    ${GLOBAL_OPENSTACK_KEYSTONE_SERVER}/v2.0   
+    Init Bridge    ${openstack_identity_url}    ${GLOBAL_VM_PROPERTIES['openstack_username']}    ${GLOBAL_VM_PROPERTIES['openstack_password']}    ${tenant_id}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${GLOBAL_AAI_CLOUD_OWNER}    
+    ${request}=    Bridge Data    ${stack_id}
+    Log    ${request}
+    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${MULTIPART_PATH}    ${request}
+    Should Be Equal As Strings    ${resp.status_code}     200
+    Generate Reverse Heatbridge   ${request}
+    Run Validation Query    ${stack_info}    ${service}
+
+Run Validation Query
+    [Documentation]    Run A&AI query to validate the bulk add 
+    [Arguments]    ${stack_info}    ${service}
+    Return from Keyword If    '${service}' == ''    
+    ${server_name_parameter}=    Get From Dictionary    ${GLOBAL_VALIDATE_NAME_MAPPING}    ${service}
+    ${vserver_name}=    Get From Dictionary    ${stack_info}   ${server_name_parameter}
+    Run Vserver Query   ${vserver_name}     
+
+Run Vserver Query
+    [Documentation]    Run A&AI query to validate the bulk add 
+    [Arguments]    ${vserver_name}
+    ${dict}=    Create Dictionary    vserver_name=${vserver_name}
+    ${request}=    OperatingSystem.Get File    ${NAMED_QUERY_TEMPLATE}
+    ${request}=    Template String    ${request}    ${dict}    
+    ${resp}=    Run A&AI Post Request    ${NAMED_QUERY_PATH}    ${request}
+    Should Be Equal As Strings    ${resp.status_code}    200   
+    
+Generate Reverse Heatbridge
+    [Documentation]    Turn all of the HB puts into deletes... 
+    [Arguments]    ${heatbridge_string}
+    ${heatbridge}=  To Json    ${heatbridge_string}
+    ${list}=    Get From Dictionary   ${heatbridge}   transactions
+    ${transactions}=    Create List
+    ${dupeDict}   Create Dictionary    
+    :for   ${t}   in   @{list}
+    \   ${entry}=    Get Deletes From Heatbridge   ${t}   ${dupeDict}
+    \   Run Keyword If   len(${entry}) > 0    Append To List    ${transactions}   ${entry}    
+    ${reverse}=    Create Dictionary    transactions=${transactions}
+    Set Test Variable   ${REVERSE_HEATBRIDGE}   ${reverse}
+    [Return]      ${REVERSE_HEATBRIDGE} 
+
+Get Deletes From Heatbridge
+    [Documentation]    Turn all of the HB puts into deletes... Should be one 'put' with one 
+    ...   Not sure why this is structured this way, dictionary with operation as the key
+    ...   So only one occurrance of an each operation, but with list of urls/bodies
+    ...   So multiple gets, puts, etc. but in which order??? 
+    [Arguments]    ${putDict}   ${dupeDict}
+    ${deleteDict}=    Create Dictionary
+    ${keys}=   Get Dictionary Keys    ${putDict} 
+    # We do not expect anyhting other than 'put'
+    :for   ${key}   in    @{keys}
+    \    Should be Equal   ${key}   put  
+    \    ${list}=   Get From Dictionary   ${putDict}   put
+    \    ${deleteList}=   Get List Of Deletes   ${list}   ${dupeDict}
+    \    Run Keyword If   len(${deleteList}) > 0   Set To Dictionary    ${deleteDict}   delete=${deleteList}
+    [Return]    ${deleteDict}           
+
+Get List Of Deletes
+    [Documentation]    Turn the list of puts into a list of deletes... 
+    ...   There is only on hash per 'put' but it looks like there can be more...
+    [Arguments]    ${putList}    ${dupeDict}
+    ${deleteList}=   Create List
+    :for   ${put}   in    @{putList}     
+    \   ${uri}=   Get From Dictionary   ${put}   uri
+    \   Continue For Loop If    '${uri}' in ${dupeDict}
+    \   ${delete}=    Create Dictionary   uri=${uri}
+    \   Append To List     ${deleteList}   ${delete}
+    \   Set To Dictionary   ${dupeDict}   ${uri}=${uri} 
+    [Return]   ${deleteList}  
+         
+Execute Bulk Transaction    
+    [Arguments]    ${transaction}
+    :for   ${put}    in    ${transaction}
+    \    Execute Put List    ${put}
+
+Execute Put List 
+    [Arguments]    ${put}
+    Log    ${put}
+    ${list}=   Get From Dictionary    ${put}    put 
+    :for   ${request}    in    @{list}
+    \    Execute Single Put    ${request}
+        
+Execute Single Put 
+    [Arguments]    ${request}
+    ${data}=    Get From Dictionary    ${request}    body
+    ${path}=    Get From Dictionary    ${request}    uri
+    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${path}    ${data}
+    Should Be Equal As Strings        ${resp.status_code}      201
+    
+
+Execute Reverse Heatbridge
+    [Documentation]   VID has already torn down the stack, reverse HB 
+    [Arguments]    ${reverse_heatbridge}
+    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${MULTIPART_PATH}    ${reverse_heatbridge}
+    Should Be Equal As Strings    ${resp.status_code}     200
+    
+
+Execute Heatbridge Teardown
+    [Documentation]   Run teardown against the stack to generate a bulkadd message that removes it
+    [Arguments]    ${stack_name}
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${tenant_id}=   Get From Dictionary    ${stack_info}    OS::project_id
+    ${stack_resources}=    Get Stack Resources    auth    ${stack_name}    ${stack_id}
+    ${resource_list}=    Get From Dictionary    ${stack_resources}    resources
+    Get Length    ${resource_list}
+    Log     ${resource_list}
+    :FOR   ${resource}    in    @{resource_list}
+    \    Log     ${resource}
+    \    Run Keyword If    '${resource['resource_type']}' == 'OS::Nova::Server'    Execute Server Teardown    auth    ${resource['physical_resource_id']}
+
+Execute Server Teardown
+    [Documentation]   Run teardown against the server to generate a message that removes it
+    [Arguments]    ${alias}    ${server_id}
+    ${server}=    Get Openstack Server By Id   ${alias}        ${server_id}
+    Log     ${server}
\ No newline at end of file
diff --git a/robot/resources/json_templater.robot b/robot/resources/json_templater.robot
new file mode 100644 (file)
index 0000000..6a5ca17
--- /dev/null
@@ -0,0 +1,21 @@
+*** Settings ***
+Documentation     This resource is filling out json string templates and returning the json back
+Library              RequestsLibrary
+Library           StringTemplater
+Library           OperatingSystem
+Resource          global_properties.robot
+
+*** Keywords ***
+Fill JSON Template
+    [Documentation]    Runs substitution on template to return a filled in json
+    [Arguments]    ${json}    ${arguments}
+    ${returned_string}=    Template String    ${json}    ${arguments}
+    ${returned_json}=  To Json    ${returned_string}
+    [Return]    ${returned_json}
+
+Fill JSON Template File
+    [Documentation]    Runs substitution on template to return a filled in json
+    [Arguments]    ${json_file}    ${arguments}
+    ${json}=    OperatingSystem.Get File    ${json_file}
+    ${returned_json}=  Fill JSON Template    ${json}    ${arguments}
+    [Return]    ${returned_json}
\ No newline at end of file
diff --git a/robot/resources/mr_interface.robot b/robot/resources/mr_interface.robot
new file mode 100644 (file)
index 0000000..11c9348
--- /dev/null
@@ -0,0 +1,28 @@
+*** Settings ***
+Documentation    The main interface for interacting with Message router. It handles low level stuff like managing the http request library and message router required fields
+Library                  RequestsClientCert
+Library              RequestsLibrary
+Library                  UUID      
+
+Resource          global_properties.robot
+
+*** Variables ***
+${MR_HEALTH_CHECK_PATH}        /topics
+
+*** Keywords ***
+Run MR Health Check
+     [Documentation]    Runs MR Health check
+     ${resp}=    Run MR Get Request    ${MR_HEALTH_CHECK_PATH}    
+     Should Be Equal As Strings        ${resp.status_code}     200
+     Should Contain    ${resp.json()}    topics
+         
+Run MR Get Request
+     [Documentation]    Runs MR Get request
+     [Arguments]    ${data_path}
+     ${session}=    Create Session     mr      ${GLOBAL_MR_SERVER}
+     ${uuid}=    Generate UUID
+     ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+     ${resp}=  Get Request     mr      ${data_path}     headers=${headers}
+     Log    Received response from message router ${resp.text}
+     [Return]    ${resp}
+
diff --git a/robot/resources/mso_interface.robot b/robot/resources/mso_interface.robot
new file mode 100644 (file)
index 0000000..b6a53b4
--- /dev/null
@@ -0,0 +1,54 @@
+*** Settings ***
+Documentation     The main interface for interacting with MSO. It handles low level stuff like managing the http request library and MSO required fields
+Library              RequestsLibrary
+Library                  UUID      
+Library           OperatingSystem
+Library           Collections
+Resource          global_properties.robot
+Resource          ../resources/json_templater.robot
+*** Variables ***
+${MSO_HEALTH_CHECK_PATH}    /ecomp/mso/infra/globalhealthcheck
+
+*** Keywords ***
+Run MSO Health Check
+    [Documentation]    Runs an MSO global health check
+    ${auth}=  Create List  ${GLOBAL_MSO_USERNAME}    ${GLOBAL_MSO_PASSWORD}
+    ${session}=    Create Session      mso     ${GLOBAL_MSO_SERVER}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=text/html    Content-Type=text/html    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     mso     ${MSO_HEALTH_CHECK_PATH}     headers=${headers}
+    Should Be Equal As Strings         ${resp.status_code}     200
+
+Run MSO Get Request
+    [Documentation]    Runs an MSO get request
+    [Arguments]    ${data_path}    ${accept}=application/json
+    ${auth}=  Create List  ${GLOBAL_MSO_USERNAME}    ${GLOBAL_MSO_PASSWORD}
+    Log    Creating session ${GLOBAL_MSO_SERVER}
+    ${session}=    Create Session      mso     ${GLOBAL_MSO_SERVER}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=${accept}    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     mso     ${data_path}     headers=${headers}
+    Log    Received response from mso ${resp.text}
+    [Return]    ${resp}
+    
+Poll MSO Get Request
+    [Documentation]    Runs an MSO get request until a certain status is received. valid values are COMPLETE
+    [Arguments]    ${data_path}     ${status}
+    ${auth}=  Create List  ${GLOBAL_MSO_USERNAME}    ${GLOBAL_MSO_PASSWORD}
+    Log    Creating session ${GLOBAL_MSO_SERVER}
+    ${session}=    Create Session      mso     ${GLOBAL_MSO_SERVER}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    #do this until it is done
+    :FOR    ${i}    IN RANGE    20
+    \    ${resp}=      Get Request     mso     ${data_path}     headers=${headers}
+    \    Should Not Contain    ${resp.text}    FAILED
+    \    Log    ${resp.json()['request']['requestStatus']['requestState']}   
+    \    ${exit_loop}=    Evaluate    "${resp.json()['request']['requestStatus']['requestState']}" == "${status}"
+    \    Exit For Loop If  ${exit_loop}
+    \    Sleep    15s
+    Log    Received response from mso ${resp.text}
+    [Return]    ${resp}
+
+
+    
diff --git a/robot/resources/openstack/cinder_interface.robot b/robot/resources/openstack/cinder_interface.robot
new file mode 100644 (file)
index 0000000..ee1a253
--- /dev/null
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation     The main interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+Library           OpenstackLibrary
+Library              RequestsLibrary
+Library                  UUID      
+Library    OperatingSystem
+Resource    ../global_properties.robot
+Resource    ../json_templater.robot
+Resource    openstack_common.robot
+
+
+*** Variables ***
+${OPENSTACK_CINDER_API_VERSION}    /v1
+${OPENSTACK_CINDER_TYPES_PATH}    /types
+${OPENSTACK_CINDER_VOLUMES_PATH}    /volumes
+${OPENSTACK_CINDER_VOLUMES_ADD_BODY_FILE}        robot/assets/templates/cinder_add_volume.template
+${OPENSTACK_CINDER_VOLUMES_TYPE}    SSD
+${OPENSTACK_CINDER_AVAILABILITY_ZONE}    nova
+
+*** Keywords ***
+Get Openstack Volume Types
+    [Documentation]    Returns the openstack volume types information
+    [Arguments]    ${alias}  
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_CINDER_TYPES_PATH}  
+    [Return]    ${resp.json()}
+    
+Get Openstack Volume
+    [Documentation]    Returns the openstack volume information for the passed in volume id
+    [Arguments]    ${alias}    ${volume_id}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_CINDER_VOLUMES_PATH}            /${volume_id}
+    [Return]    ${resp.json()}
+
+Add Openstack Volume
+    [Documentation]    Runs an Openstack Request to add a volume and returns that volume id of the created volume
+    [Arguments]    ${alias}    ${name}     ${size}
+    ${data_template}=    OperatingSystem.Get File    ${OPENSTACK_CINDER_VOLUMES_ADD_BODY_FILE}
+    ${uuid}=    Generate UUID
+    ${arguments}=    Create Dictionary    name=${name}     description=${GLOBAL_APPLICATION_ID}${uuid} size=${size}    type=${OPENSTACK_CINDER_VOLUMES_TYPE}    availability_zone=${OPENSTACK_CINDER_AVAILABILITY_ZONE}
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_CINDER_VOLUMES_PATH}    data_path=    data=${data}
+    Should Be Equal As Strings    200  ${resp.status_code}
+    [Return]    ${resp.json()['volume']['id']}
+    
+Delete Openstack Volume
+    [Documentation]    Runs an Openstack Request to delete a volume
+    [Arguments]    ${alias}    ${volume_id}
+    ${resp}=    Internal Delete Openstack    ${alias}    ${GLOBAL_OPENSTACK_CINDER_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_CINDER_VOLUMES_PATH}       /${volume_id}  
+    ${status_string}=    Convert To String    ${resp.status_code}
+    Should Match Regexp    ${status_string}    ^(204|200|404)$     
+    [Return]    ${resp.text}
\ No newline at end of file
diff --git a/robot/resources/openstack/heat_interface.robot b/robot/resources/openstack/heat_interface.robot
new file mode 100644 (file)
index 0000000..74c7aac
--- /dev/null
@@ -0,0 +1,93 @@
+*** Settings ***
+Documentation     The interface for interacting with Openstack Heat API. 
+Library           OpenstackLibrary
+Library              RequestsLibrary
+Library                  UUID      
+Library    OperatingSystem
+Library    HEATUtils
+Library    StringTemplater
+Library    Collections
+Resource    ../global_properties.robot
+Resource    ../json_templater.robot
+Resource    openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_HEAT_API_VERSION}    /v1    
+${OPENSTACK_HEAT_STACK_PATH}    /stacks
+${OPENSTACK_HEAT_ADD_STACK_TEMPLATE}    robot/assets/templates/heat_add_stack.template
+
+
+*** Keywords ***
+Get Openstack Stacks
+    [Documentation]    Returns the openstack stacks info
+    [Arguments]    ${alias}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}
+    [Return]    ${resp.json()}
+    
+Get Openstack Stack
+    [Documentation]    Returns the openstack stacks info for the given stack name
+    [Arguments]    ${alias}    ${stack_name}    
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}    /${stack_name}
+    [Return]    ${resp.json()}
+    
+Create Openstack Stack
+    [Documentation]    Takes an openstack heat yaml and returns the created stack
+    [Arguments]    ${alias}    ${request}
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}    data_path=    data=${request}
+    [Return]    ${resp.json()}
+
+Make Add Stack Request
+    [Documentation]    Makes a JSON Add Stack Request from  YAML template and env files
+    [Arguments]    ${name}    ${template}    ${env}
+    ${templatedata}=    Template Yaml To Json    ${template}
+    ${envdata}=    Env Yaml To Json    ${env}
+    ${dict}=  Create Dictionary     template=${templatedata}    parameters=${envdata}    stack_name=${name}
+    ${resp}=    OperatingSystem.Get File    ${OPENSTACK_HEAT_ADD_STACK_TEMPLATE}
+    ${request}=     Template String    ${resp}    ${dict}
+    Log    $request 
+    [Return]    ${request}
+
+Delete Openstack Stack
+    [Documentation]    Deletes and Openstack Stack for the passed name and id
+    [Arguments]    ${alias}    ${stack_name}    ${stack_id}    
+    ${data_path}=    Catenate    /${stack_name}/${stack_id}
+    ${resp}=    Internal Delete Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}    data_path=${data_path}
+    Should Be Equal As Strings    204  ${resp.status_code}
+    [Return]    ${resp}
+
+Get Stack Details
+    [Documentation]    Gets all of the information necessary for tearing down an existing Openstack Stack 
+    [Arguments]    ${alias}    ${stack_name}    
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}    /${stack_name}
+    ${result}=    Stack Info Parse    ${resp.json()}    
+    [Return]     ${result}
+
+Get Stack Template
+    [Documentation]    Gets all of the template information of an existing Openstack Stack 
+    [Arguments]    ${alias}    ${stack_name}    ${stack_id}    
+    ${data_path}=    Catenate    /${stack_name}/${stack_id}/template
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}    ${data_path}
+    ${template}=       Catenate    ${resp.json()}
+    [Return]    ${template}
+    
+Get Stack Resources
+    [Documentation]    Gets all of the resources of an existing Openstack Stack 
+    [Arguments]    ${alias}    ${stack_name}    ${stack_id}    
+    ${data_path}=    Catenate    /${stack_name}/${stack_id}/resources
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_HEAT_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_HEAT_STACK_PATH}    ${data_path}
+    [Return]    ${resp.json()}
+Wait for Stack to Be Deployed
+    [Arguments]    ${alias}   ${stack_name}    ${timeout}=600s
+    ${stack_info}=    Wait Until Keyword Succeeds    ${timeout}    30 sec    Get Deployed Stack    ${alias}    ${stack_name}    
+    ${status}=   Get From Dictionary    ${stack_info}    stack_status
+    Should Be Equal    ${status}    CREATE_COMPLETE
+    [Return]    ${stack_info}
+    
+Get Deployed Stack
+    [Arguments]    ${alias}    ${stack_name}    
+    ${stack_info}=    Get Stack Details    ${alias}    ${stack_name}
+    ${status}=   Get From Dictionary    ${stack_info}    stack_status
+    Should Not Be Equal    ${status}    CREATE_IN_PROGRESS
+    [Return]    ${stack_info}     
+        
\ No newline at end of file
diff --git a/robot/resources/openstack/keystone_interface.robot b/robot/resources/openstack/keystone_interface.robot
new file mode 100644 (file)
index 0000000..928efbd
--- /dev/null
@@ -0,0 +1,49 @@
+*** Settings ***
+Documentation     The main interface for interacting with Openstack Keystone API. It handles low level stuff like managing the authtoken and Openstack required fields
+Library           OpenstackLibrary
+Library              RequestsLibrary
+Library                  UUID      
+Library    OperatingSystem
+Resource    ../global_properties.robot
+Resource    ../json_templater.robot
+Resource    openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_KEYSTONE_API_VERSION}    /v2.0
+${OPENSTACK_KEYSTONE_AUTH_PATH}    /tokens
+${OPENSTACK_KEYSTONE_AUTH_BODY_FILE}    robot/assets/templates/keystone_get_auth.template
+${OPENSTACK_KEYSTONE_TENANT_PATH}    /tenants
+
+*** Keywords ***
+Run Openstack Auth Request
+    [Documentation]    Runs an Openstack Auth Request and returns the token and service catalog. you need to include the token in future request's x-auth-token headers. Service catalog describes what can be called
+    [Arguments]    ${alias}    ${username}=    ${password}=
+    ${username}    ${password}=   Set Openstack Credentials   ${username}    ${password}
+    ${session}=    Create Session      keystone        ${GLOBAL_OPENSTACK_KEYSTONE_SERVER}    verify=True
+    ${uuid}=    Generate UUID
+    ${data_template}=    OperatingSystem.Get File    ${OPENSTACK_KEYSTONE_AUTH_BODY_FILE}
+    ${arguments}=    Create Dictionary    username=${username}    password=${password}
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}
+    ${data_path}=    Catenate    ${OPENSTACK_KEYSTONE_API_VERSION}${OPENSTACK_KEYSTONE_AUTH_PATH}
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    Log    Sending authenticate post request ${data_path} with headers ${headers} and data ${data}
+    ${resp}=   Post Request    keystone        ${data_path}     data=${data}    headers=${headers}
+    Save Openstack Auth    ${alias}    ${resp.text} 
+    Log    Received response from keystone ${resp.text}
+       
+Get Openstack Tenants
+    [Documentation]    Returns all the openstack tenant info
+    [Arguments]    ${alias}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_KEYSTONE_SERVICE_TYPE}    region=    url_ext=${OPENSTACK_KEYSTONE_TENANT_PATH}    data_path=
+    [Return]    ${resp.json()}
+    
+Get Openstack Tenant
+    [Documentation]    Returns the openstack tenant info for the specified tenantid
+    [Arguments]    ${alias}     ${tenant_id}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_KEYSTONE_SERVICE_TYPE}    region=    url_ext=${OPENSTACK_KEYSTONE_TENANT_PATH}    data_path=/${tenant_id}
+    [Return]    ${resp.json()}
+    
+Set Openstack Credentials
+    [Arguments]    ${username}    ${password}
+    Return From Keyword If    '${username}' != ''   ${username}    ${password} 
+    [Return]   ${GLOBAL_VM_PROPERTIES['openstack_username']}    ${GLOBAL_VM_PROPERTIES['openstack_password']}
\ No newline at end of file
diff --git a/robot/resources/openstack/neutron_interface.robot b/robot/resources/openstack/neutron_interface.robot
new file mode 100644 (file)
index 0000000..77635cd
--- /dev/null
@@ -0,0 +1,123 @@
+*** Settings ***
+Documentation     The main interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+Library           OpenstackLibrary
+Library              RequestsLibrary
+Library                  UUID      
+Library           OperatingSystem
+Library           Collections
+Resource    ../global_properties.robot
+Resource    ../json_templater.robot
+Resource    openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_NEUTRON_API_VERSION}    /v2.0
+${OPENSTACK_NEUTRON_NETWORK_PATH}    /networks
+${OPENSTACK_NEUTRON_NETWORK_ADD_BODY_FILE}    robot/assets/templates/neutron_add_network.template
+${OPENSTACK_NEUTRON_SUBNET_PATH}    /subnets
+${OPENSTACK_NEUTRON_SUBNET_ADD_BODY_FILE}    robot/assets/templates/neutron_add_subnet.template
+${OPENSTACK_NEUTRON_PORT_PATH}    /ports
+
+*** Keywords ***
+Get Openstack Network
+    [Documentation]    Runs an Openstack Request and returns the network info
+    [Arguments]    ${alias}    ${network_id}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_NETWORK_PATH}    /${network_id}
+    [Return]    ${resp.json()}
+
+Get Openstack Networks
+    [Documentation]    Runs an Openstack Request and returns the network info
+    [Arguments]    ${alias}    
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_NETWORK_PATH}    
+    [Return]    ${resp.json()}
+
+Get Openstack Subnets
+    [Documentation]    Runs an Openstack Request and returns the network info
+    [Arguments]    ${alias}    
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_SUBNET_PATH}    
+    [Return]    ${resp.json()}
+
+Get Openstack Ports
+    [Documentation]    Runs an Openstack Request and returns the network info
+    [Arguments]    ${alias}    
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_PORT_PATH}    
+    [Return]    ${resp.json()}
+
+Add Openstack Network
+    [Documentation]    Runs an Openstack Request to add a network and returns that network id of the created network
+    [Arguments]    ${alias}    ${name}
+    ${data_template}=    OperatingSystem.Get File    ${OPENSTACK_NEUTRON_NETWORK_ADD_BODY_FILE}
+    ${arguments}=    Create Dictionary    name=${name}
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_NETWORK_PATH}    data_path=    data=${data}
+    Should Be Equal As Strings    201  ${resp.status_code}
+    [Return]    ${resp.json()['network']['id']}
+
+Delete Openstack Network
+    [Documentation]    Runs an Openstack Request to delete a network
+    [Arguments]    ${alias}    ${network_id}
+    ${resp}=    Internal Delete Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_NETWORK_PATH}     /${network_id}  
+    ${status_string}=    Convert To String    ${resp.status_code}
+    Should Match Regexp    ${status_string}    ^(204|200)$     
+    [Return]    ${resp.text}
+
+Add Openstack Network With Subnet If Not Exists
+    [Documentation]    Runs an Openstack Request to add a network and returns that network id of the created network
+    [Arguments]    ${alias}    ${name}    ${cidr}
+    ${network}=    Get Openstack Subnet By Name    ${alias}    ${name}   ${cidr}
+    ${pass}    ${v}=    Run Keyword and Ignore Error    Dictionary Should Contain Key    ${network}    id    
+    Run Keyword If    '${pass}' == 'FAIL'    Add Openstack Network With Subnet    ${alias}    ${name}    ${cidr}
+    ${network}=    Get Openstack Subnet By Name    ${alias}    ${name}   ${cidr}
+    ${network_id}=     Get From Dictionary    ${network}    id
+    [Return]     ${network_id}
+    
+
+Add Openstack Network With Subnet
+    [Documentation]    Runs an Openstack Request to add a network and returns that network id of the created network
+    [Arguments]    ${alias}    ${name}    ${cidr}
+    ${network_id}=    Add Openstack Network    ${alias}    ${name}
+    ${data_template}=    OperatingSystem.Get File    ${OPENSTACK_NEUTRON_SUBNET_ADD_BODY_FILE}
+    ${arguments}=    Create Dictionary    network_id=${network_id}    cidr=${cidr}    subnet_name=${name}
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_SUBNET_PATH}    data_path=    data=${data}
+    Should Be Equal As Strings    201  ${resp.status_code}
+    [Return]     ${network_id}
+    
+Get Openstack Subnet By Name
+    [Documentation]    Retrieve the subnet from openstack by it's name.
+    [Arguments]    ${alias}    ${network_name}    ${network_cidr}
+    ${resp}=    Get Openstack Subnets    ${alias}
+    @{list}=    Get From Dictionary    ${resp}    subnets
+    ${returnnet}=    Set Variable                    
+    :for    ${net}    in    @{list}
+    \    ${name}=   Get From Dictionary    ${net}    name
+    \    ${cidr}=   Get From Dictionary    ${net}    cidr
+    \    ${returnnet}=    Set Variable    ${net}
+    \    Exit For Loop If    '${name}'=='${network_name}' and '${cidr}'=='${network_cidr}' 
+    \    ${returnnet}=    Create DIctionary
+    [Return]    ${returnnet}
+
+Get Openstack IP By Name 
+    [Arguments]    ${alias}    ${network_name}    ${cidr}    ${ip}
+    ${ports}=    Get Openstack Ports For Subnet    ${alias}    ${network_name}    ${cidr}
+    Log    ${ports}
+    :for    ${port}   in   @{ports}
+    \    Return From Keyword If    '${port['fixed_ips'][0]['ip_address']}' == '${ip}'    ${port}
+    [Return]    None
+
+Get Openstack Ports For Subnet
+    [Arguments]    ${alias}    ${network_name}    ${cidr}
+    ${net}=    Get Openstack Subnet By Name    ${alias}    ${network_name}    ${cidr}
+    ${ports}=    Get Openstack Ports     ${alias}
+    ${net_ports}=    Create List
+    :for    ${port}    in    @{ports['ports']}
+    \    Run Keyword If   '${net['network_id']}' == '${port['network_id']}'    Append To List    ${net_ports}   ${port}
+    [Return]   ${net_ports}
+                
+Delete Openstack Port
+    [Arguments]    ${alias}    ${port_id} 
+    ${resp}=    Internal Delete Openstack    ${alias}    ${GLOBAL_OPENSTACK_NEUTRON_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NEUTRON_PORT_PATH}        /${port_id}  
+    ${status_string}=    Convert To String    ${resp.status_code}
+    Should Match Regexp    ${status_string}    ^(204|200)$     
+    [Return]    ${resp.text}
+      
+    
\ No newline at end of file
diff --git a/robot/resources/openstack/nova_interface.robot b/robot/resources/openstack/nova_interface.robot
new file mode 100644 (file)
index 0000000..efee279
--- /dev/null
@@ -0,0 +1,149 @@
+*** Settings ***
+Documentation     The main interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+Library           OpenstackLibrary
+Library              RequestsLibrary
+Library              JSONUtils
+Library                  UUID      
+Library    OperatingSystem
+Library    Collections
+Resource    ../global_properties.robot
+Resource    ../json_templater.robot
+Resource    openstack_common.robot
+
+*** Variables ***
+${OPENSTACK_NOVA_API_VERSION}    /v2
+${OPENSTACK_NOVA_KEYPAIR_PATH}    /os-keypairs
+${OPENSTACK_NOVA_KEYPAIR_ADD_BODY_FILE}    robot/assets/templates/nova_add_keypair.template
+${OPENSTACK_NOVA_KEYPAIR_SSH_KEY}    robot/assets/keys/robot_ssh_public_key.txt
+${OPENSTACK_NOVA_FLAVORS_PATH}    /flavors
+${OPENSTACK_NOVA_SERVERS_PATH}    /servers
+${OPENSTACK_NOVA_IMAGES_PATH}    /images
+${OPENSTACK_NOVA_SERVERS_REBOOT_BODY}    {"reboot" : { "type" : "SOFT" }}
+${OPENSTACK_NOVA_SERVER_ADD_BODY_FILE}    robot/assets/templates/nova_add_server.template
+
+
+*** Keywords ***
+Get Openstack Keypair
+    [Documentation]    Runs an Openstack Request and returns the keypair info
+    [Arguments]    ${alias}    ${keypair_name}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_KEYPAIR_PATH}    /${keypair_name}
+    [Return]    ${resp.json()}
+
+Add Openstack Keypair
+    [Documentation]    Runs an Openstack Request to add a keypair and returns the keypair name
+    [Arguments]    ${alias}    ${name}
+    ${data_template}=    OperatingSystem.Get File    ${OPENSTACK_NOVA_KEYPAIR_ADD_BODY_FILE}
+    ${ssh_key}=    OperatingSystem.Get File     ${OPENSTACK_NOVA_KEYPAIR_SSH_KEY}
+    ${arguments}=    Create Dictionary    name=${name}     publickey=${ssh_key}
+    ${data}=   Fill JSON Template    ${data_template}    ${arguments}
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_KEYPAIR_PATH}    data_path=    data=${data}
+    Should Be Equal As Strings    200  ${resp.status_code}
+    [Return]    ${resp.json()['keypair']['name']}
+
+Delete Openstack Keypair
+    [Documentation]    Runs an Openstack Request to delete a keypair
+    [Arguments]    ${alias}    ${keypair_name}
+    ${resp}=    Internal Delete Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_KEYPAIR_PATH}   /${keypair_name}  
+    ${status_string}=    Convert To String    ${resp.status_code}
+    Should Match Regexp    ${status_string}    ^(204|202|200)$    
+    [Return]    ${resp.text}
+
+
+Get Openstack Servers
+    [Documentation]    Returns the list of servers as a dictionary by name
+    [Arguments]    ${alias}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_SERVERS_PATH}    /detail
+    Log    Returned from Internal Get Openstack
+    ${by_name}=    Make List Into Dict    ${resp.json()['servers']}    name
+    Log    got it
+    [Return]    ${by_name}
+    
+Get Openstack Server By Id
+    [Documentation]    Returns the openstack stacks info for the given stack name
+    [Arguments]    ${alias}    ${server_id}        
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_SERVERS_PATH}    /${server_id}
+    [Return]    ${resp}
+    
+Get Openstack Flavors
+    [Documentation]    Runs an Openstack Request and returns the flavor list
+    [Arguments]    ${alias}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_FLAVORS_PATH}
+    [Return]    ${resp.json()}
+
+Get Openstack Images
+    [Documentation]    Runs an Openstack Request and returns the flavor list
+    [Arguments]    ${alias}
+    ${resp}=    Internal Get Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_IMAGES_PATH}
+    [Return]    ${resp.json()}
+
+Reboot Server
+    [Documentation]    Requests a reboot of the passed server id
+    [Arguments]    ${alias}    ${server_id}        
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_SERVERS_PATH}    /${server_id}/action    ${OPENSTACK_NOVA_SERVERS_REBOOT_BODY}
+    [Return]    ${resp}
+
+Add Server
+    [Documentation]    Adds a server for the passed if
+    [Arguments]    ${alias}    ${name}    ${imageRef}    ${flavorRef}
+    ${dict}=    Create Dictionary   name=${name}   imageRef=${imageRef}   flavorRef=${flavorRef}
+    ${data}=    Fill JSON Template File    ${OPENSTACK_NOVA_SERVER_ADD_BODY_FILE}    ${dict}        
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_SERVERS_PATH}   data_path=    data=${data}     
+    [Return]    ${resp}
+
+Add Server For Image Name
+    [Documentation]    Adds a server for the passed if
+    [Arguments]    ${alias}    ${name}    ${imageName}    ${flavorName}
+    ${images}=  Get Openstack Images    ${alias}
+    ${flavors}=  Get Openstack Flavors    ${alias}
+    ${images}=   Get From Dictionary   ${images}   images
+    ${flavors}=   Get From Dictionary   ${flavors}   flavors
+    ${imageRef}=    Get Id For Name   ${images}    ${imageName}
+    ${flavorRef}=   Get Id For Name   ${flavors}    ${flavorName}
+    ${dict}=    Create Dictionary   name=${name}   imageRef=${imageRef}   flavorRef=${flavorRef}
+    ${data}=    Fill JSON Template File    ${OPENSTACK_NOVA_SERVER_ADD_BODY_FILE}    ${dict}        
+    ${resp}=    Internal Post Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_SERVERS_PATH}   data_path=    data=${data}     
+    ${status_string}=    Convert To String    ${resp.status_code}
+    Should Match Regexp    ${status_string}    ^(202)$
+    [Return]    ${resp.json()}
+
+Wait for Server to Be Active
+    [Arguments]    ${alias}   ${server_id}    ${timeout}=300s
+    ${server_info}=    Wait Until Keyword Succeeds    ${timeout}    10 sec    Get Active Server    ${alias}    ${server_id}    
+    ${status}=   Get From Dictionary    ${server_info}    status
+    Should Be Equal    ${status}    ACTIVE
+    [Return]    ${server_info}
+
+ Get Active Server
+    [Arguments]    ${alias}    ${server_id}    
+    ${resp}=    Get Openstack Server By Id    ${alias}    ${server_id}
+    Should Be Equal As Strings   ${resp.status_code}    200
+    ${server_info}=    Set Variable    ${resp.json()}   
+    ${server_info}=    Get From Dictionary   ${server_info}    server
+    ${status}=   Get From Dictionary    ${server_info}    status
+    Should Not Be Equal    ${status}    BUILD
+    [Return]    ${server_info}     
+
+Wait for Server to Be Deleted
+    [Arguments]    ${alias}    ${server_id}
+    Wait Until Keyword Succeeds    300s   10s    Get Deleted Server   ${alias}    ${server_id}
+
+Get Deleted Server
+    [Arguments]    ${alias}    ${server_id}
+    ${resp}=  Get Openstack Server By Id   ${alias}    ${server_id}
+    Should Be Equal As Strings    ${resp.status_code}    404
+
+Delete Server
+    [Documentation]    Runs an Openstack Request to delete a keypair
+    [Arguments]    ${alias}    ${server_id}
+    ${resp}=    Internal Delete Openstack    ${alias}    ${GLOBAL_OPENSTACK_NOVA_SERVICE_TYPE}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${OPENSTACK_NOVA_SERVERS_PATH}   /${server_id}  
+    ${status_string}=    Convert To String    ${resp.status_code}
+    Should Match Regexp    ${status_string}    ^(204)$    
+    [Return]    ${resp.text}
+
+Get Id For Name
+    [Arguments]    ${list}    ${name}
+    :for   ${item}   in   @{list}
+    \    ${id}=    Get From Dictionary    ${item}    id 
+    \    ${n}=    Get From Dictionary    ${item}    name
+    \    Return from Keyword If   '${n}' == '${name}'   ${id} 
+    [Return]   None    
diff --git a/robot/resources/openstack/openstack_common.robot b/robot/resources/openstack/openstack_common.robot
new file mode 100644 (file)
index 0000000..6a53ab6
--- /dev/null
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation     The private interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+
+Library           OpenstackLibrary
+Library              RequestsLibrary
+Library                  UUID      
+Resource    ../global_properties.robot
+
+*** Keywords ***
+Internal Get Openstack
+    [Documentation]    Runs an Openstack Get Request and returns the response
+    [Arguments]    ${alias}    ${service_type}    ${region}    ${url_ext}   ${data_path}=
+    Log    Internal Get Openstack values alias=${alias} service_type=${service_type} region=${region} url_ext=${url_ext} data_path=${data_path}
+    ${url}=    Get Openstack Service Url    ${alias}     ${service_type}    ${region}
+    ${uuid}=    Generate UUID
+    ${session_alias}=    Catenate    openstack-${uuid}
+    ${session}=    Create Session      ${session_alias}        ${url}${url_ext}        verify=True    
+    ${token}=    Get Openstack Token    ${alias}
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}     X-Auth-Token=${token}
+    ${resp}=   Get Request     ${session_alias}        ${data_path}     headers=${headers}
+    Log    Received response from openstack ${resp.text}    
+    [Return]    ${resp}
+
+Internal Post Openstack
+    [Documentation]    Runs an Openstack Post Response and returns the response
+    [Arguments]    ${alias}    ${service_type}    ${region}    ${url_ext}   ${data_path}=    ${data}=
+    Log    Internal Post Openstack values alias=${alias} service_type=${service_type} region=${region} url_ext=${url_ext} data_path=${data_path}
+    ${url}=    Get Openstack Service Url    ${alias}     ${service_type}    ${region}
+    ${uuid}=    Generate UUID
+    ${session_alias}=    Catenate    openstack-${uuid}
+    ${session}=    Create Session      ${session_alias}        ${url}${url_ext}        verify=True    
+    ${token}=    Get Openstack Token    ${alias}
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}     X-Auth-Token=${token}
+    ${resp}=   Post Request    ${session_alias}        ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from openstack ${resp.text}
+    [Return]    ${resp}
+
+Internal Delete Openstack
+    [Documentation]    Runs an Openstack Delete Request and returns the response
+    [Arguments]    ${alias}    ${service_type}    ${region}    ${url_ext}   ${data_path}=
+    Log    Internal Post Openstack values alias=${alias} service_type=${service_type} region=${region} url_ext=${url_ext} data_path=${data_path}
+    ${url}=    Get Openstack Service Url    ${alias}     ${service_type}    ${region}
+    ${uuid}=    Generate UUID
+    ${session_alias}=    Catenate    openstack-${uuid}
+    ${session}=    Create Session      ${session_alias}        ${url}${url_ext}        verify=True
+    ${token}=    Get Openstack Token    ${alias}
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}     X-Auth-Token=${token}
+    ${resp}=   Delete Request  ${session_alias}        ${data_path}    headers=${headers}
+    Log    Received response from openstack ${resp.text}
+    [Return]    ${resp}
\ No newline at end of file
diff --git a/robot/resources/policy_interface.robot b/robot/resources/policy_interface.robot
new file mode 100644 (file)
index 0000000..3bd51f5
--- /dev/null
@@ -0,0 +1,58 @@
+*** Settings ***
+Documentation    The main interface for interacting with Policy. It handles low level stuff like managing the http request library and Policy required fields
+Library                  RequestsClientCert
+Library              RequestsLibrary
+Library           String
+Library           JSONUtils
+Library           Collections      
+Resource          global_properties.robot
+
+*** Variables ***
+${POLICY_HEALTH_CHECK_PATH}        /healthcheck
+
+*** Keywords ***
+
+Run Policy Health Check
+     [Documentation]    Runs Policy Health check
+     ${auth}=    Create List    ${GLOBAL_POLICY_USERNAME}    ${GLOBAL_POLICY_PASSWORD}    
+     Log    Creating session ${GLOBAL_POLICY_SERVER_URL}
+     ${session}=    Create Session     policy  ${GLOBAL_POLICY_HEALTHCHECK_URL}   auth=${auth}
+     ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json
+     ${resp}=  Get Request     policy  ${POLICY_HEALTH_CHECK_PATH}     headers=${headers}
+     Log    Received response from policy ${resp.text}
+     Should Be Equal As Strings        ${resp.status_code}     200
+     Should Be True    ${resp.json()['healthy']}
+     @{ITEMS}=    Copy List    ${resp.json()['details']}
+     :FOR    ${ELEMENT}    IN    @{ITEMS}
+     \    Should Be Equal As Strings   ${ELEMENT['code']}      200
+     \    Should Be True    ${ELEMENT['healthy']}
+    
+Run Policy Put Request
+     [Documentation]    Runs Policy Put request
+     [Arguments]    ${data_path}  ${data}
+     Log    Creating session ${GLOBAL_POLICY_SERVER_URL}
+     ${session}=    Create Session     policy  ${GLOBAL_POLICY_SERVER_URL}
+     ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    Authorization=Basic ${GLOBAL_POLICY_AUTH}   ClientAuth=${GLOBAL_POLICY_CLIENTAUTH}    Environment=TEST
+     ${resp}=  Put Request     policy  ${data_path}     data=${data}    headers=${headers}
+     Log    Received response from policy ${resp.text}
+     [Return]    ${resp}
+     
+Run Policy Delete Request
+     [Documentation]    Runs Policy Delete request
+     [Arguments]    ${data_path}  ${data}
+     Log    Creating session ${GLOBAL_POLICY_SERVER_URL}
+     ${session}=    Create Session     policy  ${GLOBAL_POLICY_SERVER_URL}
+     ${headers}=    Create Dictionary     Accept=application/json    Content-Type=application/json    Authorization=Basic ${GLOBAL_POLICY_AUTH}   ClientAuth=${GLOBAL_POLICY_CLIENTAUTH}    Environment=TEST
+     ${resp}=  Delete Request  policy  ${data_path}    data=${data}    headers=${headers}
+     Log    Received response from policy ${resp.text}
+     [Return]    ${resp}
+     
+Run Policy Get Configs Request
+    [Documentation]    Runs Policy Get Configs request
+    [Arguments]    ${data_path}  ${data}
+    Log    Creating session ${GLOBAL_POLICY_SERVER_URL}
+    ${session}=    Create Session      policy  ${GLOBAL_POLICY_SERVER_URL}
+    ${headers}=    Create Dictionary     Accept=application/json    Content-Type=application/json    Authorization=Basic ${GLOBAL_POLICY_AUTH}   ClientAuth=${GLOBAL_POLICY_CLIENTAUTH}    
+    ${resp}=   Post Request    policy  ${data_path}    data=${data}    headers=${headers}
+    Log    Received response from policy ${resp.text}
+    [Return]    ${resp}
\ No newline at end of file
diff --git a/robot/resources/portal_interface.robot b/robot/resources/portal_interface.robot
new file mode 100644 (file)
index 0000000..7d53b37
--- /dev/null
@@ -0,0 +1,28 @@
+*** Settings ***
+Documentation    The main interface for interacting with Portal. It handles low level stuff like managing the http request library and Portal required fields
+Library                  RequestsClientCert
+Library              RequestsLibrary
+Library                  UUID      
+
+Resource          global_properties.robot
+
+*** Variables ***
+${PORTAL_HEALTH_CHECK_PATH}        /ECOMPPORTAL/portalApi/healthCheck
+
+*** Keywords ***
+Run Portal Health Check
+     [Documentation]    Runs Portal Health check
+     ${resp}=    Run Portal Get Request    ${PORTAL_HEALTH_CHECK_PATH}    
+     Should Be Equal As Strings        ${resp.status_code}     200
+     Should Be Equal As Strings        ${resp.json()['statusCode']}    200
+         
+Run Portal Get Request
+     [Documentation]    Runs Portal Get request
+     [Arguments]    ${data_path}
+     ${session}=    Create Session     portal  ${GLOBAL_PORTAL_SERVER}
+     ${uuid}=    Generate UUID
+     ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+     ${resp}=  Get Request     portal  ${data_path}     headers=${headers}
+     Log    Received response from portal ${resp.text}
+     [Return]    ${resp}
+
diff --git a/robot/resources/sdngc_interface.robot b/robot/resources/sdngc_interface.robot
new file mode 100644 (file)
index 0000000..d413b6e
--- /dev/null
@@ -0,0 +1,203 @@
+*** Settings ***
+Documentation     The main interface for interacting with SDN-GC. It handles low level stuff like managing the http request library and SDN-GC required fields
+Library              RequestsLibrary
+Library                  UUID      
+Library    OperatingSystem
+Library            ExtendedSelenium2Library
+Library         Collections
+Library      String
+Library      StringTemplater
+Resource          global_properties.robot
+Resource          ../resources/json_templater.robot
+Resource        browser_setup.robot
+
+Variables    ../assets/service_mappings.py
+
+*** Variables ***
+${PRELOAD_VNF_TOPOLOGY_OPERATION_PATH}  /operations/VNF-API:preload-vnf-topology-operation
+${PRELOAD_VNF_CONFIG_PATH}  /config/VNF-API:preload-vnfs/vnf-preload-list
+${PRELOAD_VNF_TOPOLOGY_OPERATION_BODY}  robot/assets/templates/sdnc/
+${SDNGC_INDEX_PATH}    /restconf
+${SDNCGC_HEALTHCHECK_OPERATION_PATH}  /operations/SLI-API:healthcheck
+${SDNGC_REST_ENDPOINT}    ${GLOBAL_SDNGC_SERVER}:${GLOBAL_SDNGC_REST_PORT}
+${SDNGC_ADMIN_ENDPOINT}    ${GLOBAL_SDNGC_SERVER}:${GLOBAL_SDNGC_ADMIN_PORT}
+${SDNGC_ADMIN_SIGNUP_URL}    ${SDNGC_ADMIN_ENDPOINT}/signup
+${SDNGC_ADMIN_LOGIN_URL}    ${SDNGC_ADMIN_ENDPOINT}/login
+${SDNGC_ADMIN_VNF_PROFILE_URL}    ${SDNGC_ADMIN_ENDPOINT}/mobility/getVnfProfile
+
+*** Keywords ***
+Run SDNGC Health Check
+    [Documentation]    Runs an SDNGC healthcheck
+       ${resp}=    Run SDNGC Post Request     ${SDNGC_INDEX PATH}${SDNCGC_HEALTHCHECK_OPERATION_PATH}     ${None}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    Should Be Equal As Strings         ${resp.json()['output']['response-code']}       200   
+
+Run SDNGC Get Request
+    [Documentation]    Runs an SDNGC get request
+    [Arguments]    ${data_path}
+    ${auth}=  Create List  ${GLOBAL_SDNGC_USERNAME}    ${GLOBAL_SDNGC_PASSWORD}
+    Log    Creating session ${SDNGC_REST_ENDPOINT}
+    ${session}=    Create Session      sdngc   ${SDNGC_REST_ENDPOINT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     sdngc   ${data_path}     headers=${headers}
+    Log    Received response from sdngc ${resp.text}
+    [Return]    ${resp}
+    
+Run SDNGC Put Request
+    [Documentation]    Runs an SDNGC put request
+    [Arguments]    ${data_path}    ${data}
+    ${auth}=  Create List  ${GLOBAL_SDNGC_USERNAME}    ${GLOBAL_SDNGC_PASSWORD}
+    Log    Creating session ${SDNGC_REST_ENDPOINT}
+    ${session}=    Create Session      sdngc   ${SDNGC_REST_ENDPOINT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Put Request     sdngc   ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from sdngc ${resp.text}
+    [Return]    ${resp}
+
+Run SDNGC Post Request
+    [Documentation]    Runs an SDNGC post request
+    [Arguments]    ${data_path}    ${data}
+    ${auth}=  Create List  ${GLOBAL_SDNGC_USERNAME}    ${GLOBAL_SDNGC_PASSWORD}
+    Log    Creating session ${SDNGC_REST_ENDPOINT}
+    ${session}=    Create Session      sdngc   ${SDNGC_REST_ENDPOINT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Post Request    sdngc   ${data_path}     data=${data}    headers=${headers}
+    Log    Received response from sdngc ${resp.text}
+    [Return]    ${resp} 
+  
+Run SDNGC Delete Request
+    [Documentation]    Runs an SDNGC delete request
+    [Arguments]    ${data_path}
+    ${auth}=  Create List  ${GLOBAL_SDNGC_USERNAME}    ${GLOBAL_SDNGC_PASSWORD}
+    Log    Creating session ${SDNGC_REST_ENDPOINT}
+    ${session}=    Create Session      sdngc   ${SDNGC_REST_ENDPOINT}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Delete Request  sdngc   ${data_path}        headers=${headers}
+    Log    Received response from sdngc ${resp.text}
+    [Return]    ${resp}
+
+
+Preload Vnf
+    [Arguments]    ${service_type_uuid}    ${generic_vnf_name}    ${generic_vnf_type}     ${vf_module_name}    ${vf_modules}    ${service}   ${uuid}
+    ${base_vf_module_type}=    Catenate    ''
+    ${closedloop_vf_module}=    Create Dictionary
+    ${templates}=    Get From Dictionary    ${GLOBAL_SERVICE_TEMPLATE_MAPPING}    ${service}
+    :for    ${vf_module}    in      @{vf_modules}
+    \       ${vf_module_type}=    Get From Dictionary    ${vf_module}    name
+    \       ${dict}   Get From Mapping    ${templates}    ${vf_module}
+    \       ${filename}=    Get From Dictionary    ${dict}    template
+    \       ${base_vf_module_type}=   Set Variable If    '${dict['isBase']}' == 'true'     ${vf_module_type}    ${base_vf_module_type}
+    \       ${closedloop_vf_module}=   Set Variable If    '${dict['isBase']}' == 'false'     ${vf_module}    ${closedloop_vf_module}
+    \       ${vf_name}=     Update Module Name    ${dict}    ${vf_module_name}  
+    \       Preload Vnf Profile    ${vf_module_type}     
+    \       Preload One Vnf Topology    ${service_type_uuid}    ${generic_vnf_name}    ${generic_vnf_type}     ${vf_name}    ${vf_module_type}    ${service}    ${filename}   ${uuid}
+    [Return]    ${base_vf_module_type}   ${closedloop_vf_module}    
+
+
+Update Module Name
+    [Arguments]    ${dict}    ${vf_module_name}
+    Return From Keyword If    'prefix' not in ${dict}    ${vf_module_name}
+    Return From Keyword If    '${dict['prefix']}' == ''    ${vf_module_name}
+    ${name}=    Replace String   ${vf_module_name}   Vfmodule_    ${dict['prefix']} 
+    [Return]    ${name}           
+
+Get From Mapping
+    [Documentation]    Retrieve the appropriate prelad template entry for the passed vf_module    
+    [Arguments]    ${templates}    ${vf_module}
+    ${vf_module_name}=    Get From DIctionary    ${vf_module}    name
+    :for    ${template}   in   @{templates} 
+    \    Return From Keyword If    '${template['name_pattern']}' in '${vf_module_name}'     ${template}    
+    [Return]    None
+    
+            
+Preload One Vnf Topology
+    [Arguments]    ${service_type_uuid}    ${generic_vnf_name}    ${generic_vnf_type}       ${vf_module_name}    ${vf_module_type}    ${service}    ${filename}   ${uuid}
+    Return From Keyword If    '${filename}' == ''
+    ${data_template}=    OperatingSystem.Get File    ${PRELOAD_VNF_TOPOLOGY_OPERATION_BODY}/${filename}
+    ${parameters}=    Get Template Parameters    ${filename}   ${uuid}
+    Set To Dictionary   ${parameters}   generic_vnf_name=${generic_vnf_name}     generic_vnf_type=${generic_vnf_type}  service_type=${service_type_uuid}    vf_module_name=${vf_module_name}    vf_module_type=${vf_module_type}    uuid=${uuid}
+    ${data}=   Fill JSON Template    ${data_template}    ${parameters}        
+       ${put_resp}=    Run SDNGC Post Request     ${SDNGC_INDEX_PATH}${PRELOAD_VNF_TOPOLOGY_OPERATION_PATH}     ${data}
+    Should Be Equal As Strings         ${put_resp.json()['output']['response-code']}   200   
+    ${get_resp}=  Run SDNGC Get Request  ${SDNGC_INDEX_PATH}${PRELOAD_VNF_CONFIG_PATH}/${vf_module_name}/${vf_module_type}
+    Should Be Equal As Strings         ${get_resp.status_code}         200
+
+Get Template Parameters
+    [Arguments]    ${template}    ${uuid}
+    ${rest}   ${suite}=    Split String From Right    ${SUITE NAME}   .   1
+    ${uuid}=    Catenate    ${uuid}
+    ${hostid}=    Get Substring    ${uuid}    -4
+    ${ecompnet}=    Evaluate    ${GLOBAL_BUILD_NUMBER}%255
+    # Initialize the value map with the properties generated from the Robot VM /opt/config folder
+    ${valuemap}=   Copy Dictionary   ${GLOBAL_VM_PROPERTIES}
+    # update the value map with unique values.
+    Set To Dictionary   ${valuemap}   uuid=${uuid}   hostid=${hostid}    ecompnet=${ecompnet}
+    ${parameters}=    Create Dictionary
+    ${defaults}=    Get From Dictionary    ${GLOBAL_PRELOAD_PARAMETERS}    defaults
+    Resolve Values Into Dictionary   ${valuemap}   ${defaults}    ${parameters}
+    ${suite_templates}=    Get From Dictionary    ${GLOBAL_PRELOAD_PARAMETERS}    ${suite}
+    ${template}=    Get From Dictionary    ${suite_templates}    ${template}
+    Resolve Values Into Dictionary   ${valuemap}   ${template}    ${parameters}
+    [Return]    ${parameters}
+   
+Resolve Values Into Dictionary    
+    [Arguments]   ${valuemap}    ${from}    ${to}
+    ${keys}=    Get Dictionary Keys    ${from}
+    :for   ${key}   in  @{keys}
+    \    ${value}=    Get From Dictionary    ${from}   ${key}
+    \    ${value}=    Template String    ${value}    ${valuemap}
+    \    Set To Dictionary    ${to}    ${key}    ${value}
+     
+Preload Vnf Profile
+    [Arguments]    ${vnf_name}
+    Login To SDNGC Admin GUI
+    Go To    ${SDNGC_ADMIN_VNF_PROFILE_URL}
+    Click Button    xpath=//button[@data-target='#add_vnf_profile']
+    Input Text    xpath=//input[@id='nf_vnf_type']    ${vnf_name}
+    Input Text    xpath=//input[@id='nf_availability_zone_count']    999
+    Input Text    xpath=//input[@id='nf_equipment_role']    robot-ete-test
+    Click Button    xpath=//button[contains(.,'Submit')]
+    Page Should Contain  VNF Profile 
+    Input Text    xpath=//div[@id='vnf_profile_filter']//input    ${vnf_name}
+    Page Should Contain  ${vnf_name}  
+
+Delete Vnf Profile
+    [Arguments]    ${vnf_name}
+    Login To SDNGC Admin GUI
+    Go To    ${SDNGC_ADMIN_VNF_PROFILE_URL}
+    Page Should Contain  VNF Profile 
+    Input Text    xpath=//div[@id='vnf_profile_filter']//input    ${vnf_name}
+    Page Should Contain  ${vnf_name}
+    Click Button    xpath=//button[contains(@onclick, '${vnf_name}')]    
+    Page Should Contain    Are you sure you want to delete VNF_PROFILE
+    Click Button    xpath=//button[contains(text(), 'Yes')]
+    Page Should Not Contain  ${vnf_name}
+        
+Login To SDNGC Admin GUI
+    [Documentation]   Login To SDNGC Admin GUI
+    ## Setup Browser is now being managed by the test case 
+    ## Setup Browser
+    Go To    ${SDNGC_ADMIN_SIGNUP_URL}
+    Maximize Browser Window
+    Set Selenium Speed    ${GLOBAL_SELENIUM_DELAY}
+    Set Browser Implicit Wait    ${GLOBAL_SELENIUM_BROWSER_IMPLICIT_WAIT}
+    Log    Logging in to ${SDNGC_ADMIN_LOGIN_URL}
+    Handle Proxy Warning
+    Title Should Be    AdminPortal
+    ${uuid}=    Generate UUID  
+    ${shortened_uuid}=     Evaluate    str("${uuid}")[:12]
+    ${email}=        Catenate    ${shortened_uuid}@robotete.com
+    Input Text    xpath=//input[@id='nf_email']    ${email}
+    Input Password    xpath=//input[@id='nf_password']    ${shortened_uuid}
+    Click Button    xpath=//button[@type='submit']
+    Wait Until Page Contains    User created   20s
+    Go To    ${SDNGC_ADMIN_LOGIN_URL}
+    Input Text    xpath=//input[@id='email']    ${email}
+    Input Password    xpath=//input[@id='password']    ${shortened_uuid}
+    Click Button    xpath=//button[@type='submit']
+    Title Should Be    SDN-C AdminPortal
+    Log    Logged in to ${SDNGC_ADMIN_LOGIN_URL}
\ No newline at end of file
diff --git a/robot/resources/ssh/files.robot b/robot/resources/ssh/files.robot
new file mode 100644 (file)
index 0000000..798ce89
--- /dev/null
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation     Some handy Keywords for accessing log files over SSH.  Assumptions are that logs will belong to users other than the currently logged in user and that sudo will be required
+Library           OperatingSystem
+Library              SSHLibrary   
+Library           HttpLibrary.HTTP
+Library           String
+Library           Collections
+
+*** Variables ***
+
+*** Keywords ***
+Open Connection And Log In
+   [Documentation]    Open a connection using the passed user and SSH key. Connection alias will be the host name by default.
+   [Arguments]    ${HOST}    ${user}    ${pvt}    ${password}=    ${alias}=${HOST}    ${timeout}=20s
+   Open Connection    ${HOST}    alias=${alias}    timeout=${timeout}
+   Login With Public Key    ${user}    ${pvt}    password=${password}    delay=0.5 seconds
+
+Grep Local File
+    [Documentation]     Grep the passed file name and return all of the lines that match the passed pattern using the current connection 
+    [Arguments]    ${pattern}     ${fullpath}
+    ${output}=    Execute Command    grep ${pattern} ${fullpath}  
+    [Return]     ${output}
+    
+ Grep File on Host
+    [Documentation]     Grep the passed file name and return all of the lines that match the passed pattern using passed connection alias/host 
+    [Arguments]     ${host}    ${pattern}     ${fullpath}
+    Switch Connection    ${host}
+    ${output}=    Grep Local File    ${pattern}    ${fullpath}
+    @{lines}=    Split To Lines    ${output}   
+    [Return]     @{lines}
+
+Grep File on Hosts
+    [Documentation]     Grep the passed file name and return all of the lines that match the passed pattern using passed list of connections 
+    [Arguments]    ${HOSTS}    ${pattern}    ${fullpath} 
+    &{map}=    Create Dictionary
+    :FOR    ${HOST}    IN    @{HOSTS}
+    \    Log    ${HOST}
+    \    @{lines}=    Grep File on Host    ${HOST}   ${pattern}    ${fullpath}
+    \    &{map}=    Create Dictionary    ${HOST}=@{lines}    &{map}
+    [Return]    &{map}
+
+Tail File on Host Until
+    [Documentation]     Tail log file into grep which returns file lines containing the grep pattern. Will timeout after timeout= if expected pattern not received.   
+    [Arguments]    ${host}    ${pattern}    ${fullpath}    ${expected}    ${timeout}=60    ${options}=-c -0
+    Switch Connection    ${host}
+    ${tailcommand}=    Catenate    tail ${options} -f ${fullpath} | grep --color=never ${pattern}    
+    Write    ${tailcommand}
+    ${stdout}= Read Until Regexp    ${expected}         
+    @{lines}=    Split To Lines    ${stdout}
+    [Return]    @{lines}
diff --git a/robot/resources/ssh/processes.robot b/robot/resources/ssh/processes.robot
new file mode 100644 (file)
index 0000000..e9f3731
--- /dev/null
@@ -0,0 +1,74 @@
+*** Settings ***
+Documentation     Some handy Keywords for accessing log files over SSH.  Assumptions are that logs will belong to users other than the currently logged in user and that sudo will be required
+Library           OperatingSystem
+Library              SSHLibrary    60 seconds
+Library           HttpLibrary.HTTP
+Library           String
+Library           Collections
+
+*** Variables ***
+
+*** Keywords ***
+
+Get Processes
+    [Documentation]     Returns all of the processes on the currently connected host 
+    ${output}=    Execute Command    ps -ef   
+    ${map}=    Create Process Map    ${output}
+    [Return]     ${map}
+
+Grep Processes
+    [Documentation]     Return the list of processes matching the passed regex 
+    [Arguments]    ${pattern} 
+    ${output}=    Execute Command    ps -ef|grep "${pattern}"|grep -v grep   
+    ${map}=    Create Process Map    ${output}
+    [Return]     ${map}
+
+Create Process Map
+    [Documentation]     Extract process pids and process names from ps -ef output
+    [Arguments]    ${input} 
+    @{lines}=    Split To Lines    ${input}
+    ${map}=    Create Dictionary
+    :for    ${line}    in    @{lines}
+    \    @{parts}=    Split String    ${line}    max_split=7 
+    \    ${pid}=    Catenate    ${parts[1]}
+    \    ${name}=   Catenate   ${parts[7]}
+    \    Set To Dictionary    ${map}    ${pid}=${name}      
+    [Return]     ${map}
+    
+         
+Wait for Process on Host
+    [Documentation]     Wait for the passed process name (regular expression) to be running on the passed host  
+    [Arguments]    ${process_name}    ${host}    ${timeout}=600s    
+    ${map}=    Wait Until Keyword Succeeds    ${timeout}    10 sec    Is Process On Host    ${process_name}    ${host}
+    [Return]    ${map}
+
+
+Pkill Process on Host
+    [Documentation]     Kill the named process(es). Process name must match exactly  
+    [Arguments]    ${process_name}    ${host}    ${timeout}=600s
+    Switch Connection    ${host}
+    ${output}=    Execute Command    pkill -9 -e -f ${process_name}     
+    [Return]    ${output}
+
+Is Process on Host
+   [Documentation]     Look for the passed process name (regex) to be running on the passed host. Process name can include regex.   
+   [Arguments]    ${process_name}    ${host}    
+   Switch Connection    ${host}
+   ${pass}    ${map}=    Run Keyword and Ignore Error    Grep Processes    ${process_name}
+   @{pids}=    Get Dictionary Keys    ${map}
+   ${foundpid}=    Catenate    ""
+   :for    ${pid}    in    @{pids}
+   \    ${process_cmd}=    Get From Dictionary    ${map}    ${pid}
+   \    ${status}    ${value}=    Run Keyword And Ignore Error    Should Match Regexp    ${process_cmd}    ${process_name}    
+   \    Run Keyword If   '${status}' == 'PASS'    Set Test Variable    ${foundpid}    ${pid}             
+   Should Not Be Equal    ${foundpid}    ""           
+   [Return]    ${map}[${foundpid}]
+   
+   
+Get Process List on Host
+    [Documentation]     Gets the list of all processes on the passed host  
+    [Arguments]    ${host}    
+    Switch Connection    ${host}
+    ${map}=    Get Processes  
+    [Return]    ${map}
+        
\ No newline at end of file
diff --git a/robot/resources/stack_validation/darkstat_interface.robot b/robot/resources/stack_validation/darkstat_interface.robot
new file mode 100644 (file)
index 0000000..3537408
--- /dev/null
@@ -0,0 +1,82 @@
+*** Settings ***
+Documentation     The main interface for interacting with A&AI. It handles low level stuff like managing the http request library and A&AI required fields
+Library            ExtendedSelenium2Library
+Library           StringTemplater
+Library                  UUID      
+Library                  OperatingSystem      
+Resource          ../global_properties.robot
+Resource          ../browser_setup.robot
+
+*** Variables ***
+${SNK_HOSTS_TEMPLATE}     http://\${host}:\${port}/hosts/
+${SNK_HOME_TEMPLATE}     http://\${host}:\${port}/
+${SNK_PATH}    
+${SNK_PORT}    667
+${BYTES_PER_PACKET}    29
+${PACKETS_PER_SECOND_PER_STREAM}     11
+${MONITOR_INTERVAL_IN_SECONDS}      4
+
+*** Keywords ***
+Get Darkstat Bytes In 
+    [Documentation]    Get bytes received on the passed interface for the given interval  
+    [Arguments]    ${host}    ${interface}    ${interval}=${MONITOR_INTERVAL_IN_SECONDS}     
+    ${map}=  Create Dictionary     host=${host}    port=${SNK_PORT}    path=${SNK_PATH}   
+    ${url}=    Template String    ${SNK_HOSTS_TEMPLATE}    ${map}        
+    Connect to Darkstat    ${host}    ${url}        
+    Title Should Be    Hosts (darkstat3 eth1)
+    ${initial_bytes}=    Get Current Bytes In    ${interface}
+    Sleep     ${interval}    
+    Go To    ${url}
+    ${new_bytes}=    Get Current Bytes In   ${interface}
+    ${return_bytes}=    Evaluate    int(${new_bytes}) - int(${initial_bytes})
+    [Return]    ${return_bytes}
+
+Get Darkstat Packets In 
+    [Documentation]    Get bytes received on the passed interface for the given interval  
+    [Arguments]    ${host}    ${interval}=${MONITOR_INTERVAL_IN_SECONDS}     
+    ${map}=  Create Dictionary     host=${host}    port=${SNK_PORT}    path=${SNK_PATH}   
+    ${url}=    Template String    ${SNK_HOME_TEMPLATE}    ${map}        
+    Connect to Darkstat    ${host}    ${url}        
+    Title Should Be    Graphs (darkstat3 eth1)
+    ${initial_pkts}=    Get Current Packets In
+    Sleep     ${interval}    
+    Go To    ${url}
+    ${new_pkts}=    Get Current Packets In
+    ${return_pkts}=    Evaluate    int(${new_pkts}) - int(${initial_pkts})
+    [Return]    ${return_pkts}
+
+    
+Connect to Darkstat
+    [Documentation]   COnnects to the Darkstat port on passed host
+    [Arguments]    ${host}    ${url}
+    ## Being managed by the test case
+    ##Setup Browser
+    Go To    ${url}
+    Maximize Browser Window
+    Set Selenium Speed    ${GLOBAL_SELENIUM_DELAY}
+    Set Browser Implicit Wait    ${GLOBAL_SELENIUM_BROWSER_IMPLICIT_WAIT}
+    Log    Logging in to ${url}
+    Handle Proxy Warning
+    
+
+Get Current Bytes In
+    [Documentation]    Retrieves packets input from given host from current Darkstats hosts page
+    [Arguments]    ${interface}
+    ${bytes}=    Get Text    xpath=//tr[td/a[text() = '${interface}']]/td[4]
+    ${bytes}=    Evaluate    ${bytes.replace(',', '')}
+    [Return]     ${bytes}
+
+Get Current Packets In
+    [Documentation]    Retrieves packets input from given host from current Darkstats hosts page
+    ${bytes}=    Get Text    xpath=//span[@id = 'tp']
+    ${bytes}=    Evaluate    ${bytes.replace(',', '')}
+    [Return]     ${bytes}
+    
+    
+Get Expected Range For Number Of Streams
+    [Documentation]    Calculates the expected range of bytes for an interval for the given number of streams
+    [Arguments]    ${number_of_streams}
+    ${bytes_per_second}=     Evaluate    ${BYTES_PER_PACKET}*(${PACKETS_PER_SECOND_PER_STREAM}*${number_of_streams})
+    ${low_bytes}=    Evaluate    (${MONITOR_INTERVAL_IN_SECONDS}-1)*${bytes_per_second}
+    ${high_bytes}=    Evaluate    (${MONITOR_INTERVAL_IN_SECONDS}+1)*${bytes_per_second}       
+    [Return]    ${low_bytes}    ${high_bytes}
\ No newline at end of file
diff --git a/robot/resources/stack_validation/packet_generator_interface.robot b/robot/resources/stack_validation/packet_generator_interface.robot
new file mode 100644 (file)
index 0000000..cc9ba04
--- /dev/null
@@ -0,0 +1,98 @@
+*** Settings ***
+Documentation     The main interface for interacting with A&AI. It handles low level stuff like managing the http request library and A&AI required fields
+Library              RequestsLibrary
+Library           StringTemplater
+Library                  UUID      
+Library                  OperatingSystem      
+Resource          ../global_properties.robot
+Resource          ../json_templater.robot
+
+*** Variables ***
+${PGN_URL_TEMPLATE}     http://\${host}:\${port}
+${PGN_PATH}    /restconf/config/sample-plugin:sample-plugin
+${PGN_ENABLE_STREAM_TEMPLATE}    robot/assets/templates/vfw_pg_stream_enable.template
+${PGN_ENABLE_STREAMS_TEMPLATE}    robot/assets/templates/vfw_pg_streams_enable.template
+
+*** Keywords ***
+Connect To Packet Generator
+    [Documentation]    Enables packet generator for the passed stream on the passed host
+    [Arguments]    ${host}    ${alias}=pgn
+    ${map}=  Create Dictionary     host=${host}    port=${GLOBAL_PACKET_GENERATOR_PORT}    path=${PGN_PATH}   
+    ${url}=    Template String    ${PGN_URL_TEMPLATE}    ${map}        
+    ${auth}=  Create List     ${GLOBAL_PACKET_GENERATOR_USERNAME}    ${GLOBAL_PACKET_GENERATOR_PASSWORD} 
+    ${session}=    Create Session      ${alias}        ${url}    auth=${auth}
+    [Return]     ${session}    
+
+Enable Stream
+    [Documentation]    Enable a single stream on the passed packet generator host IP  
+    [Arguments]    ${host}    ${stream}=udp1    ${alias}=pgn
+    Connect To Packet Generator    ${host}    alias=${alias}
+    ${headers}=  Create Headers
+    ${data_path}=    Catenate    ${PGN_PATH}/pg-streams    
+    ${map}=    Create Dictionary    stream=${stream}
+    ${streams}=   Fill JSON Template File    ${PGN_ENABLE_STREAM_TEMPLATE}    ${map}
+    ${streams}=    evaluate    json.dumps(${streams})    json
+    ${map}=    Create Dictionary    pgstreams=${streams}
+    ${data}=   Fill JSON Template File    ${PGN_ENABLE_STREAMS_TEMPLATE}    ${map} 
+    ${resp}=   Put Request     ${alias}        ${data_path}     data=${data}     headers=${headers}
+    Should Be Equal As Strings    ${resp.status_code}    200
+    [Return]    ${resp}
+
+Enable Streams
+    [Documentation]    Enable <stream_count> number of streams on the passed packet generator host IP  
+    [Arguments]    ${host}    ${stream_count}=5    ${alias}=pgn    ${prefix}=fw_udp
+    Connect To Packet Generator    ${host}    alias=${alias}
+    ${headers}=  Create Headers
+    ${data_path}=    Catenate    ${PGN_PATH}/pg-streams
+    ${streams}=    Set Variable
+    ${comma}=      Set Variable
+    ${stream_count}=    Evaluate    ${stream_count}+1        
+    :for    ${i}    in Range     1    ${stream_count}
+    \    ${name}=    Catenate    ${prefix}${i}
+    \    ${map}=    Create Dictionary    stream=${name}
+    \    ${one}=   Fill JSON Template File    ${PGN_ENABLE_STREAM_TEMPLATE}    ${map}
+    \    ${one}=    evaluate    json.dumps(${one})    json     
+    \    ${streams}=    Set Variable    ${streams}${comma}${one}
+    \    ${comma}=      Set Variable    , 
+    ${map}=    Create Dictionary    pgstreams=${streams}
+    ${data}=   Fill JSON Template File    ${PGN_ENABLE_STREAMS_TEMPLATE}    ${map} 
+    ${resp}=   Put Request     ${alias}        ${data_path}     data=${data}     headers=${headers}
+    Should Be Equal As Strings    ${resp.status_code}    200
+    [Return]    ${resp}
+
+Disable All Streams
+    [Documentation]    Disable all streams on the passed packet generator host IP
+    [Arguments]    ${host}    ${stream}=udp1    ${alias}=pgn
+    Connect To Packet Generator    ${host}    alias=${alias}
+    ${headers}=  Create Headers
+    ${data_path}=    Catenate    ${PGN_PATH}/pg-streams  
+    ${data}=   Catenate    {"pg-streams":{"pg-stream": []}}
+    ${resp}=   Put Request     ${alias}        ${data_path}     data=${data}     headers=${headers}
+    Should Be Equal As Strings    ${resp.status_code}    200
+    [Return]    ${resp}
+
+ Disable Stream
+    [Documentation]    Disables packet generator for the passed stream 
+    [Arguments]    ${host}    ${stream}=udp1    ${alias}=pgn
+    ${session}=    Connect To Packet Generator    ${host}    alias=${alias}
+    ${headers}=  Create Headers
+    ${data_path}=    Catenate    ${PGN_PATH}/pg-streams/pg-stream/${stream}        
+    ${resp}=   Delete Request  ${alias}        ${data_path}     headers=${headers}
+    Should Be Equal As Strings    ${resp.status_code}    200
+    [Return]    ${resp}
+    
+Get List Of Enabled Streams
+    [Documentation]     Get a list of streams on the passed packet generator host IP    
+    [Arguments]    ${host}    ${alias}=pgn
+    ${session}=    Connect To Packet Generator    ${host}    alias=${alias}
+    ${headers}=  Create Headers
+    ${data_path}=    Catenate    /        
+    ${resp}=   Get Request     ${alias}        ${PGN_PATH}     headers=${headers}
+    Should Be Equal As Strings    ${resp.status_code}    200
+    [Return]    ${resp.json()}
+    
+   
+Create Headers
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    [Return]    ${headers}     
\ No newline at end of file
diff --git a/robot/resources/stack_validation/policy_check_vfw.robot b/robot/resources/stack_validation/policy_check_vfw.robot
new file mode 100644 (file)
index 0000000..a1ed3fa
--- /dev/null
@@ -0,0 +1,95 @@
+*** Settings ***
+Documentation    Testing openstack.
+Library    OperatingSystem
+Library    Process
+Library    SSHLibrary
+Library    RequestsLibrary
+Library    JSONUtils
+Library    OpenstackLibrary
+Library    HEATUtils
+Library    Collections
+LIbrary    String
+Resource          ../../resources/openstack/keystone_interface.robot
+Resource          ../../resources/openstack/nova_interface.robot
+Resource          ../../resources/openstack/heat_interface.robot
+Resource          ../../resources/ssh/files.robot
+Resource          ../../resources/ssh/processes.robot
+Resource          packet_generator_interface.robot
+Resource          darkstat_interface.robot
+Resource          validate_common.robot
+
+
+*** Variables ***
+${ASSETS}              ${EXECDIR}/robot/assets/
+
+*** Keywords ***
+Policy Check Firewall Stack
+    [Documentation]    Identifies the firewall servers in the VFW Stack in the GLOBAL_OPENSTACK_SERVICE_REGION
+    [Arguments]    ${stack_name}    ${policy_rate}        
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${server_list}=    Get Openstack Servers    auth 
+    Log     ${server_list}
+    ${vpg_unprotected_ip}=    Get From Dictionary    ${stack_info}    vpg_private_ip_0
+    ${vsn_protected_ip}=    Get From Dictionary    ${stack_info}    vsn_private_ip_0
+    ${vpg_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vpg_name_0    network_name=public     
+    ${vsn_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vsn_name_0    network_name=public
+    ${upper_bound}=    Evaluate    ${policy_rate}*2
+    Wait Until Keyword Succeeds    300s    1s    Run VFW Policy Check    ${vpg_public_ip}   ${policy_rate}    ${upper_bound}    1
+
+Run VFW Policy Check
+    [Documentation]     Push traffic above upper bound, wait for policy to fix it, push traffic to lower bound, wait for policy to fix it, 
+    [Arguments]    ${vpg_public_ip}    ${policy_rate}    ${upper_bound}    ${lower_bound}
+    # Force traffic above threshold
+    Check For Policy Enforcement    ${vpg_public_ip}    ${policy_rate}    ${upper_bound}
+    # Force traffic below threshold
+    Check For Policy Enforcement    ${vpg_public_ip}    ${policy_rate}    ${lower_bound}
+
+Check For Policy Enforcement
+    [Documentation]     Push traffic above upper bound, wait for policy to fix it, push traffic to lower bound, wait for policy to fix it, 
+    [Arguments]    ${vpg_public_ip}    ${policy_rate}    ${forced_rate}
+    Enable Streams    ${vpg_public_ip}    ${forced_rate}
+    Wait Until Keyword Succeeds    20s    5s    Test For Expected Rate    ${vpg_public_ip}    ${forced_rate}
+    Wait Until Keyword Succeeds    280s    5s    Test For Expected Rate    ${vpg_public_ip}    ${policy_rate}
+
+Test For Expected Rate
+    [Documentation]    Ge the number of pg-streams from the PGN, and test to see if it is what we expect.    
+    [Arguments]    ${vpg_public_ip}    ${number_of_streams}
+    ${list}=    Get List Of Enabled Streams    ${vpg_public_ip}
+    ${list}=    Evaluate   ${list['sample-plugin']}['pg-streams']['pg-stream']
+    Length Should Be    ${list}    ${number_of_streams}     
+
+
+
+Policy Check vLB Stack
+    [Documentation]    Identifies the firewall servers in the VFW Stack in the GLOBAL_OPENSTACK_SERVICE_REGION
+    [Arguments]    ${stack_name}    ${policy_rate}        
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${server_list}=    Get Openstack Servers    auth 
+    ${vlb_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vlb_name_0    network_name=public     
+    ${upper_bound}=    Evaluate    ${policy_rate}*2
+    Start DNS Traffic    ${vlb_public_ip}    ${upper_bound}   
+
+    # Now wiat for the dnsscaling stack to be deployed
+    ${prefix}=    Get DNSScaling Prefix
+    ${dnsscaling}=    Replace String Using Regexp    ${stack_name}    ^Vfmodule_    ${prefix}    
+    ${dnsscaling_info}=    Wait for Stack to Be Deployed    auth    ${dnsscaling}
+    # TO DO: Log into vLB and cehck that traffic is flowing to the new DNS
+    [Return]    ${dnsscaling}   
+
+Get DNSScaling Prefix
+    ${mapping}=    Get From Dictionary   ${GLOBAL_SERVICE_TEMPLATE_MAPPING}   vLB
+    :for   ${dict}    in   @{mapping}
+    \    Return From Keyword If    '${dict['isBase']}' == 'false'    ${dict['prefix']}
+    [Return]   None
+    
+
+Start DNS Traffic
+    [Documentation]   Run nslookups at rate per second. Run for 10 minutes or until it is called by the terminate process
+    [Arguments]    ${vlb_public_ip}    ${rate}
+    ${pid}=   Start Process   ./dnstraffic.sh   ${vlb_public_ip}   ${rate}   ${GLOBAL_DNS_TRAFFIC_DURATION}
+    [Return]    ${pid} 
\ No newline at end of file
diff --git a/robot/resources/stack_validation/validate_common.robot b/robot/resources/stack_validation/validate_common.robot
new file mode 100644 (file)
index 0000000..eb7f9f5
--- /dev/null
@@ -0,0 +1,51 @@
+*** Settings ***
+Documentation    Testing openstack.
+Library    OperatingSystem
+Library    SSHLibrary
+Library    RequestsLibrary
+Library    JSONUtils
+Library    OpenstackLibrary
+Library    HEATUtils
+Library    Collections
+Resource          ../../resources/openstack/keystone_interface.robot
+Resource          ../../resources/openstack/nova_interface.robot
+Resource          ../../resources/openstack/heat_interface.robot
+Resource          ../../resources/ssh/files.robot
+Resource          ../../resources/ssh/processes.robot
+Resource          packet_generator_interface.robot
+
+
+*** Variables ***
+${ASSETS}              ${EXECDIR}/robot/assets/
+${VFW_STACK_NAME}    EcompETE_VFWStack
+${VLB_STACK_NAME}    EcompETE_VLBStack
+${DNS_STACK_NAME}    EcompETE_DNSStack
+
+*** Keywords ***
+Wait For Server
+    [Documentation]    Attempts to login to the passed server info and verify (??). Uses server info to get public ip and locate corresponding provate key file   
+    [Arguments]    ${server_ip}    ${timeout}=300s
+    ${file}=    Catenate    ${ASSETS}keys/robot_ssh_private_key.pvt
+    Wait Until Keyword Succeeds    ${timeout}    5 sec    Open Connection And Log In    ${server_ip}    root    ${file}
+    ${lines}=   Grep Local File    "Accepted publickey"    /var/log/auth.log    
+    Log    ${lines}            
+    Should Not Be Empty    ${lines}
+        
+Get Server Ip 
+    [Arguments]    ${server_list}    ${stack_info}    ${key_name}    ${network_name}=public
+    ${server_name}=   Get From Dictionary     ${stack_info}   ${key_name}
+    ${server}=    Get From Dictionary    ${server_list}    ${server_name}
+    Log    Entering Get Openstack Server Ip
+    ${ip}=    Get Openstack Server Ip    ${server}    network_name=${network_name} 
+    Log    Returned Get Openstack Server Ip
+    [Return]    ${ip}    
+
+Find And Reboot The Server
+    [Documentation]    Code to reboot the server by teh heat server name parameter value    
+    [Arguments]    ${stack_info}    ${server_list}    ${server_name_parameter}
+    ${server_name}=   Get From Dictionary     ${stack_info}   ${server_name_parameter}
+    ${vfw_server}=    Get From Dictionary    ${server_list}    ${server_name}
+    ${vfw_server_id}=    Get From Dictionary    ${vfw_server}    id
+    Reboot Server    auth   ${vfw_server_id}
+        
+    
diff --git a/robot/resources/stack_validation/validate_dns_scaling.robot b/robot/resources/stack_validation/validate_dns_scaling.robot
new file mode 100644 (file)
index 0000000..f63479e
--- /dev/null
@@ -0,0 +1,43 @@
+*** Settings ***
+Documentation    Testing openstack.
+Library    OperatingSystem
+Library    SSHLibrary
+Library    RequestsLibrary
+Library    JSONUtils
+Library    OpenstackLibrary
+Library    HEATUtils
+Library    Collections
+Resource          ../../resources/openstack/keystone_interface.robot
+Resource          ../../resources/openstack/nova_interface.robot
+Resource          ../../resources/openstack/heat_interface.robot
+Resource          ../../resources/ssh/files.robot
+Resource          ../../resources/ssh/processes.robot
+Resource          packet_generator_interface.robot
+Resource          validate_common.robot
+
+
+*** Variables ***
+${ASSETS}              ${EXECDIR}/robot/assets/
+
+*** Keywords ***
+Validate Dns Scaling Stack
+    [Documentation]    Identifies the servers in the STACK_NAME in the GLOBAL_OPENSTACK_SERVICE_REGION
+    [Arguments]    ${STACK_NAME}    
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${STACK_NAME}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${server_list}=    Get Openstack Servers    auth 
+    Log     ${server_list}
+    #${vpg_unprotected_ip}=    Get From Dictionary    ${stack_info}    vpg_private_ip_0
+    #${vsn_protected_ip}=    Get From Dictionary    ${stack_info}    vsn_private_ip_0
+    ${vdns_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vdns_name_0    network_name=public     
+    Wait For Server    ${vdns_public_ip}
+    Log    Accessed all servers
+    #Wait for vDNS    ${vdns_public_ip}
+    Log    All server processes up
+
+Wait For vDNS
+    [Documentation]     Wait for the defined firewall processes to come up
+    [Arguments]    ${ip}    
+    Wait for Process on Host    java DNSServer     ${ip}    
+
diff --git a/robot/resources/stack_validation/validate_vfw.robot b/robot/resources/stack_validation/validate_vfw.robot
new file mode 100644 (file)
index 0000000..51f29b4
--- /dev/null
@@ -0,0 +1,94 @@
+*** Settings ***
+Documentation    Testing openstack.
+Library    OperatingSystem
+Library    SSHLibrary
+Library    RequestsLibrary
+Library    JSONUtils
+Library    OpenstackLibrary
+Library    HEATUtils
+Library    Collections
+Resource          ../../resources/openstack/keystone_interface.robot
+Resource          ../../resources/openstack/nova_interface.robot
+Resource          ../../resources/openstack/heat_interface.robot
+Resource          ../../resources/ssh/files.robot
+Resource          ../../resources/ssh/processes.robot
+Resource          ../appc_interface.robot
+Resource          packet_generator_interface.robot
+Resource          validate_common.robot
+
+
+*** Variables ***
+${ASSETS}              ${EXECDIR}/robot/assets/
+
+*** Keywords ***
+Validate Firewall Stack
+    [Documentation]    Identifies the firewall servers in the VFW Stack in the GLOBAL_OPENSTACK_SERVICE_REGION
+    [Arguments]    ${STACK_NAME}    
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${STACK_NAME}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${server_list}=    Get Openstack Servers    auth 
+
+    ${vpg_unprotected_ip}=    Get From Dictionary    ${stack_info}    vpg_private_ip_0
+    ${vsn_protected_ip}=    Get From Dictionary    ${stack_info}    vsn_private_ip_0
+    ${vpg_name_0}=    Get From Dictionary    ${stack_info}    vpg_name_0
+    ${vfw_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vfw_name_0    network_name=public     
+    ${vpg_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vpg_name_0    network_name=public     
+    ${vsn_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vsn_name_0    network_name=public     
+    
+    Wait For Server    ${vfw_public_ip}
+    Wait For Server    ${vpg_public_ip}
+    Wait For Server    ${vsn_public_ip}
+    Log    Accessed all servers
+    Wait For Firewall    ${vfw_public_ip}        
+    Wait For Packet Generator    ${vpg_public_ip}      
+    Wait For Packet Sink    ${vsn_public_ip}        
+    Log    All server processes up
+    ${appc}=    Create Mount Point In APPC    ${vpg_name_0}    ${vpg_public_ip}
+
+    # Following hack was implemented because the stack doesn't always come up clean
+    # It was found that rebooting the servers at this point did not improve the
+    # chances of the packets flowing to the SNK 
+    #${status}    ${data}=    Run Keyword And Ignore Error    Wait For Packets   ${vpg_public_ip}   ${vpg_unprotected_ip}   ${vsn_protected_ip}   ${vsn_public_ip}
+    #Return From Keyword if    '${status}' == 'PASS'
+    #Close All Connections
+    #Find And Reboot The Server    ${stack_info}    ${server_list}    vfw_name_0 
+    #Find And Reboot The Server    ${stack_info}    ${server_list}    vpg_name_0 
+    #Find And Reboot The Server    ${stack_info}    ${server_list}    vsn_name_0
+    ## Gives some time for servers to shutdown 
+    #Sleep    10s 
+    #Wait For Server    ${vfw_public_ip}
+    #Wait For Server    ${vpg_public_ip}
+    #Wait For Server    ${vsn_public_ip}
+
+    Wait For Packets   ${vpg_public_ip}   ${vpg_unprotected_ip}   ${vsn_protected_ip}   ${vsn_public_ip}
+    
+Wait For Packets
+    [Documentation]    Final vfw validation that packets are flowing from the pgn VM  to the snk VM
+    [Arguments]   ${vpg_public_ip}   ${vpg_unprotected_ip}   ${vsn_protected_ip}   ${vsn_public_ip}             
+    ${resp}=    Enable Stream    ${vpg_public_ip}
+    Should Be Equal As Strings    ${resp.status_code}    200
+    ${syslog_message}=    Catenate    UDP: short packet: From ${vpg_unprotected_ip}:.* to ${vsn_protected_ip}:.* 
+    Tail File on Host Until    ${vsn_public_ip}    UDP:    /var/log/syslog    ${syslog_message}    timeout=120s
+    Disable All Streams    ${vpg_public_ip}    
+
+
+Wait For Firewall
+    [Documentation]     Wait for the defined firewall processes to come up
+    [Arguments]    ${ip}    
+    Wait for Process on Host    ./vpp_measurement_reporter    ${ip}    
+    Wait for Process on Host    vpp -c /etc/vpp/startup.conf    ${ip}    
+
+Wait For Packet Generator
+    [Documentation]     Wait for the defined packet generator processes to come up
+    [Arguments]    ${ip}    
+    Wait for Process on Host    vpp -c /etc/vpp/startup.conf    ${ip}    
+    Wait for Process on Host    java .* -jar /opt/honeycomb/Honeycomb/vpp-integration/minimal-distribution/target/vpp-integration-distribution-1.16.9-hc/vpp-integration-distribution-1.16.9/vpp-integration-distribution-1.16.9.jar    ${ip}    
+    Wait Until Keyword Succeeds    180s    5s    Tail File on Host Until    ${ip}    Honeycomb    /var/log/honeycomb/honeycomb.log    - Honeycomb initialized   options=-c +0    timeout=120s
+    Run Keyword And Ignore Error    Wait for Process on Host    run_traffic_fw_demo.sh    ${ip}    timeout=60s  
+    Pkill Process On Host    "/bin/bash ./run_traffic_fw_demo.sh"    ${ip}
+    
+Wait For Packet Sink
+    [Documentation]     Wait for the defined packet sink processes to come up
+    [Arguments]    ${ip}
+    Log    noting to check on ${ip}    
diff --git a/robot/resources/stack_validation/validate_vlb.robot b/robot/resources/stack_validation/validate_vlb.robot
new file mode 100644 (file)
index 0000000..9af768f
--- /dev/null
@@ -0,0 +1,60 @@
+*** Settings ***
+Documentation    Testing openstack.
+Library    String
+Library    DNSUtils
+Library    Collections
+Library    SSHLibrary
+Resource          validate_common.robot
+
+
+*** Variables ***
+${ASSETS}              ${EXECDIR}/robot/assets/
+
+*** Keywords ***
+Validate vLB Stack
+    [Documentation]    Identifies the LB and DNS servers in the vLB stack in the GLOBAL_OPENSTACK_SERVICE_REGION
+    [Arguments]    ${stack_name}    
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${server_list}=    Get Openstack Servers    auth 
+    Log     Returned from Get Openstack Servers
+
+    #${vpg_unprotected_ip}=    Get From Dictionary    ${stack_info}    vpg_private_ip_0
+    #${vsn_protected_ip}=    Get From Dictionary    ${stack_info}    vsn_private_ip_0
+    ${vlb_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vlb_name_0    network_name=public     
+    ##${vdns_public_ip}=    Get Server Ip    ${server_list}    ${stack_info}   vdns_name_0    network_name=public     
+
+# SCript hands right here. Trying to figure out what it is....    
+    #Wait For Server    ${vlb_public_ip}
+    #Wait For Server    ${vdns_public_ip}
+    #Log    Accessed all servers
+    
+
+    # Following is a hack because the stack doesn't always come up clean
+    # Give some time for VLB server to reconfigure the network so our script doesn't hang
+    Log     Waiting for ${vlb_public_ip} to reconfigure
+    Sleep   180s
+    #${status}    ${data}=    Run Keyword And Ignore Error    Wait For vLB    ${vlb_public_ip}
+    #Return From Keyword if    '${status}' == 'PASS'
+    #Close All Connections
+    #Find And Reboot The Server    ${stack_info}    ${server_list}    vlb_name_0 
+
+    # Give some time for VLB server to reconfigure the network so our script doesn't hang
+    #Log     Waiting for ${vlb_public_ip} to reconfigure
+    #Sleep   180s
+       Wait For vLB    ${vlb_public_ip}        
+    Log    All server processes up
+
+Wait For vLB
+    [Documentation]     Wait for the VLB to be functioning as a DNS 
+    [Arguments]    ${ip}    
+    Wait Until Keyword Succeeds    300s    10s    DNSTest    ${ip}    
+    Log  Succeeded
+    
+DNSTest
+    [Documentation]     Wait for the defined VLoadBalancer to process nslookup
+    [Arguments]    ${ip}
+    Log   Looking up ${ip}    
+    #${returned_ip}=     Dns Request    host1.dnsdemo.openecomp.org    ${ip}
+    #Should Contain    '${returned_ip}'    .
diff --git a/robot/resources/stack_validation/validate_vvg.robot b/robot/resources/stack_validation/validate_vvg.robot
new file mode 100644 (file)
index 0000000..75340a4
--- /dev/null
@@ -0,0 +1,17 @@
+*** Settings ***
+Documentation    Testing openstack.
+Library    String
+Library    DNSUtils
+Library    Collections
+Resource          validate_common.robot
+
+
+*** Variables ***
+${ASSETS}              ${EXECDIR}/robot/assets/
+
+*** Keywords ***
+Validate vVG Stack 
+    [Documentation]    Identifies the LB and DNS servers in the vLB stack in the GLOBAL_OPENSTACK_SERVICE_REGION
+    [Arguments]    ${stack_name}    
+    Log    All server processes up
+
diff --git a/robot/resources/test_templates/closedloop_test_template.robot b/robot/resources/test_templates/closedloop_test_template.robot
new file mode 100644 (file)
index 0000000..67bf0cb
--- /dev/null
@@ -0,0 +1,210 @@
+*** Settings ***
+Documentation    Policy Closed Loop Test cases
+
+Resource          ../policy_interface.robot
+Resource        ../stack_validation/policy_check_vfw.robot
+Resource        vnf_orchestration_test_template.robot
+Library    String
+Library    HttpLibrary.HTTP
+LIbrary    Process
+
+*** Variables ***
+${RESOURCE_PATH_CREATE}        /PyPDPServer/createPolicy
+${RESOURCE_PATH_CREATE_PUSH}        /PyPDPServer/pushPolicy
+${RESOURCE_PATH_CREATE_DELETE}        /PyPDPServer/deletePolicy
+${RESOURCE_PATH_GET_CONFIG}    /PyPDPServer/getConfig
+${CREATE_CONFIG_TEMPLATE}    robot/assets/templates/policy/closedloop_configpolicy.template
+${CREATE_OPS_TEMPLATE}    robot/assets/templates/policy/closedloop_opspolicy.template
+${PUSH_POLICY_TEMPLATE}   robot/assets/templates/policy/closedloop_pushpolicy.template
+${DEL_POLICY_TEMPLATE}   robot/assets/templates/policy/closedloop_deletepolicy.template
+${GECONFIG_VFW_TEMPLATE}    robot/assets/templates/policy/closedloop_getconfigpolicy.template
+
+# 'Normal' number of pg streams that will be set when policy is triggered
+${VFWPOLICYRATE}    5
+
+# Max nslookup requests per second before triggering event.
+${VLBPOLICYRATE}    20
+
+${CONFIG_POLICY_NAME}    vFirewall    
+${CONFIG_POLICY_TYPE}    Unknown    
+${OPS_POLICY_NAME}    
+${OPS_POLICY_TYPE}    BRMS_PARAM
+
+# VFW low threshold
+${Expected_Severity_1}    MAJOR
+${Expected_Threshold_1}    300
+${Expected_Direction_1}    LESS_OR_EQUAL
+
+# VFW high threshold
+${Expected_Severity_2}    CRITICAL
+${Expected_Threshold_2}    700
+${Expected_Direction_2}    GREATER_OR_EQUAL
+
+# VDNS High threshold
+${Expected_Severity_3}    MAJOR
+${Expected_Threshold_3}    200
+${Expected_Direction_3}    GREATER_OR_EQUAL
+
+${DNSSCALINGSTACK}    
+
+*** Keywords ***
+VFW Policy
+    Log    Suite name ${SUITE NAME} ${TEST NAME} ${PREV TEST NAME}
+    Initialize VFW Policy
+    ${stackname}=   Orchestrate VNF vFW closedloop 
+    Policy Check Firewall Stack    ${stackname}    ${VFWPOLICYRATE}
+    
+
+VDNS Policy
+    Initialize VDNS Policy
+    ${stackname}=   Orchestrate VNF vDNS closedloop
+    ${dnsscaling}=   Policy Check vLB Stack    ${stackname}    ${VLBPOLICYRATE}
+    Set Test Variable   ${DNSSCALINGSTACK}   ${dnsscaling}
+      
+Initialize VFW Policy
+#    Create Config Policy
+#    Push Config Policy    ${CONFIG_POLICY_NAME}    ${CONFIG_POLICY_TYPE}
+#    Create Ops Policy
+#    Push Ops Policy    ${OPS_POLICY_NAME}    ${OPS_POLICY_TYPE} 
+     Get Configs VFW Policy
+     
+Initialize VDNS Policy
+    Get Configs VDNS Policy
+      
+Get Configs VFW Policy
+    [Documentation]    Get Config Policy for VFW
+    ${getconfigpolicy}=    Catenate    .*${CONFIG_POLICY_NAME}*
+    ${configpolicy_name}=    Create Dictionary    config_policy_name=${getconfigpolicy}
+    ${output} =     Fill JSON Template File     ${GECONFIG_VFW_TEMPLATE}    ${configpolicy_name}
+    ${get_resp} =    Run Policy Get Configs Request    ${RESOURCE_PATH_GET_CONFIG}   ${output}
+       Should Be Equal As Strings      ${get_resp.status_code}         200
+       
+       ${json}=    Parse Json    ${get_resp.content}
+    ${config}=    Parse Json    ${json[0]["config"]}
+       
+    # Extract object1 from Array  
+    ${severity}=    Get Variable Value      ${config["content"]["thresholds"][0]["severity"]}
+    Should Be Equal    ${severity}    ${Expected_Severity_1}  
+    ${Thresold_Value}=    Get Variable Value      ${config["content"]["thresholds"][0]["thresholdValue"]}
+    Should Be Equal   ${Thresold_Value}    ${Expected_Threshold_1} 
+    ${direction}=    Get Variable Value      ${config["content"]["thresholds"][0]["direction"]}
+    Should Be Equal   ${direction}    ${Expected_Direction_1} 
+    
+    # Extract object2 from Array
+    ${severity_1}=    Get Variable Value      ${config["content"]["thresholds"][1]["severity"]}
+    Should Be Equal    ${severity_1}    ${Expected_Severity_2}  
+    ${Thresold_Value_1}=    Get Variable Value      ${config["content"]["thresholds"][1]["thresholdValue"]}
+    Should Be Equal   ${Thresold_Value_1}    ${Expected_Threshold_2} 
+    ${direction_1}=    Get Variable Value      ${config["content"]["thresholds"][1]["direction"]}
+    Should Be Equal   ${direction_1}    ${Expected_Direction_2}   
+    
+Get Configs VDNS Policy
+    [Documentation]    Get Config Policy for VDNS
+    ${getconfigpolicy}=    Catenate    .*vLoadBalancer*
+    ${configpolicy_name}=    Create Dictionary    config_policy_name=${getconfigpolicy}
+    ${output} =     Fill JSON Template File     ${GECONFIG_VFW_TEMPLATE}    ${configpolicy_name}
+    ${get_resp} =    Run Policy Get Configs Request    ${RESOURCE_PATH_GET_CONFIG}   ${output}
+       Should Be Equal As Strings      ${get_resp.status_code}         200
+    ${json}=    Parse Json    ${get_resp.content}
+    ${config}=    Parse Json    ${json[0]["config"]}
+       
+    # Extract object1 from Array  
+    ${severity}=    Get Variable Value      ${config["content"]["thresholds"][0]["severity"]}
+    Should Be Equal    ${severity}    ${Expected_Severity_3}  
+    ${Thresold_Value}=    Get Variable Value      ${config["content"]["thresholds"][0]["thresholdValue"]}
+    Should Be Equal   ${Thresold_Value}    ${Expected_Threshold_3} 
+    ${direction}=    Get Variable Value      ${config["content"]["thresholds"][0]["direction"]}
+    Should Be Equal   ${direction}    ${Expected_Direction_3} 
+
+Teardown Closed Loop
+    [Documentation]   Tear down a closed loop test case
+    Terminate All Processes 
+    Teardown VDNS
+    Teardown VNF   
+    #Clean A&AI Inventory    VFWPolicy_Customer   Rackspece    vFW   
+#    Delete Config Policy    ${CONFIG_POLICY_NAME}
+#    Delete Ops Policy    ${OPS_POLICY_NAME}  
+    Log     Teardown complete  
+
+Teardown VDNS
+    Return From Keyword if    '${DNSSCALINGSTACK}' == ''
+    # This needs to be done via VID
+    Teardown Stack    ${DNSSCALINGSTACK}
+
+Create Config Policy
+    [Documentation]    Create Config Policy 
+    ${randompolicyname} =     Create Policy Name  
+    ${policyname1}=    Catenate   com.${randompolicyname}
+    ${CONFIG_POLICY_NAME}=    Set Test Variable    ${policyname1}            
+    ${configpolicy}=    Create Dictionary    policy_name=${CONFIG_POLICY_NAME}
+    ${output} =     Fill JSON Template File     ${CREATE_CONFIG_TEMPLATE}    ${configpolicy}
+    ${put_resp} =    Run Policy Put Request    ${RESOURCE_PATH_CREATE}  ${output}
+       Should Be Equal As Strings      ${put_resp.status_code}         200
+
+ Create Policy Name
+     [Documentation]    Generate Policy Name
+     [Arguments]    ${prefix}=ETE_ 
+     ${random}=    Generate Random String    15    [LOWER][NUMBERS]
+     ${policyname}=    Catenate    ${prefix}${random}
+     [Return]    ${policyname}
+     
+Create Ops Policy
+       [Documentation]    Create Opertional Policy 
+       ${randompolicyname} =     Create Policy Name  
+       ${policyname1}=    Catenate   com.${randompolicyname}
+       ${OPS_POLICY_NAME}=    Set Test Variable    ${policyname1}            
+       ${dict}=     Create Dictionary    policy_name=${OPS_POLICY_NAME}
+       #${NEWPOLICY1}=     Create Dictionary    policy_name=com.${OPS_POLICY_NAME}
+       ${output} =     Fill JSON Template File     ${CREATE_OPS_TEMPLATE}    ${dict}
+    ${put_resp} =    Run Policy Put Request    ${RESOURCE_PATH_CREATE}  ${output}
+    Log    ${put_resp}
+    Should Be Equal As Strings         ${put_resp.status_code}         200
+           
+Push Ops Policy
+    [Documentation]    Push Ops Policy
+    [Arguments]    ${policyname}    ${policytype}
+    ${dict}=     Create Dictionary     policy_name=${policyname}    policy_type=${policytype} 
+       ${output} =     Fill JSON Template     ${PUSH_POLICY_TEMPLATE}     ${dict}
+    ${put_resp} =    Run Policy Put Request    ${RESOURCE_PATH_CREATE_PUSH}  ${output}
+    Should Be Equal As Strings         ${put_resp.status_code}         200
+
+Push Config Policy
+    [Documentation]    Push Config Policy
+    [Arguments]    ${policyname}    ${policytype}
+    ${dict}=     Create Dictionary     policy_name=${policyname}    policy_type=${policytype} 
+       ${output} =     Fill JSON Template     ${PUSH_POLICY_TEMPLATE}     ${dict}
+    ${put_resp} =    Run Policy Put Request    ${RESOURCE_PATH_CREATE_PUSH}  ${output}
+    Should Be Equal As Strings         ${put_resp.status_code}         200
+           
+Delete Config Policy
+    [Documentation]    Delete Config Policy
+    [Arguments]    ${policy_name}
+    ${policyname3}=    Catenate   com.Config_BRMS_Param_${policyname}.1.xml
+    ${dict}=     Create Dictionary     policy_name=${policyname3} 
+       ${output} =     Fill JSON Template     ${DEL_POLICY_TEMPLATE}     ${dict}
+    ${put_resp} =    Run Policy Delete Request    ${RESOURCE_PATH_CREATE_DELETE}  ${output}
+    Should Be Equal As Strings         ${put_resp.status_code}         200         
+           
+Delete Ops Policy
+    [Documentation]    Delete Ops Policy
+    [Arguments]    ${policy_name}
+    ${policyname3}=    Catenate   com.Config_MS_com.vFirewall.1.xml
+    ${dict}=     Create Dictionary     policy_name=${policyname3} 
+       ${output} =     Fill JSON Template     ${DEL_POLICY_TEMPLATE}     ${dict}
+    ${put_resp} =    Run Policy Delete Request    ${RESOURCE_PATH_CREATE_DELETE}  ${output}
+    Should Be Equal As Strings         ${put_resp.status_code}         200     
+           
+Orchestrate VNF vFW closedloop
+       [Documentation]    VNF Orchestration for vFW
+       Log    VNF Orchestration flow TEST NAME=${TEST NAME} 
+       Setup Orchestrate VNF    ${GLOBAL_AAI_CLOUD_OWNER}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    SharedNode    OwnerType    v1    CloudZone    
+       ${stack_name}    ${service}=  Orchestrate VNF   ETE_CLP    vFW      vFW             ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${TENANT_NAME}    
+       [Return]  ${stack_name}  
+      
+ Orchestrate VNF vDNS closedloop
+       [Documentation]    VNF Orchestration for vLB
+       Log    VNF Orchestration flow TEST NAME=${TEST NAME} 
+       Setup Orchestrate VNF    ${GLOBAL_AAI_CLOUD_OWNER}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    SharedNode    OwnerType    v1    CloudZone    
+       ${stack_name}    ${service}=  Orchestrate VNF   ETE_CLP    vLB      vLB             ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${TENANT_NAME}    
+       [Return]  ${stack_name}  
diff --git a/robot/resources/test_templates/model_test_template.robot b/robot/resources/test_templates/model_test_template.robot
new file mode 100644 (file)
index 0000000..263c592
--- /dev/null
@@ -0,0 +1,57 @@
+*** Settings ***
+Documentation     The main interface for interacting with ASDC. It handles low level stuff like managing the http request library and DCAE required fields
+Library           OperatingSystem
+Library            ArchiveLibrary
+Library           Collections   
+Resource          ../asdc_interface.robot
+
+Variables       ../../assets/service_mappings.py
+
+*** Variables ***
+${ASDC_BASE_PATH}    /sdc1
+${ASDC_DESIGNER_PATH}    /proxy-designer1#/dashboard
+${ASDC_ASSETS_DIRECTORY}    robot/assets/asdc
+${VFW_DIRECTORY}    base_vfw
+${VLB_DIRECTORY}    base_vlb
+${VVG_DIRECTORY}    base_vvg
+${SCALING_DIRECTORY}    dns_scaling
+${ASDC_ZIP_DIRECTORY}    ${ASDC_ASSETS_DIRECTORY}/temp
+
+${CATALOG_RESOURCE_IDS}    
+${CATALOG_SERVICE_ID}   
+
+*** Keywords ***
+
+Model Distribution For Directory
+    [Arguments]    ${service}
+    ${directory_list}=    Get From Dictionary    ${GLOBAL_SERVICE_FOLDER_MAPPING}    ${service}
+    ${ziplist}=    Create List
+    :for   ${directory}    in    @{directory_list}
+    \    ${zip}=    Catenate    ${ASDC_ZIP_DIRECTORY}/${directory}.zip
+    \    ${folder}=    Catenate    ${ASDC_ASSETS_DIRECTORY}/${directory}         
+    \    OperatingSystem.Create Directory    ${ASDC_ASSETS_DIRECTORY}/temp
+    \    Create Zip From Files In Directory        ${folder}    ${zip}
+    \    Append To List    ${ziplist}    ${zip}    
+    ${catalog_service_name}    ${catalog_resource_name}    ${vf_modules}    ${catalog_resource_ids}   ${catalog_service_id}   Distribute Model From ASDC    ${ziplist}
+    Set Test Variable   ${CATALOG_RESOURCE_IDS}   ${catalog_resource_ids}
+    Set Test Variable   ${CATALOG_SERVICE_ID}   ${catalog_service_id}
+    [Return]    ${catalog_service_name}    ${catalog_resource_name}    ${vf_modules}        
+             
+
+
+
+Teardown Model Distribution
+    [Documentation]    Clean up at the end of the test
+    Log   ${CATALOG_SERVICE_ID} ${CATALOG_RESOURCE_IDS}  
+    Teardown Models    ${CATALOG_SERVICE_ID}   ${CATALOG_RESOURCE_IDS}    
+        
+Teardown Models
+    [Documentation]    Clean up at the end of the test
+    [Arguments]     ${catalog_service_id}    ${catalog_resource_ids}
+    Return From Keyword If    '${catalog_service_id}' == ''
+    :for    ${catalog_resource_id}   in   @{catalog_resource_ids}
+    \   ${resourece_json}=   Mark ASDC Catalog Resource Inactive    ${catalog_resource_id}    
+    ${service_json}=   Mark ASDC Catalog Service Inactive    ${catalog_service_id}
+    ${services_json}=   Delete Inactive ASDC Catalog Services
+    ${resources_json}=    Delete Inactive ASDC Catalog Resources
+                     
\ No newline at end of file
diff --git a/robot/resources/test_templates/vnf_orchestration_test_template.robot b/robot/resources/test_templates/vnf_orchestration_test_template.robot
new file mode 100644 (file)
index 0000000..00f15cf
--- /dev/null
@@ -0,0 +1,183 @@
+*** Settings ***
+Documentation    This test template encapsulates the VNF Orchestration use case. 
+
+Resource        ../vid/create_service_instance.robot
+Resource        ../vid/vid_interface.robot
+Resource        ../aai/service_instance.robot
+Resource        ../vid/create_vid_vnf.robot
+Resource        ../sdngc_interface.robot
+Resource        model_test_template.robot
+
+Resource        ../aai/create_customer.robot
+Resource        ../aai/create_tenant.robot
+Resource        ../aai/create_service.robot
+Resource        ../openstack/neutron_interface.robot
+Resource        ../heatbridge.robot
+
+
+Library         OpenstackLibrary
+Library            ExtendedSelenium2Library
+Library                UUID
+Library                Collections
+
+
+
+*** Variables ***
+
+${TENANT_NAME}    
+${TENANT_ID}
+${REGIONS}
+${CUSTOMER_NAME}
+${STACK_NAME}
+${SERVICE} 
+${VVG_SERVER_ID}
+
+*** Keywords ***     
+Orchestrate VNF
+    [Arguments]    ${customer_name}    ${service}    ${product_family}    ${lcp_region}    ${tenant}
+    ${uuid}=    Generate UUID  
+    Set Test Variable    ${CUSTOMER_NAME}    ${customer_name}_${uuid}
+    Set Test Variable    ${SERVICE}    ${service}
+    ${vnf_name}=    Catenate    Vnf_Ete_Name${uuid}       
+    ${service_name}=    Catenate    Service_Ete_Name${uuid}
+    ${service_type}=    Set Variable    ${service}
+    ${vf_module_name}=    Catenate    Vfmodule_Ete_Name${uuid}
+    ${service_model_type}     ${vnf_type}    ${vf_modules} =    Model Distribution For Directory    ${service}
+    ## MSO polling is 60 second intervals
+    Sleep    70s     
+    Run Keyword If   '${service}' == 'vVG'    Create VVG Server    ${uuid}  
+    Create Customer For VNF    ${CUSTOMER_NAME}    ${CUSTOMER_NAME}    INFRA    ${service_type}    ${GLOBAL_AAI_CLOUD_OWNER}    ${GLOBAL_OPENSTACK_SERVICE_REGION}        
+    Setup Browser   
+    Login To VID GUI
+    ${service_instance_id}=    Create VID Service Instance    ${customer_name}    ${service_model_type}    ${service}     ${service_name}
+    Validate Service Instance    ${service_instance_id}    ${service}      ${customer_name}     
+    Create VID VNF    ${service_instance_id}    ${vnf_name}    ${product_family}    ${lcp_region}    ${tenant}    ${vnf_type}
+    ${vf_module_type}   ${closedloop_vf_module}=   Preload Vnf    ${service_instance_id}   ${vnf_name}   ${vnf_type}   ${vf_module_name}    ${vf_modules}    ${service}    ${uuid}
+    ${vf_module_id}=   Create VID VNF module    ${service_instance_id}    ${vf_module_name}    ${lcp_region}    ${tenant}     ${vf_module_type}
+    ${generic_vnf}=   Validate Generic VNF    ${vnf_name}    ${vnf_type}    ${service_instance_id}
+    VLB Closed Loop Hack   ${service}   ${generic_vnf}   ${closedloop_vf_module}      
+    Set Test Variable    ${STACK_NAME}   ${vf_module_name}         
+    Execute Heatbridge    ${vf_module_name}    ${service_instance_id}    ${service}
+    Validate VF Module      ${vf_module_name}    ${service}
+    [Return]     ${vf_module_name}    ${service}
+    [Teardown]    Close All Browsers
+
+
+Create Customer For VNF
+    [Documentation]    VNF Orchestration Test setup....
+    ...                Create Tenant if not exists, Create Customer, Create Service and related relationships
+    [Arguments]    ${customer_name}    ${customer_id}    ${customer_type}    ${service_type}    ${cloud_owner}  ${cloud_region_id}         
+    ${resp}=    Create Customer    ${customer_name}    ${customer_id}    ${customer_type}    ${service_type}   ${cloud_owner}  ${cloud_region_id}    ${TENANT_ID}      
+       Should Be Equal As Strings      ${resp}         201
+    Create Service If Not Exists    ${service_type}
+
+Setup Orchestrate VNF
+    [Documentation]    Called before each test case to ensure data required by the Orchstrate VNF exists 
+    [Arguments]        ${cloud_owner}  ${cloud_region_id}   ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}
+    Initialize Tenant From Openstack
+    Initialize Regions From Openstack
+    :FOR    ${region}    IN    @{REGIONS}
+    \    Inventory Tenant If Not Exists    ${cloud_owner}  ${region}  ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}    ${TENANT_NAME}    ${TENANT_ID}       
+    Log   Orchestrate VNF setup complete    
+        
+Initialize Tenant From Openstack
+    Run Openstack Auth Request    auth
+    ${tenants}=    Get Current Openstack Tenant     auth
+    ${tenant_name}=    Evaluate    $tenants.get("name")
+    ${tenant_id}=     Evaluate    $tenants.get("id")  
+    Set Suite Variable ${TENANT_NAME}   ${tenant_name}
+    Set Suite Variable ${TENANT_ID}     ${tenant_id}   
+
+Initialize Regions From Openstack
+    Run Openstack Auth Request    auth
+    ${regs}=    Get Openstack Regions    auth
+    Set Suite Variable ${REGIONS}     ${regs} 
+
+Create VVG Server
+    [Arguments]    ${uuid}            
+    Run Openstack Auth Request    auth
+    ${vvg_server_name}=    Catenate   vVG_${uuid}
+    ${server}=   Add Server For Image Name  auth    ${vvg_server_name}   ${GLOBAL_VVGSERVER_IMAGE}   ${GLOBAL_VVGSERVER_FLAVOR}
+    ${server}=       Get From Dictionary   ${server}   server
+    ${server_id}=    Get From Dictionary   ${server}   id
+    Set Test Variable    ${VVG_SERVER_ID}   ${server_id}
+    ${vvg_params}=    Get VVG Preload Parameters 
+    Set To Dictionary   ${vvg_params}   nova_instance   ${server_id}
+    Wait for Server to Be Active    auth    ${server_id}    
+
+Get VVG Preload Parameters    
+    ${test_dict}=    Get From Dictionary    ${GLOBAL_PRELOAD_PARAMETERS}    Vnf-Orchestration
+    ${vvg_params}   Get From Dictionary    ${test_dict}    vvg_preload.template
+    [Return]    ${vvg_params}
+       
+Teardown VNF
+    [Documentation]    Called at the end of a test case to tear down the VNF created by Orchestrate VNF
+    Teardown VVG Server  
+    # Free up rackspace resources until true teardown is implemented
+    Run Keyword If   '${TEST STATUS}' == 'PASS'    Teardown Stack   ${STACK_NAME}
+    Set Test Variable     ${VVG_SERVER_ID}   ''
+    
+    ## Conditional remove so as to enable manual teardown testing of failed stacks
+    Run Keyword If   '${TEST STATUS}' == 'PASS'    Teardown Model Distribution  
+    Log    Teardown VNF not completely implemented
+
+Teardown VVG Server
+    Return From Keyword if   '${VVG_SERVER_ID}' == ''
+    Delete Server   auth   ${VVG_SERVER_ID}
+    Wait for Server To Be Deleted    auth    ${VVG_SERVER_ID}    
+    ${vvg_params}=    Get VVG Preload Parameters   
+    Remove from Dictionary   ${vvg_params}   nova_instance
+    Log    Teardown VVG Server Completed
+    
+Teardown Stack
+    [Documentation]    Called at the end of a test case to tear down the Stack created by Orchestrate VNF
+    [Arguments]   ${stack}
+    Run Openstack Auth Request    auth
+    ${stack_info}=    Get Stack Details    auth    ${stack}
+    Log    ${stack_info}
+    ${stack_id}=    Get From Dictionary    ${stack_info}    id
+    ${key_pair_status}   ${keypair_name}=   Run Keyword And Ignore Error   Get From Dictionary    ${stack_info}    key_name
+    Delete Openstack Stack      auth    ${stack}    ${stack_id}
+    Log    Deleted ${stack} ${stack_id}
+    Run Keyword If   '${key_pair_status}' == 'PASS'   Delete Openstack Keypair    auth    ${keypair_name}
+    ## Removed  code to remove all of the IPs from the oam network - didn't help
+
+
+Get Ecomp Private Net Ports
+    [Arguments]    ${alias}    ${stack_info}    ${service}
+    ${list}=    Create List
+    ${netid}=    Get From Dictionary    ${stack_info}    ecomp_private_net_id
+    ${cidr}=    Get From Dictionary    ${stack_info}    ecomp_private_net_cidr
+    ${ip_addresses}=    Get Ecomp Ip Addresses    ${stack_info}    ${service}
+    ${net_ports}=    Get Openstack Ports For Subnet    ${alias}    ${netid}    ${cidr}
+    :for    ${ip_address}    in    @{ip_addresses}
+    \    ${port}=    Find Ecomp Port     ${net_ports}    ${ip_address}
+    \     Run Keyword If    ${port} is not None    Append To List    ${list}    ${port}        
+    [Return]    ${list}
+    
+Get Ecomp Ip Addresses
+    [Arguments]    ${stack_info}    ${service}
+    ${ip_addresses}=    Create List
+    ${names}=    Get From Dictionary    ${GLOBAL_SERVICE_ECOMP_IP_MAPPING}    ${service}
+    :for    ${name}    in    @{names}
+    \    ${ip}=    Get From Dictionary    ${stack_info}    ${name}
+    \    Append To List    ${ip_addresses}    ${ip}
+    [Return]    ${ip_addresses}
+
+Find Ecomp Port
+    [Arguments]    ${ports}    ${ip_address}
+   :for    ${port}   in   @{ports}
+    \    Return From Keyword If    '${port['fixed_ips'][0]['ip_address']}' == '${ip_address}'    ${port}
+    [Return]    None
+
+Clean A&AI Inventory 
+    [Documentation]    Clean up Tenant in A&AI, Create Customer, Create Service and related relationships      
+    [Arguments]    ${customer_id}    ${cloud_owner}    ${service_type}
+    :FOR    ${region}    IN    @{REGIONS}
+    \      Delete Tenant  ${TENANT_ID}    ${cloud_owner}  ${region}
+    \      Delete Cloud Region  ${TENANT_ID}    ${cloud_owner}  ${region}
+    Delete Customer    ${customer_id}
+    Delete Service If Exists    ${service_type}        
+
diff --git a/robot/resources/vid/create_service_instance.robot b/robot/resources/vid/create_service_instance.robot
new file mode 100644 (file)
index 0000000..2ea01ce
--- /dev/null
@@ -0,0 +1,57 @@
+*** Settings ***
+Documentation    Creates VID Service Instance
+...
+...                  Creates VID Service Instance
+
+Library            ExtendedSelenium2Library
+Library                UUID
+Library         String
+Library        DateTime
+
+Resource          ../mso_interface.robot
+Resource          vid_interface.robot
+
+*** Keywords ***  
+Create VID Service Instance
+    [Documentation]    Creates a service instance using VID    
+    [Arguments]    ${customer_name}  ${service_model_type}    ${service_type}     ${service_name}    
+    Go To VID HOME
+    Click Element    partial link=Browse SDC Service
+    Page Should Contain Element    xpath=//div/h1[text() = 'Browse SDC Service Models']
+    Wait Until Page Contains Element    xpath=//button[text() = 'Deploy']    240s
+    Input Text When Enabled    //input[@ng-model='searchString']    ${service_model_type}     
+    Wait Until Element Is Visible    xpath=//tr[td/span/text() = '${service_model_type}']/td/button[contains(text(),'Deploy')]    300000   
+    Press Key    xpath=//tr[td/span/text() = '${service_model_type}']/td/button[text() = 'Deploy' and not(@disabled)]    \\13
+    ${uuid}=    Generate UUID  
+    Wait Until Page Contains Element    xpath=//input[@parameter-name='Instance Name']    120s
+    Wait Until Element Is Visible    xpath=//input[@parameter-name='Instance Name']    120s
+    Xpath Should Match X Times    //input[@parameter-name='Instance Name']    1
+    Input Text When Enabled    //input[@parameter-name='Instance Name']    ${service_name}
+    Select From List When Enabled    //select[@prompt='Select Subscriber Name']    ${customer_name}      
+    Select From List WHen Enabled    //select[@prompt='Select Service Type']     ${service_type}
+    Click On Button When Enabled    //div[@class = 'buttonRow']/button[text() = 'Confirm']
+       Wait Until Element Contains    xpath=//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']    requestId    timeout=120s
+    ${response text}=    Get Text    xpath=//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']  
+    Click On Button When Enabled    //div[@class = 'buttonRow']/button[text() = 'Close']
+    ${request_id}=    Parse Request Id    ${response text}       
+    ${service_instance_id}=    Parse Instance Id     ${response text}
+    Poll MSO Get Request    ${GLOBAL_MSO_STATUS_PATH}${request_id}   COMPLETE
+    [return]    ${service_instance_id}
+
+    
+Delete Service Instance By GUI   
+    [Arguments]    ${service_instance_id}    ${customer_name} 
+    Click On Element When Visible    xpath=//a/span[@class='glyphicon glyphicon-remove']   
+    Click On Button When Visible    xpath=//div[@class='buttonRow']/button[@ngx-enabled='true']   
+    Wait Until Element Contains    xpath=//div[@ng-controller='deletionDialogController']//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']   requestId    timeout=120s
+    ${response text}=    Get Text    xpath=//div[@ng-controller='deletionDialogController']//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']
+    ${request_id}=    Parse Request Id     ${response text}
+    Poll MSO Get Request    ${GLOBAL_MSO_STATUS_PATH}${request_id}   COMPLETE
+  
+    
+Search Service Instance 
+    [Arguments]    ${service_instance_id}    ${customer_name}   
+    Click Link       xpath=//div[@heading = 'Search for Existing Service Instances']/a   
+    Input Text When Enabled    //input[@name='selectedServiceInstance']    ${service_instance_id} 
+    Click On Button When Enabled    //button[text() = 'Submit'] 
+   
\ No newline at end of file
diff --git a/robot/resources/vid/create_vid_vnf.robot b/robot/resources/vid/create_vid_vnf.robot
new file mode 100644 (file)
index 0000000..a306637
--- /dev/null
@@ -0,0 +1,122 @@
+*** Settings ***
+Documentation    Creates VID VNF Instance
+
+Library    ExtendedSelenium2Library    60
+Library                UUID
+Library         String
+Library        DateTime
+Library              RequestsLibrary
+
+Resource          ../mso_interface.robot
+Resource          vid_interface.robot
+*** Keywords ***  
+    
+Create VID VNF
+    [Documentation]    Creates a VNF instance using VID for passed instance id with the passed service instance name   
+    [Arguments]    ${service_instance_id}    ${service_instance_name}    ${product_family}    ${lcp_region}    ${tenant}   ${vnf_type}        
+    Go To VID HOME
+    Click Link       xpath=//div[@heading = 'Search for Existing Service Instances']/a
+    Wait Until Page Contains    Please search by    timeout=60s
+    #Wait Until Page Contains Element    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    #Wait Until Element Is Not Visible    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    
+    # If we don't wait for this control to be enabled, the submit results in a 'not found' pop-up (UnexpectedAlertPresentException) 
+    Input Text When Enabled    //input[@name='selectedServiceInstance']    ${service_instance_id}
+    Click Button    button=Submit
+    Wait Until Page Contains Element    link=View/Edit    timeout=60s
+    Click Element     xpath=//a[contains(text(), 'View/Edit')]    
+    Wait Until Page Contains    View/Edit Service Instance     timeout=60s
+    #Wait Until Page Contains Element    xpath=//div[@class='statusLine aaiVisible']    timeout=120s
+    #Wait Until Element Is Not Visible    xpath=//div[@class='statusLine aaiVisible']    timeout=60s
+    Click Element    button=Add VNF
+    
+    # This is where firefox breaks. Th elink never becomes visible when run with the script.
+    Click Element    link=${vnf_type}
+    Wait Until Page Contains Element    xpath=//input[@parameter-id='instanceName']    20s
+    Wait Until Element Is Enabled    xpath=//input[@parameter-id='instanceName']    20s
+    
+    ## Without this sleep, the input text below gets immediately wiped out. 
+    ## Wait Until Angular Ready just sleeps for its timeout value
+    Sleep    10s
+    Input Text           xpath=//input[@parameter-id='instanceName']    ${service_instance_name}
+    Select From List By Label     xpath=//select[@parameter-id='productFamily']    ${product_family}      
+    Select From List By Label    xpath=//select[@parameter-id='lcpRegion']    ${lcp_region}      
+    Select From List By Label    xpath=//select[@parameter-id='tenant']    ${tenant}      
+    Click Element    button=Confirm
+       Wait Until Element Contains    xpath=//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']    Status: OK (200)    timeout=120
+    ${response text}=    Get Text    xpath=//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']
+       Should Not Contain    ${response text}    FAILED   
+    Click Element    button=Close
+    ${instance_id}=    Parse Instance Id     ${response text}
+    Wait Until Page Contains    ${service_instance_name}    60s
+    [Return]     ${instance_id}  
+
+Delete VID VNF   
+    [Arguments]    ${service_instance_id}    ${lcp_region}    ${tenant}    ${vnf_instance_id} 
+    Go To VID HOME
+    Click Link       xpath=//div[@heading = 'Search for Existing Service Instances']/a
+    Wait Until Page Contains    Please search by    timeout=60s
+    Wait Until Page Contains Element    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    Wait Until Element Is Not Visible    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    
+    # If we don't wait for this control to be enabled, the submit results in a 'not found' pop-up (UnexpectedAlertPresentException) 
+    Input Text When Enabled    //input[@name='selectedServiceInstance']    ${service_instance_id}
+    Click Button    button=Submit
+    Wait Until Page Contains Element    link=View/Edit    timeout=60s
+    Click Element     link=View/Edit   
+    Wait Until Page Contains    View/Edit Service Instance     timeout=60s
+    Wait Until Page Contains Element    xpath=//div[@class='statusLine']    timeout=120s
+    Wait Until Element Is Not Visible    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    
+
+    
+    Click On Element When Visible    xpath=//li/div[contains(.,'${vnf_instance_id}')]/a/span[@class='glyphicon glyphicon-remove']    timeout=120s  
+    Select From List By Label    xpath=//select[@parameter-id='lcpRegion']    ${lcp_region}      
+    Select From List By Label    xpath=//select[@parameter-id='tenant']    ${tenant}      
+    Click Element    xpath=//div[@class='buttonRow']/button[@ngx-enabled='true']
+    #//*[@id="mContent"]/div/div/div/div/table/tbody/tr/td/div/div[2]/div/div[1]/div[5]/button[1]
+    
+    ${response text}=    Get Text    xpath=//div[@ng-controller='deletionDialogController']//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']
+    ${request_id}=    Parse Request Id     ${response text}
+    Poll MSO Get Request    ${GLOBAL_MSO_STATUS_PATH}${request_id}   COMPLETE
+  
+Create VID VNF module    
+    [Arguments]    ${service_instance_id}    ${vf_module_name}    ${LCP_REGION}    ${TENANT}    ${VNF_TYPE}       
+    Go To VID HOME
+    Click Link       xpath=//div[@heading = 'Search for Existing Service Instances']/a
+    Wait Until Page Contains    Please search by    timeout=60s
+    Wait Until Page Contains Element    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    
+     # If we don't wait for this control to be enabled, the submit results in a 'not found' pop-up (UnexpectedAlertPresentException) 
+    Input Text When Enabled    //input[@name='selectedServiceInstance']    ${service_instance_id}
+    Click Button    button=Submit
+    Wait Until Page Contains Element    link=View/Edit    timeout=60s
+    Click Element     link=View/Edit   
+    Wait Until Page Contains    View/Edit Service Instance     timeout=60s
+    Wait Until Page Contains Element    xpath=//div[@class='statusLine']    timeout=120s
+    Wait Until Element Is Not Visible    xpath=//div[@class='statusLine aaiHidden']    timeout=120s
+    Wait Until Element Is Visible    button=Add VF-Module   timeout=120s  
+    Click Element    button=Add VF-Module
+    
+    # This is where firefox breaks. Th elink never becomes visible when run with the script.
+    Click Element    link=${vnf_type}
+    Wait Until Page Contains Element    xpath=//input[@parameter-id='instanceName']    20s
+    Wait Until Element Is Enabled    xpath=//input[@parameter-id='instanceName']    20s
+    
+    ## Without this sleep, the input text below gets immediately wiped out. 
+    ## Wait Until Angular Ready just sleeps for its timeout value
+    Sleep    10s
+    Input Text           xpath=//input[@parameter-id='instanceName']    ${vf_module_name}     
+    Select From List By Label    xpath=//select[@parameter-id='lcpRegion']    ${lcp_region}      
+    Select From List By Label    xpath=//select[@parameter-id='tenant']    ${tenant}      
+    Click Element    button=Confirm
+       Wait Until Element Contains    xpath=//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']    requestId    timeout=120
+    ${response text}=    Get Text    xpath=//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']  
+    Click Element    button=Close
+    ${instance_id}=    Parse Instance Id     ${response text}
+    
+    ${request_id}=    Parse Request Id     ${response text}
+    Poll MSO Get Request    ${GLOBAL_MSO_STATUS_PATH}${request_id}   COMPLETE
+    
+    [Return]     ${instance_id} 
\ No newline at end of file
diff --git a/robot/resources/vid/teardown_vid.robot b/robot/resources/vid/teardown_vid.robot
new file mode 100644 (file)
index 0000000..50b5051
--- /dev/null
@@ -0,0 +1,63 @@
+*** Settings ***
+Documentation     The main interface for interacting with VID. It handles low level stuff like managing the selenium request library and VID required steps
+Library            ExtendedSelenium2Library
+Library            Collections
+Library         String
+Library              StringTemplater
+Library                  UUID      
+Resource        vid_interface.robot
+Resource        create_vid_vnf.robot
+Resource        create_service_instance.robot
+
+*** Variables ***
+${VID_ENV}            /vid
+${VID_SERVICE_MODELS_SEARCH_URL}  ${GLOBAL_VID_SERVER}${VID_ENV}/serviceModels.htm#/instances/subdetails?selectedSubscriber=\${customer_id}
+
+*** Keywords ***
+    
+Teardown VID 
+    [Documentation]   Teardown the VID This assumes that the any runnign stacks have been torn down
+    [Arguments]    ${service_instance_id}    ${lcp_region}    ${tenant}        
+    # Keep going to the VID service instance until all  of the remove icons are goe
+    Wait Until Keyword Succeeds    300s    1s    Delete VID    ${service_instance_id}    ${lcp_region}    ${tenant}
+    
+
+Delete VID   
+    [Documentation]    Teardown the next VID entity that has a Remove icon.
+    [Arguments]    ${service_instance_id}    ${lcp_region}    ${tenant}    
+    Go To    ${VID_SERVICE_MODELS_SEARCH_URL}
+    Wait Until Page Contains    Please search by    timeout=60s
+    Wait Until Page Contains Element    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    Wait Until Element Is Not Visible    xpath=//div[@class='statusLine aaiHidden']    timeout=60s
+    
+    # If we don't wait for this control to be enabled, the submit results in a 'not found' pop-up (UnexpectedAlertPresentException) 
+    Input Text When Enabled    //input[@name='selectedServiceInstance']    ${service_instance_id}
+    Click Button    button=Submit
+    Wait Until Page Contains Element    link=View/Edit    timeout=60s
+    Click Element     link=View/Edit   
+    Wait Until Page Contains    View/Edit Service Instance     timeout=60s
+    ${status}    ${data}=   Run Keyword And Ignore Error    Wait Until Element Is Visible    xpath=//li/div/a/span[@class='glyphicon glyphicon-remove']    timeout=120s
+    Return From Keyword If    '${status}' == 'FAIL'
+    
+    # At least one more Remove!
+    
+    # This list is a bit ogf a hack to determine the order of removal if there is more than one remove icon.
+    # Cannot tell how this will hold up once all of the VID removes are working for all conditions. 
+    ${remove_order}=    Create List    Vfmodule_Ete
+    :for   ${remove_first}    in    @{remove_order}  
+    \    ${status}    ${data}=   Run Keyword And Ignore Error    Page Should Contain Element     xpath=//li/div[contains(.,'${remove_first}')]/a/span[@class='glyphicon glyphicon-remove']
+    \    Run Keyword If   '${status}' == 'PASS'   Click On Element When Visible    xpath=//li/div[contains(.,'${remove_first}')]/a/span[@class='glyphicon glyphicon-remove']    timeout=120s
+    \    Run Keyword If   '${status}' == 'FAIL'   Click On Element When Visible    xpath=//li/div/a/span[@class='glyphicon glyphicon-remove']    timeout=120s  
+
+    Wait Until Page Contains Element     xpath=//select[@parameter-id='lcpRegion']
+    Select From List By Label    xpath=//select[@parameter-id='lcpRegion']    ${lcp_region}      
+    Select From List By Label    xpath=//select[@parameter-id='tenant']    ${tenant}      
+    Click Element    xpath=//div[@class='buttonRow']/button[@ngx-enabled='true']
+    #//*[@id="mContent"]/div/div/div/div/table/tbody/tr/td/div/div[2]/div/div[1]/div[5]/button[1]
+    Wait Until Page Contains    Status:COMPLETE -     300s
+    ${response text}=    Get Text    xpath=//div[@ng-controller='deletionDialogController']//div[@ng-controller= 'msoCommitController']/pre[@class = 'log ng-binding']
+    ${request_id}=    Parse Request Id     ${response text}
+    Click Element    button=Close
+    Poll MSO Get Request    ${GLOBAL_MSO_STATUS_PATH}${request_id}   COMPLETE
+    Fail   Successful VID Delete - continue with next delete
+  
diff --git a/robot/resources/vid/vid_interface.robot b/robot/resources/vid/vid_interface.robot
new file mode 100644 (file)
index 0000000..78b8148
--- /dev/null
@@ -0,0 +1,101 @@
+*** Settings ***
+Documentation     The main interface for interacting with VID. It handles low level stuff like managing the selenium request library and VID required steps
+Library            ExtendedSelenium2Library
+Library    Collections
+Library         String
+Library              RequestsLibrary
+Library                  UUID      
+Resource        ../global_properties.robot
+Resource        ../browser_setup.robot
+
+*** Variables ***
+${VID_ENV}            /vid
+${VID_LOGIN_URL}                ${GLOBAL_VID_SERVER}${VID_ENV}/login_external.htm
+${VID_HEALTHCHECK_PATH}    ${VID_ENV}/api/users
+${VID_HOME_URL}                ${GLOBAL_VID_SERVER}${VID_ENV}/vidhome.htm
+
+*** Keywords ***
+Run VID Health Check
+    [Documentation]   Logs in to VID GUI
+    ${resp}=    Run VID Get Request    ${VID_HEALTHCHECK_PATH}
+    Should Be Equal As Strings         ${resp.status_code}     200
+    Should Be String    ${resp.json()[0]['loginId']}
+
+Run VID Get Request
+    [Documentation]    Runs an VID get request
+    [Arguments]    ${data_path}
+    ${auth}=  Create List  ${GLOBAL_VID_HEALTH_USERNAME}    ${GLOBAL_VID_HEALTH_PASSWORD}
+    Log    Creating session ${GLOBAL_VID_SERVER}
+    ${session}=    Create Session      vid     ${GLOBAL_VID_SERVER}    auth=${auth}
+    ${uuid}=    Generate UUID
+    ${headers}=  Create Dictionary     username=${GLOBAL_VID_HEALTH_USERNAME}    password=${GLOBAL_VID_HEALTH_PASSWORD}    Accept=application/json    Content-Type=application/json    X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid}    X-FromAppId=${GLOBAL_APPLICATION_ID}
+    ${resp}=   Get Request     vid     ${data_path}     headers=${headers}
+    Log    Received response from vid ${resp.text}
+    [Return]    ${resp}   
+    
+Login To VID GUI
+    [Documentation]   Logs in to VID GUI
+    # Setup Browser Now being managed by test case
+    ##Setup Browser
+    Go To    ${VID_LOGIN_URL}
+    Maximize Browser Window
+    Set Selenium Speed    ${GLOBAL_SELENIUM_DELAY}
+    Set Browser Implicit Wait    ${GLOBAL_SELENIUM_BROWSER_IMPLICIT_WAIT}
+    Log    Logging in to ${GLOBAL_VID_SERVER}${VID_ENV}
+    Handle Proxy Warning
+    Title Should Be    VID Login
+    Input Text    xpath=//input[@ng-model='loginId']    ${GLOBAL_VID_USERNAME}
+    Input Password    xpath=//input[@ng-model='password']    ${GLOBAL_VID_PASSWORD}
+    Click Button    xpath=//input[@id='loginBtn']
+    Wait Until Page Contains Element    xpath=//div[@class='applicationWindow']    ${GLOBAL_SELENIUM_BROWSER_WAIT_TIMEOUT}    
+    Log    Logged in to ${GLOBAL_VID_SERVER}${VID_ENV}
+
+Go To VID HOME
+    [Documentation]    Naviage to VID Home
+    Go To    ${VID_HOME_URL}
+    Wait Until Page Contains Element    xpath=//div[@class='applicationWindow']    ${GLOBAL_SELENIUM_BROWSER_WAIT_TIMEOUT}    
+        
+Click On Button When Enabled
+    [Arguments]     ${xpath}    ${timeout}=60s
+    Wait Until Page Contains Element    xpath=${xpath}    ${timeout}
+    Wait Until Element Is Enabled    xpath=${xpath}    ${timeout}
+    Click Button      xpath=${xpath}
+
+Click On Button When Visible
+    [Arguments]     ${xpath}    ${timeout}=60s
+    Wait Until Page Contains Element    xpath=${xpath}    ${timeout}
+    Wait Until Element Is Visible    xpath=${xpath}    ${timeout}
+    Click Button      xpath=${xpath}
+   
+Click On Element When Visible
+    [Arguments]     ${xpath}    ${timeout}=60s
+    Wait Until Page Contains Element    xpath=${xpath}    ${timeout}
+    Wait Until Element Is Visible    xpath=${xpath}    ${timeout}
+    Click Element      xpath=${xpath}
+    
+Select From List When Enabled
+    [Arguments]     ${xpath}    ${value}    ${timeout}=60s
+    Wait Until Page Contains Element    xpath=${xpath}    ${timeout}
+    Wait Until Element Is Enabled    xpath=${xpath}    ${timeout}
+    Select From List     xpath=${xpath}    ${value}   
+    
+Input Text When Enabled        
+    [Arguments]     ${xpath}    ${value}    ${timeout}=60s
+    Wait Until Page Contains Element    xpath=${xpath}    ${timeout}
+    Wait Until Element Is Enabled    xpath=${xpath}    ${timeout}
+    Input Text    xpath=${xpath}    ${value}
+    
+Parse Request Id
+    [Arguments]    ${mso_response_text}                                        
+       ${request_list}=     Split String    ${mso_response_text}    202)\n    1
+       ${clean_string}=    Replace String    ${request_list[1]}    \n    ${empty}   
+    ${json}=    To Json    ${clean_string} 
+    ${request_id}=    Catenate    ${json['requestReferences']['requestId']}
+    [Return]    ${request_id}
+    
+Parse Instance Id
+    [Arguments]    ${mso_response_text}                                        
+       ${request_list}=     Split String    ${mso_response_text}    202)\n    1
+    ${json}=    To Json    ${request_list[1]} 
+    ${request_id}=    Catenate    ${json['requestReferences']['instanceId']}
+    [Return]    ${request_id}
\ No newline at end of file
diff --git a/robot/testsuites/closed-loop.robot b/robot/testsuites/closed-loop.robot
new file mode 100644 (file)
index 0000000..e36be89
--- /dev/null
@@ -0,0 +1,15 @@
+*** Settings ***
+Documentation    Closed Loop Test cases
+
+Resource    ../resources/test_templates/closedloop_test_template.robot
+
+Test Teardown    Teardown Closed Loop
+
+*** Test Cases ***
+
+VFW Closed Loop Test
+    [TAGS]    ete    closedloop
+    VFW Policy
+VDNS Closed Loop Test
+    [TAGS]    ete    closedloop
+    VDNS Policy    
\ No newline at end of file
diff --git a/robot/testsuites/health-check.robot b/robot/testsuites/health-check.robot
new file mode 100644 (file)
index 0000000..0a05375
--- /dev/null
@@ -0,0 +1,61 @@
+*** Settings ***
+Documentation    Testing ecomp components are available via calls.
+...
+...                  Testing ecomp components are available via calls.
+
+Resource          ../resources/dcae_interface.robot
+Resource          ../resources/sdngc_interface.robot
+Resource          ../resources/aai/aai_interface.robot
+Resource          ../resources/vid/vid_interface.robot
+Resource          ../resources/policy_interface.robot
+Resource          ../resources/mso_interface.robot
+Resource          ../resources/asdc_interface.robot
+Resource          ../resources/appc_interface.robot
+Resource          ../resources/portal_interface.robot
+Resource          ../resources/mr_interface.robot
+Resource          ../resources/aaf_interface.robot
+Resource          ../resources/heatbridge.robot
+
+*** Test Cases ***   
+Do Teardown
+    Execute Heatbridge Teardown    Vfmodule_Ete_Name49a8fbc5-3e94-430d-80d6-a52826961170
+
+Basic DCAE Health Check
+    [Tags]    health
+       Run DCAE Health Check
+       
+Basic SDNGC Health Check
+    [Tags]    health
+       Run SDNGC Health Check
+       
+Basic A&AI Health Check
+    [Tags]    health
+       Run A&AI Health Check
+
+Basic Policy Health Check
+    [Tags]    health
+    Run Policy Health Check
+    
+Basic MSO Health Check
+    [Tags]    health
+    Run MSO Health Check
+    
+Basic ASDC Health Check
+    [Tags]    health
+    Run ASDC Health Check
+
+Basic APPC Health Check    
+    [Tags]    health
+    Run APPC Health Check
+    
+Basic Portal Health Check    
+    [Tags]    health
+    Run Portal Health Check
+       
+Basic Message Router Health Check
+    [Tags]    health
+       Run MR Health Check
+       
+Basic VID Health Check
+    [Tags]    health
+       Run VID Health Check
diff --git a/robot/testsuites/model-distribution.robot b/robot/testsuites/model-distribution.robot
new file mode 100644 (file)
index 0000000..f1ce407
--- /dev/null
@@ -0,0 +1,22 @@
+*** Settings ***
+Documentation    Testing asdc.
+Library    OperatingSystem
+Library    RequestsLibrary
+Library    Collections
+Library    UUID
+Library              ExtendedSelenium2Library
+Resource          ../resources/test_templates/model_test_template.robot
+
+Test Template         Model Distribution For Directory
+Test Teardown    Teardown Model Distribution     
+
+*** Variables ***
+
+*** Test Cases ***
+Distribute vLB Model    vLB
+    [Tags]    ete    distribute
+Distribute vFW Model    vFW
+    [Tags]    ete    distribute
+Distribute vVG Model    vVG
+    [Tags]    ete    distribute
+    
diff --git a/robot/testsuites/vnf-orchestration.robot b/robot/testsuites/vnf-orchestration.robot
new file mode 100644 (file)
index 0000000..9e85da0
--- /dev/null
@@ -0,0 +1,22 @@
+*** Settings ***
+Documentation    Executes the VNF Orchestration Test cases including setup and teardown
+...
+
+Resource         ../resources/test_templates/vnf_orchestration_test_template.robot
+
+Test Setup            Setup Orchestrate VNF    ${GLOBAL_AAI_CLOUD_OWNER}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    SharedNode    OwnerType    v1    CloudZone  
+Test Template         Orchestrate VNF
+Test Teardown         Teardown VNF  
+    
+*** Test Cases ***              CUSTOMER           SERVICE   PRODUCT_FAMILY  LCP_REGION                             TENANT        
+Instantiate Virtual Firewall        ETE_Customer    vFW      vFW             ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${TENANT_NAME}          
+    [Tags]    ete    instantiate
+Instantiate Virtual DNS             ETE_Customer    vLB      vLB             ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${TENANT_NAME}          
+    [Tags]    ete    instantiate
+Instantiate Virtual Volume Group    ETE_Customer    vVG      vVG             ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${TENANT_NAME}          
+    [Tags]    ete    instantiate
+
+   
+
+
+
diff --git a/runTags.sh b/runTags.sh
new file mode 100644 (file)
index 0000000..5a51e25
--- /dev/null
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+# Set the defaults
+DEFAULT_LOG_LEVEL="INFO" # Available levels: TRACE, DEBUG, INFO (default), WARN, NONE (no logging)
+DEFAULT_RES="1280x1024x24"
+DEFAULT_DISPLAY=":99"
+DEFAULT_ROBOT_TEST="-i health"
+INSTALL_NAME="OpenECOMP_ETE"
+DEFAULT_OUTPUT_FOLDER=./
+
+# Use default if none specified as env var
+LOG_LEVEL=${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}
+RES=${RES:-$DEFAULT_RES}
+DISPLAY=${DISPLAY:-$DEFAULT_DISPLAY}
+
+# OUTPUT_FOLDER env variable will be overridden by -d command line argument.
+OUTPUT_FOLDER=${OUTPUT_FOLDER:-$DEFAULT_OUTPUT_FOLDER}
+
+VARIABLEFILES=
+
+## Single argument, it is an include tag
+if [ $# -eq 1 ]; then
+    ROBOT_TAGS="-i $1"
+fi
+
+## 
+## if more than 1 tag is supplied, the must be provided with -i or -e 
+##
+while [ $# -gt 1 ]
+do
+       key="$1"
+       
+       case $key in
+       -i|--include)
+       ROBOT_TAGS="${ROBOT_TAGS} -i $2"
+       shift 
+       ;;
+       -e|--exclude)
+       ROBOT_TAGS="${ROBOT_TAGS} -e $2"
+       shift 
+       ;;
+       -d|--outputdir)
+       OUTPUT_FOLDER=$2
+       shift
+       ;; 
+       --display)
+       DISPLAY=:$2
+       shift 
+       ;;
+       -V)
+       VARIABLEFILES="${VARIABLEFILES} -V $2 "
+       shift 
+       ;;
+       -v)
+       VARIABLES="${VARIABLES} -v $2 "
+       shift 
+       ;;
+       esac
+       shift
+done   
+
+if [ "${ROBOT_TAGS}" = "" ];then
+    ROBOT_TAGS=$DEFAULT_ROBOT_TEST
+fi 
+
+# Start Xvfb
+echo -e "Starting Xvfb on display ${DISPLAY} with res ${RES}"
+Xvfb ${DISPLAY} -ac -screen 0 ${RES} +extension RANDR &
+XVFBPID=$!
+# Get pid of this spawned process to make sure we kill the correct process later
+
+export DISPLAY=${DISPLAY}
+
+# Execute tests
+echo -e "Executing robot tests at log level ${LOG_LEVEL}"
+
+ROBOT_LIBS=./robot/library:./robot/library/eteutils:./robot/library/heatbridge
+
+cd /var/opt/${INSTALL_NAME}
+python -m robot.run -L ${LOG_LEVEL} -d ${OUTPUT_FOLDER} ${VARIABLEFILES} ${VARIABLES} -P ${ROBOT_LIBS} ${ROBOT_TAGS} $(pwd)
+
+# Stop Xvfb we started earlier
+# select it from list of possible Xvfb pids running because
+# a) there may be multiple Xvfbs running and 
+# b) the XVFBPID may not be the correct if the start did not actually work (unlikely and that may be) 
+PIDS=$(pgrep Xvfb)
+for P in $PIDS
+do
+       if [ $P == $XVFBPID ];then
+               kill -9 $P
+       fi
+done
diff --git a/setup.sh b/setup.sh
new file mode 100644 (file)
index 0000000..3d324c9
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+#
+# setup : script to setup required runtime environment. This script can be run again to update anything
+# this should stay in your project directory
+#
+
+# get the path
+path=$(pwd)
+
+pip install --target="$path/robot/library" 'selenium<=3.0.0' 'requests==2.11.1' 'robotframework-selenium2library==1.8.0' \
+'robotframework-databaselibrary==0.8.1' 'robotframework-extendedselenium2library==0.9.1' 'robotframework-requests==0.4.5' \
+'robotframework-sshlibrary==2.1.2' \
+'robotframework-sudslibrary==0.8' 'robotframework-ftplibrary==1.3' 'robotframework-rammbock==0.4.0.1' \
+'deepdiff==2.5.1' 'dnspython==1.15.0' 'robotframework-httplibrary==0.4.2' 'robotframework-archivelibrary==0.3.2' 'PyYAML==3.12'
+
+
+# get the git for the eteutils you will need to add a private key to your ssh before this
+if [ -d $path/eteutils ]
+then
+       cd $path/eteutils
+else 
+       cd ~
+       git config --global http.sslVerify false
+       if [ -d ~/python-testing-utils ]
+       then
+               cd python-testing-utils
+               git pull origin master
+       else 
+               git clone https://gerrit.openecomp.org/r/testsuite/python-testing-utils.git
+               cd python-testing-utils
+       fi
+fi
+pip install --upgrade --target="$path/robot/library" .
+
+
+if [ -d $path/heatbridge ]
+then
+       cd $path/heatbridge
+else 
+       cd ~
+       git config --global http.sslVerify false
+       if [ -d ~/heatbridge ]
+       then
+               cd heatbridge
+               git pull origin master
+       else 
+               git clone https://gerrit.openecomp.org/r/testsuite/heatbridge.git
+               cd heatbridge
+       fi
+fi
+pip install --upgrade --target="$path/robot/library" .
+
+
+# NOTE: Patch to incude explicit install of paramiko to 2.0.2 to work with sshlibrary 2.1.2
+# This should be removed on new release of paramiko (2.1.2) or sshlibrary
+# https://github.com/robotframework/SSHLibrary/issues/157
+pip install --target="$path/robot/library" -U 'paramiko==2.0.2'
+
+#
+# Get the appropriate chromedriver. Default to linux64 
+#
+CHROMEDRIVER_URL=http://chromedriver.storage.googleapis.com/2.27
+CHROMEDRIVER_ZIP=chromedriver_linux64.zip
+
+# Handle mac and windows 
+OS=`uname -s`
+case $OS in
+  MINGW*_NT*) 
+       CHROMEDRIVER_ZIP=chromedriver_win32.zip
+       ;;
+  Darwin*)
+       CHROMEDRIVER_ZIP=chromedriver_mac64.zip 
+       ;;
+  *) echo "Defaulting to Linux 64" ;;
+esac
+
+if [ $CHROMEDRIVER_ZIP == 'chromedriver_linux64.zip' ]
+then
+    wget -O chromedriver.zip $CHROMEDRIVER_URL/$CHROMEDRIVER_ZIP 
+       unzip chromedriver.zip -d /usr/local/bin
+else
+    curl $CHROMEDRIVER_URL/$CHROMEDRIVER_ZIP -o chromedriver.zip  
+       unzip chromedriver.zip 
+fi