summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xjjb/apex/apex-deploy.sh9
-rw-r--r--jjb/apex/apex.yml55
-rw-r--r--jjb/armband/armband-ci-jobs.yml70
-rwxr-xr-xjjb/armband/armband-deploy.sh8
-rw-r--r--jjb/compass4nfv/compass-ci-jobs.yml16
-rwxr-xr-xjjb/fuel/fuel-build.sh4
-rw-r--r--jjb/fuel/fuel-daily-jobs.yml18
-rw-r--r--jjb/functest/functest-daily-jobs.yml8
-rw-r--r--jjb/global/slave-params.yml18
-rw-r--r--jjb/joid/joid-daily-jobs.yml4
-rwxr-xr-xjjb/multisite/fuel-deploy-for-multisite.sh8
-rw-r--r--jjb/multisite/multisite-daily-jobs.yml10
-rw-r--r--jjb/opnfvdocs/docs-rtd.yaml2
-rw-r--r--jjb/qtip/qtip-validate-jobs.yml29
-rw-r--r--jjb/xci/bifrost-cleanup-job.yml (renamed from jjb/infra/bifrost-cleanup-job.yml)2
-rw-r--r--jjb/xci/bifrost-verify-jobs.yml (renamed from jjb/infra/bifrost-verify-jobs.yml)0
-rwxr-xr-xjjb/xci/bifrost-verify.sh (renamed from jjb/infra/bifrost-verify.sh)0
-rw-r--r--jjb/xci/xci-daily-jobs.yml220
-rwxr-xr-xjjb/xci/xci-deploy.sh3
-rwxr-xr-xjjb/xci/xci-functest.sh3
-rwxr-xr-xjjb/xci/xci-provision.sh3
-rwxr-xr-xprototypes/bifrost/scripts/destroy-env.sh6
-rwxr-xr-xprototypes/bifrost/scripts/osa-bifrost-deployment.sh142
-rwxr-xr-xprototypes/openstack-ansible/scripts/osa_deploy.sh1
-rw-r--r--prototypes/openstack-ansible/var/ubuntu.yml2
-rw-r--r--prototypes/puppet-infracloud/creds/clouds.yaml1
-rw-r--r--prototypes/puppet-infracloud/hiera/common.yaml1
-rw-r--r--prototypes/puppet-infracloud/hiera/common_baremetal.yaml9
-rw-r--r--utils/lab-reconfiguration/foreman.yaml1
-rw-r--r--utils/lab-reconfiguration/fuel.yaml1
-rw-r--r--utils/test/dashboard/dashboard/functest/testcases.yaml1
-rw-r--r--utils/test/dashboard/dashboard/qtip/testcases.yaml3
-rw-r--r--utils/test/reporting/functest/testCase.py12
-rw-r--r--utils/test/reporting/reporting.yaml19
-rw-r--r--utils/test/testapi/update/test.yml2
-rw-r--r--utils/test/testapi/update/update.yml4
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/README.md9
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/app.js24
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/database.js23
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/package.json9
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js7
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js60
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js82
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js12
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css12
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css58
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css36
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css19
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.pngbin0 -> 12138 bytes
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js116
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js52
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js19
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js79
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js36
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js36
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js55
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade164
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade3
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade3
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade84
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade5
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade132
-rw-r--r--utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade167
-rw-r--r--utils/test/vnfcatalogue/cronjobs/README.md24
-rw-r--r--utils/test/vnfcatalogue/cronjobs/database.js14
-rw-r--r--utils/test/vnfcatalogue/cronjobs/github.js129
-rw-r--r--utils/test/vnfcatalogue/helpers/migrate.js12
-rw-r--r--utils/test/vnfcatalogue/helpers/schema.js8
68 files changed, 1997 insertions, 187 deletions
diff --git a/jjb/apex/apex-deploy.sh b/jjb/apex/apex-deploy.sh
index c91e3ee82..564c9cdb8 100755
--- a/jjb/apex/apex-deploy.sh
+++ b/jjb/apex/apex-deploy.sh
@@ -196,6 +196,15 @@ else
NETWORK_SETTINGS_DIR="/root/network"
INVENTORY_FILE="/root/inventory/pod_settings.yaml"
+ # if fdio on baremetal, then we are using UCS enic and
+ # need to use vfio-pci instead of uio generic
+ if [[ "$DEPLOY_SCENARIO" == *fdio* ]]; then
+ TMP_DEPLOY_FILE="${WORKSPACE}/${DEPLOY_SCENARIO}.yaml"
+ cp -f ${DEPLOY_FILE} ${TMP_DEPLOY_FILE}
+ sed -i 's/^\(\s*uio-driver:\).*$/\1 vfio-pci/g' ${TMP_DEPLOY_FILE}
+ DEPLOY_FILE=${TMP_DEPLOY_FILE}
+ fi
+
if ! sudo test -e "$INVENTORY_FILE"; then
echo "ERROR: Required settings file missing: Inventory settings file ${INVENTORY_FILE}"
exit 1
diff --git a/jjb/apex/apex.yml b/jjb/apex/apex.yml
index 3e78f32c9..93eaa6c6c 100644
--- a/jjb/apex/apex.yml
+++ b/jjb/apex/apex.yml
@@ -52,6 +52,7 @@
- 'os-odl_l3-fdio_dvr-noha'
- 'os-odl_l3-fdio_dvr-ha'
- 'os-odl_l3-csit-noha'
+ - 'os-odl_l3-nofeature-noha'
- 'os-onos-nofeature-ha'
- 'gate'
@@ -610,17 +611,17 @@
# i.e. one tempest smoke ipv6, two vping from functest)
# 4.not used for release criteria or compliance,
# only to debug the dovetail tool bugs with apex
- - trigger-builds:
- - project: 'dovetail-apex-{slave}-debug-{stream}'
- current-parameters: false
- predefined-parameters:
- DEPLOY_SCENARIO=os-nosdn-nofeature-ha
- block: true
- same-node: true
- block-thresholds:
- build-step-failure-threshold: 'never'
- failure-threshold: 'never'
- unstable-threshold: 'FAILURE'
+ #- trigger-builds:
+ # - project: 'dovetail-apex-{slave}-debug-{stream}'
+ # current-parameters: false
+ # predefined-parameters:
+ # DEPLOY_SCENARIO=os-nosdn-nofeature-ha
+ # block: true
+ # same-node: true
+ # block-thresholds:
+ # build-step-failure-threshold: 'never'
+ # failure-threshold: 'never'
+ # unstable-threshold: 'FAILURE'
- trigger-builds:
- project: 'apex-deploy-baremetal-os-odl_l3-nofeature-ha-{stream}'
predefined-parameters: |
@@ -831,6 +832,36 @@
build-step-failure-threshold: 'never'
failure-threshold: 'never'
unstable-threshold: 'FAILURE'
+ - trigger-builds:
+ - project: 'apex-deploy-baremetal-os-nosdn-fdio-ha-{stream}'
+ predefined-parameters: |
+ BUILD_DIRECTORY=apex-build-{stream}/.build
+ OPNFV_CLEAN=yes
+ git-revision: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ block: true
+ - trigger-builds:
+ - project: 'functest-apex-{daily-slave}-daily-{stream}'
+ predefined-parameters:
+ DEPLOY_SCENARIO=os-nosdn-fdio-ha
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
+ - trigger-builds:
+ - project: 'yardstick-apex-{slave}-daily-{stream}'
+ predefined-parameters:
+ DEPLOY_SCENARIO=os-nosdn-fdio-ha
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
# CSIT promote
- job-template:
@@ -1046,7 +1077,7 @@
- trigger:
name: 'apex-master'
triggers:
- - timed: '0 3 * * 7'
+ - timed: '0 3 1 1 7'
- trigger:
name: 'apex-danube'
triggers:
diff --git a/jjb/armband/armband-ci-jobs.yml b/jjb/armband/armband-ci-jobs.yml
index 137d645d1..ddcbbd038 100644
--- a/jjb/armband/armband-ci-jobs.yml
+++ b/jjb/armband/armband-ci-jobs.yml
@@ -56,6 +56,10 @@
slave-label: arm-pod3
installer: fuel
<<: *danube
+ - arm-pod3-2:
+ slave-label: arm-pod3-2
+ installer: fuel
+ <<: *danube
#--------------------------------
# master
#--------------------------------
@@ -67,6 +71,10 @@
slave-label: arm-pod3
installer: fuel
<<: *master
+ - arm-pod3-2:
+ slave-label: arm-pod3-2
+ installer: fuel
+ <<: *master
#--------------------------------
# scenarios
#--------------------------------
@@ -505,3 +513,65 @@
name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-danube-trigger'
triggers:
- timed: ''
+#--------------------------------------------------------------------------
+# Enea Armband POD 3 Triggers running against master branch (aarch64 slave)
+#--------------------------------------------------------------------------
+- trigger:
+ name: 'fuel-os-odl_l2-nofeature-ha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-nosdn-nofeature-ha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l3-nofeature-ha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-bgpvpn-ha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-nofeature-noha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-sfc-ha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-2-master-trigger'
+ triggers:
+ - timed: ''
+#--------------------------------------------------------------------------
+# Enea Armband POD 3 Triggers running against danube branch (aarch64 slave)
+#--------------------------------------------------------------------------
+- trigger:
+ name: 'fuel-os-odl_l2-nofeature-ha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-nosdn-nofeature-ha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l3-nofeature-ha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-bgpvpn-ha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-nofeature-noha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-sfc-ha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
+- trigger:
+ name: 'fuel-os-odl_l2-sfc-noha-arm-pod3-2-danube-trigger'
+ triggers:
+ - timed: ''
diff --git a/jjb/armband/armband-deploy.sh b/jjb/armband/armband-deploy.sh
index adabfcaeb..2e5aa3924 100755
--- a/jjb/armband/armband-deploy.sh
+++ b/jjb/armband/armband-deploy.sh
@@ -32,6 +32,14 @@ fi
# set deployment parameters
export TMPDIR=${WORKSPACE}/tmpdir
+
+# arm-pod3-2 is an aarch64 jenkins slave for the same POD as the
+# x86 jenkins slave arm-pod3; therefore we use the same pod name
+# to deploy the pod from both jenkins slaves
+if [[ "${NODE_NAME}" == "arm-pod3-2" ]]; then
+ NODE_NAME="arm-pod3"
+fi
+
LAB_NAME=${NODE_NAME/-*}
POD_NAME=${NODE_NAME/*-}
diff --git a/jjb/compass4nfv/compass-ci-jobs.yml b/jjb/compass4nfv/compass-ci-jobs.yml
index c934d1985..237f8944d 100644
--- a/jjb/compass4nfv/compass-ci-jobs.yml
+++ b/jjb/compass4nfv/compass-ci-jobs.yml
@@ -32,11 +32,11 @@
<<: *master
- baremetal:
slave-label: compass-baremetal
- os-version: 'trusty'
+ os-version: 'xenial'
<<: *danube
- virtual:
slave-label: compass-virtual
- os-version: 'trusty'
+ os-version: 'xenial'
<<: *danube
#--------------------------------
# master
@@ -323,27 +323,27 @@
- trigger:
name: 'compass-os-nosdn-nofeature-ha-baremetal-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 9 * * *'
- trigger:
name: 'compass-os-nosdn-openo-ha-baremetal-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 13 * * *'
- trigger:
name: 'compass-os-odl_l2-nofeature-ha-baremetal-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 17 * * *'
- trigger:
name: 'compass-os-odl_l3-nofeature-ha-baremetal-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 21 * * *'
- trigger:
name: 'compass-os-onos-nofeature-ha-baremetal-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 1 * * *'
- trigger:
name: 'compass-os-ocl-nofeature-ha-baremetal-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 5 * * *'
- trigger:
name: 'compass-os-onos-sfc-ha-baremetal-danube-trigger'
triggers:
diff --git a/jjb/fuel/fuel-build.sh b/jjb/fuel/fuel-build.sh
index c66dc3d8d..e1a4c0267 100755
--- a/jjb/fuel/fuel-build.sh
+++ b/jjb/fuel/fuel-build.sh
@@ -25,8 +25,10 @@ if [[ "$JOB_NAME" =~ "daily" ]]; then
echo "Checking to see if we already built and stored Fuel ISO for this commit"
curl -s -o $LATEST_ISO_PROPERTIES http://$GS_URL/latest.properties 2>/dev/null
+fi
- # get metadata of latest ISO
+# get metadata of latest ISO
+if grep -q OPNFV_GIT_SHA1 $LATEST_ISO_PROPERTIES 2>/dev/null; then
LATEST_ISO_SHA1=$(grep OPNFV_GIT_SHA1 $LATEST_ISO_PROPERTIES | cut -d'=' -f2)
LATEST_ISO_URL=$(grep OPNFV_ARTIFACT_URL $LATEST_ISO_PROPERTIES | cut -d'=' -f2)
else
diff --git a/jjb/fuel/fuel-daily-jobs.yml b/jjb/fuel/fuel-daily-jobs.yml
index 36f3ce414..b65b2c0dd 100644
--- a/jjb/fuel/fuel-daily-jobs.yml
+++ b/jjb/fuel/fuel-daily-jobs.yml
@@ -386,11 +386,11 @@
- trigger:
name: 'fuel-os-onos-sfc-ha-baremetal-daily-danube-trigger'
triggers:
- - timed: '0 5 * * *'
+ - timed: '' # '0 5 * * *'
- trigger:
name: 'fuel-os-onos-nofeature-ha-baremetal-daily-danube-trigger'
triggers:
- - timed: '0 8 * * *'
+ - timed: '' # '0 8 * * *'
- trigger:
name: 'fuel-os-odl_l2-sfc-ha-baremetal-daily-danube-trigger'
triggers:
@@ -410,11 +410,11 @@
- trigger:
name: 'fuel-os-nosdn-kvm_ovs_dpdk-ha-baremetal-daily-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 12 * * *'
- trigger:
name: 'fuel-os-nosdn-kvm_ovs_dpdk_bar-ha-baremetal-daily-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 8 * * *'
# NOHA Scenarios
- trigger:
name: 'fuel-os-nosdn-nofeature-noha-baremetal-daily-danube-trigger'
@@ -615,11 +615,11 @@
- trigger:
name: 'fuel-os-onos-sfc-noha-virtual-daily-danube-trigger'
triggers:
- - timed: '30 20 * * *'
+ - timed: '' # '30 20 * * *'
- trigger:
name: 'fuel-os-onos-nofeature-noha-virtual-daily-danube-trigger'
triggers:
- - timed: '0 23 * * *'
+ - timed: '' # '0 23 * * *'
- trigger:
name: 'fuel-os-odl_l2-sfc-noha-virtual-daily-danube-trigger'
triggers:
@@ -639,11 +639,11 @@
- trigger:
name: 'fuel-os-nosdn-kvm_ovs_dpdk-noha-virtual-daily-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 16 * * *'
- trigger:
name: 'fuel-os-nosdn-kvm_ovs_dpdk_bar-noha-virtual-daily-danube-trigger'
triggers:
- - timed: ''
+ - timed: '0 20 * * *'
#-----------------------------------------------
# ZTE POD1 Triggers running against master branch
#-----------------------------------------------
@@ -1140,7 +1140,7 @@
- trigger:
name: 'fuel-os-nosdn-kvm-ha-zte-pod3-daily-danube-trigger'
triggers:
- - timed: '0 18 * * *'
+ - timed: '0 2 * * *'
- trigger:
name: 'fuel-os-nosdn-ovs-ha-zte-pod3-daily-danube-trigger'
triggers:
diff --git a/jjb/functest/functest-daily-jobs.yml b/jjb/functest/functest-daily-jobs.yml
index 972c4fd2f..a3268d3e5 100644
--- a/jjb/functest/functest-daily-jobs.yml
+++ b/jjb/functest/functest-daily-jobs.yml
@@ -158,6 +158,10 @@
slave-label: '{pod}'
installer: fuel
<<: *master
+ - arm-pod3-2:
+ slave-label: '{pod}'
+ installer: fuel
+ <<: *master
- zte-pod1:
slave-label: '{pod}'
installer: fuel
@@ -186,6 +190,10 @@
slave-label: '{pod}'
installer: fuel
<<: *danube
+ - arm-pod3-2:
+ slave-label: '{pod}'
+ installer: fuel
+ <<: *danube
# PODs for verify jobs triggered by each patch upload
- ool-virtual1:
slave-label: '{pod}'
diff --git a/jjb/global/slave-params.yml b/jjb/global/slave-params.yml
index 6aa2e717c..1905a098a 100644
--- a/jjb/global/slave-params.yml
+++ b/jjb/global/slave-params.yml
@@ -747,6 +747,24 @@
default: ssh://jenkins-enea@gerrit.opnfv.org:29418/securedlab
description: 'Base URI to the configuration directory'
- parameter:
+ name: 'arm-pod3-2-defaults'
+ parameters:
+ - node:
+ name: SLAVE_NAME
+ description: 'Slave name on Jenkins'
+ allowed-slaves:
+ - arm-pod3-2
+ default-slaves:
+ - arm-pod3-2
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: 'Git URL to use on this Jenkins Slave'
+ - string:
+ name: LAB_CONFIG_URL
+ default: ssh://jenkins-enea@gerrit.opnfv.org:29418/securedlab
+ description: 'Base URI to the configuration directory'
+- parameter:
name: 'intel-virtual6-defaults'
parameters:
- node:
diff --git a/jjb/joid/joid-daily-jobs.yml b/jjb/joid/joid-daily-jobs.yml
index 97e290c8a..8c69c8310 100644
--- a/jjb/joid/joid-daily-jobs.yml
+++ b/jjb/joid/joid-daily-jobs.yml
@@ -64,13 +64,13 @@
- 'os-odl_l2-nofeature-ha':
auto-trigger-name: 'joid-{scenario}-{pod}-{stream}-trigger'
- 'os-onos-nofeature-ha':
- auto-trigger-name: 'joid-{scenario}-{pod}-{stream}-trigger'
+ auto-trigger-name: 'daily-trigger-disabled'
- 'os-odl_l2-nofeature-noha':
auto-trigger-name: 'daily-trigger-disabled'
- 'os-onos-nofeature-noha':
auto-trigger-name: 'daily-trigger-disabled'
- 'os-onos-sfc-ha':
- auto-trigger-name: 'joid-{scenario}-{pod}-{stream}-trigger'
+ auto-trigger-name: 'daily-trigger-disabled'
- 'os-ocl-nofeature-ha':
auto-trigger-name: 'daily-trigger-disabled'
- 'os-ocl-nofeature-noha':
diff --git a/jjb/multisite/fuel-deploy-for-multisite.sh b/jjb/multisite/fuel-deploy-for-multisite.sh
index 06617610c..71c6cc11d 100755
--- a/jjb/multisite/fuel-deploy-for-multisite.sh
+++ b/jjb/multisite/fuel-deploy-for-multisite.sh
@@ -19,9 +19,9 @@ else
fi
export TERM="vt220"
-
+export BRANCH=$(echo $BRANCH | sed 's/stable\///g')
# get the latest successful job console log and extract the properties filename
-FUEL_DEPLOY_BUILD_URL="https://build.opnfv.org/ci/job/fuel-deploy-virtual-daily-master/lastSuccessfulBuild/consoleText"
+FUEL_DEPLOY_BUILD_URL="https://build.opnfv.org/ci/job/fuel-deploy-virtual-daily-$BRANCH/lastSuccessfulBuild/consoleText"
FUEL_PROPERTIES_FILE=$(curl -s -L ${FUEL_DEPLOY_BUILD_URL} | grep 'ISO:' | awk '{print $2}' | sed 's/iso/properties/g')
if [[ -z "FUEL_PROPERTIES_FILE" ]]; then
echo "Unable to extract the url to Fuel ISO properties from ${FUEL_DEPLOY_URL}"
@@ -29,8 +29,8 @@ if [[ -z "FUEL_PROPERTIES_FILE" ]]; then
fi
# use known/working version of fuel
-FUEL_PROPERTIES_FILE="opnfv-2017-03-06_16-00-15.properties"
-curl -L -s -o $WORKSPACE/latest.properties http://artifacts.opnfv.org/fuel/$FUEL_PROPERTIES_FILE
+#FUEL_PROPERTIES_FILE="opnfv-2017-03-06_16-00-15.properties"
+curl -L -s -o $WORKSPACE/latest.properties $GS_PATH/$FUEL_PROPERTIES_FILE
# source the file so we get OPNFV vars
source latest.properties
diff --git a/jjb/multisite/multisite-daily-jobs.yml b/jjb/multisite/multisite-daily-jobs.yml
index 23c95f627..06cefb646 100644
--- a/jjb/multisite/multisite-daily-jobs.yml
+++ b/jjb/multisite/multisite-daily-jobs.yml
@@ -24,7 +24,12 @@
branch: '{stream}'
gs-pathname: ''
disabled: false
- timed: '@midnight'
+ timed: '0 12 * * *'
+ - danube:
+ branch: 'stable/{stream}'
+ gs-pathname: '/{stream}'
+ disabled: false
+ timed: '0 0 * * *'
- job-template:
name: 'multisite-kingbird-virtual-daily-{stream}'
@@ -166,6 +171,9 @@
- string:
name: KINGBIRD_LOG_FILE
default: $WORKSPACE/kingbird.log
+ - string:
+ name: GS_PATH
+ default: 'http://artifacts.opnfv.org/fuel{gs-pathname}'
- 'fuel-defaults'
- '{slave-label}-defaults'
- choice:
diff --git a/jjb/opnfvdocs/docs-rtd.yaml b/jjb/opnfvdocs/docs-rtd.yaml
index bfe719149..bf6d0012b 100644
--- a/jjb/opnfvdocs/docs-rtd.yaml
+++ b/jjb/opnfvdocs/docs-rtd.yaml
@@ -7,6 +7,8 @@
stream:
- master:
branch: 'master'
+ - danube:
+ branch: 'stable/{stream}'
project: 'opnfvdocs'
rtdproject: 'opnfv'
diff --git a/jjb/qtip/qtip-validate-jobs.yml b/jjb/qtip/qtip-validate-jobs.yml
index 4cd8490fd..deaf525af 100644
--- a/jjb/qtip/qtip-validate-jobs.yml
+++ b/jjb/qtip/qtip-validate-jobs.yml
@@ -23,22 +23,25 @@
# JOB VARIABLES
#--------------------------------
pod:
- - zte-pod2:
+ - zte-pod1:
installer: fuel
<<: *master
- zte-pod3:
installer: fuel
<<: *master
+ - zte-pod1:
+ installer: fuel
+ <<: *danube
- zte-pod3:
installer: fuel
<<: *danube
task:
- daily:
auto-builder-name: qtip-validate-deploy
- auto-trigger-name: 'qtip-daily-{pod}-trigger'
+ auto-trigger-name: 'qtip-{pod}-daily-{stream}-trigger'
- validate:
auto-builder-name: qtip-validate-setup
- auto-trigger-name: qtip-validate-trigger
+ auto-trigger-name: gerrit-trigger-change-merged
- experimental:
auto-builder-name: qtip-validate-setup
auto-trigger-name: experimental
@@ -58,7 +61,8 @@
parameters:
- qtip-common-parameters:
project: '{project}'
- <<: *master
+ branch: '{branch}'
+ docker-tag: '{docker-tag}'
- '{installer}-defaults'
- '{pod}-defaults'
- string:
@@ -82,7 +86,6 @@
#---------
# builder
#---------
-
- builder:
name: qtip-common-builders
builders:
@@ -136,14 +139,24 @@
#---------
- trigger:
- name: qtip-daily-zte-pod2-trigger
+ name: 'qtip-zte-pod1-daily-master-trigger'
+ triggers:
+ - timed: '30 0 * * *'
+
+- trigger:
+ name: 'qtip-zte-pod3-daily-master-trigger'
+ triggers:
+ - timed: '30 0 * * *'
+
+- trigger:
+ name: 'qtip-zte-pod1-daily-danube-trigger'
triggers:
- timed: '0 7 * * *'
- trigger:
- name: qtip-daily-zte-pod3-trigger
+ name: 'qtip-zte-pod3-daily-danube-trigger'
triggers:
- - timed: '0 1 * * *'
+ - timed: '0 7 * * *'
- trigger:
name: qtip-validate-trigger
diff --git a/jjb/infra/bifrost-cleanup-job.yml b/jjb/xci/bifrost-cleanup-job.yml
index d09dd5a32..571e275da 100644
--- a/jjb/infra/bifrost-cleanup-job.yml
+++ b/jjb/xci/bifrost-cleanup-job.yml
@@ -88,6 +88,7 @@
trigger-on:
# We only run this when the change is merged or
# abandoned since we don't need the logs anymore
+ - patchset-uploaded-event: 'false'
- change-merged-event: 'true'
- change-abandoned-event: 'true'
- change-restored-event: 'false'
@@ -118,6 +119,7 @@
trigger-on:
# We only run this when the change is merged or
# abandoned since we don't need the logs anymore
+ - patchset-uploaded-event: 'false'
- change-merged-event: 'true'
- change-abandoned-event: 'true'
- change-restored-event: 'false'
diff --git a/jjb/infra/bifrost-verify-jobs.yml b/jjb/xci/bifrost-verify-jobs.yml
index 33032bc7b..33032bc7b 100644
--- a/jjb/infra/bifrost-verify-jobs.yml
+++ b/jjb/xci/bifrost-verify-jobs.yml
diff --git a/jjb/infra/bifrost-verify.sh b/jjb/xci/bifrost-verify.sh
index 4115ffcc4..4115ffcc4 100755
--- a/jjb/infra/bifrost-verify.sh
+++ b/jjb/xci/bifrost-verify.sh
diff --git a/jjb/xci/xci-daily-jobs.yml b/jjb/xci/xci-daily-jobs.yml
new file mode 100644
index 000000000..a71b9b783
--- /dev/null
+++ b/jjb/xci/xci-daily-jobs.yml
@@ -0,0 +1,220 @@
+- project:
+ name: 'bifrost-osa-daily'
+#--------------------------------
+# BRANCH ANCHORS
+#--------------------------------
+ master: &master
+ stream: master
+ branch: '{stream}'
+ gs-pathname: ''
+ ocata: &ocata
+ stream: ocata
+ branch: 'stable/{stream}'
+ gs-pathname: '/{stream}'
+#--------------------------------
+# scenarios
+#--------------------------------
+ scenario:
+ # HA scenarios
+ - 'os-nosdn-nofeature-ha':
+ auto-trigger-name: 'daily-trigger-disabled'
+#--------------------------------
+# XCI PODs
+#--------------------------------
+ pod:
+ - virtual:
+ <<: *master
+ - virtual:
+ <<: *ocata
+#--------------------------------
+# Supported Distros
+#--------------------------------
+ distro:
+ - 'xenial':
+ disabled: false
+ slave-label: xci-xenial-virtual
+ dib-os-release: 'xenial'
+ dib-os-element: 'ubuntu-minimal'
+ dib-os-packages: 'vlan,vim,less,bridge-utils,sudo,language-pack-en,iputils-ping,rsyslog,curl,python,debootstrap,ifenslave,ifenslave-2.6,lsof,lvm2,tcpdump,nfs-kernel-server,chrony'
+ extra-dib-elements: 'openssh-server'
+ - 'centos7':
+ disabled: true
+ slave-label: xci-centos7-virtual
+ dib-os-release: '7'
+ dib-os-element: 'centos7'
+ dib-os-packages: 'vim,less,bridge-utils,iputils,rsyslog,curl'
+ extra-dib-elements: 'openssh-server'
+ - 'suse':
+ disabled: true
+ slave-label: xci-suse-virtual
+ dib-os-release: '42.2'
+ dib-os-element: 'opensuse-minimal'
+ dib-os-packages: 'vim,less,bridge-utils,iputils,rsyslog,curl'
+ extra-dib-elements: 'openssh-server'
+#--------------------------------
+# Phases
+#--------------------------------
+ phase:
+ - 'provision':
+ project: 'openstack'
+ project-repo: 'https://git.openstack.org/openstack/bifrost'
+ project-branch: '{branch}'
+ clone-location: '/opt/bifrost'
+ - 'deploy':
+ project: 'openstack'
+ project-repo: 'https://git.openstack.org/openstack/openstack-ansible'
+ project-branch: '{branch}'
+ clone-location: '/opt/openstack-ansible'
+ - 'functest':
+ project: 'opnfv'
+ project-repo: 'https://gerrit.opnfv.org/gerrit/functest'
+ project-branch: 'master'
+ clone-location: '/opt/functest'
+#--------------------------------
+# jobs
+#--------------------------------
+ jobs:
+ - 'xci-{scenario}-{pod}-{distro}-daily-{stream}'
+ - 'xci-{phase}-{pod}-{distro}-daily-{stream}'
+
+#--------------------------------
+# job templates
+#--------------------------------
+- job-template:
+ name: 'xci-{scenario}-{pod}-{distro}-daily-{stream}'
+
+ disabled: '{obj:disabled}'
+
+ concurrent: false
+
+ properties:
+ - logrotate-default
+ - build-blocker:
+ use-build-blocker: true
+ blocking-jobs:
+ - 'xci-os-.*?-{pod}-daily-.*'
+ block-level: 'NODE'
+
+ parameters:
+ - string:
+ name: DEPLOY_SCENARIO
+ default: '{scenario}'
+ - label:
+ name: SLAVE_LABEL
+ default: '{slave-label}'
+
+ triggers:
+ - '{auto-trigger-name}'
+
+ builders:
+ - description-setter:
+ description: "Built on $NODE_NAME"
+ - trigger-builds:
+ - project: 'xci-provision-{pod}-{distro}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ same-node: true
+ block: true
+ - trigger-builds:
+ - project: 'xci-deploy-{pod}-{distro}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ same-node: true
+ block: true
+ - trigger-builds:
+ - project: 'xci-functest-{pod}-{distro}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ same-node: true
+ block: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
+
+ publishers:
+ - email:
+ recipients: fatih.degirmenci@ericsson.com yroblamo@redhat.com mchandras@suse.de jack.morgan@intel.com julienjut@gmail.com
+
+- job-template:
+ name: 'xci-{phase}-{pod}-{distro}-daily-{stream}'
+
+ disabled: '{obj:disabled}'
+
+ concurrent: false
+
+ properties:
+ - logrotate-default
+ - build-blocker:
+ use-build-blocker: true
+ blocking-jobs:
+ - 'xci-provision-.*?-{pod}-daily-.*'
+ - 'xci-deploy-.*?-{pod}-daily-.*'
+ - 'xci-functest-.*?-{pod}-daily-.*'
+ block-level: 'NODE'
+
+ parameters:
+ - string:
+ name: PROJECT
+ default: '{project}'
+ - string:
+ name: PROJECT_REPO
+ default: '{project-repo}'
+ - string:
+ name: DEPLOY_SCENARIO
+ default: '{scenario}'
+ - string:
+ name: CLONE_LOCATION
+ default: '{clone-location}'
+ - string:
+ name: DISTRO
+ default: '{distro}'
+ - string:
+ name: DIB_OS_RELEASE
+ default: '{dib-os-release}'
+ - string:
+ name: DIB_OS_ELEMENT
+ default: '{dib-os-element}'
+ - string:
+ name: EXTRA_DIB_ELEMENTS
+ default: '{extra-dib-elements}'
+ - string:
+ name: DIB_OS_PACKAGES
+ default: '{dib-os-packages}'
+ - string:
+ name: CLEAN_DIB_IMAGES
+ default: 'true'
+
+ scm:
+ - git:
+ url: '$PROJECT_REPO'
+ branches:
+ - 'origin/{project-branch}'
+ wipe-workspace: true
+ timeout: 15
+
+ builders:
+ - description-setter:
+ description: "Built on $NODE_NAME - Scenario: $DEPLOY_SCENARIO"
+ - 'xci-{phase}-builder'
+#---------------------------
+# builder macros
+#---------------------------
+- builder:
+ name: xci-provision-builder
+ builders:
+ - shell:
+ !include-raw: ./xci-provision.sh
+- builder:
+ name: xci-deploy-builder
+ builders:
+ - shell:
+ !include-raw: ./xci-deploy.sh
+- builder:
+ name: xci-functest-builder
+ builders:
+ - shell:
+ !include-raw: ./xci-functest.sh
diff --git a/jjb/xci/xci-deploy.sh b/jjb/xci/xci-deploy.sh
new file mode 100755
index 000000000..b97b24e47
--- /dev/null
+++ b/jjb/xci/xci-deploy.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Deployment via openstack-ansible"
diff --git a/jjb/xci/xci-functest.sh b/jjb/xci/xci-functest.sh
new file mode 100755
index 000000000..0f58dfefc
--- /dev/null
+++ b/jjb/xci/xci-functest.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Functional testing with functest"
diff --git a/jjb/xci/xci-provision.sh b/jjb/xci/xci-provision.sh
new file mode 100755
index 000000000..b77c79caa
--- /dev/null
+++ b/jjb/xci/xci-provision.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Provisioning via bifrost"
diff --git a/prototypes/bifrost/scripts/destroy-env.sh b/prototypes/bifrost/scripts/destroy-env.sh
index b73092b0f..1138da904 100755
--- a/prototypes/bifrost/scripts/destroy-env.sh
+++ b/prototypes/bifrost/scripts/destroy-env.sh
@@ -20,6 +20,10 @@ for vm in $(virsh list --all --name); do
virsh destroy $vm || true
virsh undefine $vm || true
done
+# Delete all hosts from vbmc (look for a port number)
+for vm in $(vbmc list | awk '/[0-9]/{{ print $2 }}'); do
+ vbmc delete $vm
+done
service ironic-conductor stop || true
@@ -47,6 +51,6 @@ rm -rf /var/lib/libvirt/images/*.qcow2
echo "restarting services"
service dnsmasq restart || true
service libvirtd restart
-service ironic-api restart || true
+service ironic-api restart || true
service ironic-conductor start || true
service ironic-inspector restart || true
diff --git a/prototypes/bifrost/scripts/osa-bifrost-deployment.sh b/prototypes/bifrost/scripts/osa-bifrost-deployment.sh
new file mode 100755
index 000000000..cca30c2fc
--- /dev/null
+++ b/prototypes/bifrost/scripts/osa-bifrost-deployment.sh
@@ -0,0 +1,142 @@
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2016 Ericsson AB and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+set -eux
+set -o pipefail
+export PYTHONUNBUFFERED=1
+SCRIPT_HOME="$(cd "$(dirname "$0")" && pwd)"
+BIFROST_HOME=$SCRIPT_HOME/..
+ANSIBLE_INSTALL_ROOT=${ANSIBLE_INSTALL_ROOT:-/opt/stack}
+ENABLE_VENV="false"
+USE_DHCP="false"
+USE_VENV="false"
+BUILD_IMAGE=true
+BAREMETAL_DATA_FILE=${BAREMETAL_DATA_FILE:-'/tmp/baremetal.json'}
+PROVISION_WAIT_TIMEOUT=${PROVISION_WAIT_TIMEOUT:-3600}
+
+# Set defaults for ansible command-line options to drive the different
+# tests.
+
+# NOTE(TheJulia/cinerama): The variables defined on the command line
+# for the default and DHCP tests are to drive the use of Cirros as the
+# deployed operating system, and as such sets the test user to cirros,
+# and writes a debian style interfaces file out to the configuration
+# drive as cirros does not support the network_info.json format file
+# placed in the configuration drive. The "build image" test does not
+# use cirros.
+
+TEST_VM_NUM_NODES=6
+export TEST_VM_NODE_NAMES="jumphost controller00 controller01 controller02 compute00 compute01"
+export VM_DOMAIN_TYPE="kvm"
+# 8 vCPU, 60 GB HDD are minimum equipment
+export VM_CPU=${VM_CPU:-8}
+export VM_DISK=${VM_DISK:-100}
+export VM_DISK_CACHE=${VM_DISK_CACHE:-unsafe}
+TEST_PLAYBOOK="test-bifrost-infracloud.yaml"
+USE_INSPECTOR=true
+USE_CIRROS=false
+TESTING_USER=root
+# seting the memory to 16 GB to make more easily success
+# 8 GB RAM is minimum equipment, but it work with at least 12 GB.
+VM_MEMORY_SIZE=${VM_MEMORY_SIZE:-16384}
+DOWNLOAD_IPA=true
+CREATE_IPA_IMAGE=false
+INSPECT_NODES=true
+INVENTORY_DHCP=false
+INVENTORY_DHCP_STATIC_IP=false
+WRITE_INTERFACES_FILE=true
+
+# Set BIFROST_INVENTORY_SOURCE
+export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.json
+
+# DIB custom elements path
+export ELEMENTS_PATH=/opt/puppet-infracloud/files/elements
+
+# settings for console access
+export DIB_DEV_USER_PWDLESS_SUDO=yes
+export DIB_DEV_USER_PASSWORD=devuser
+
+# settings for distro: trusty/ubuntu-minimal, 7/centos7
+export DIB_OS_RELEASE=${DIB_OS_RELEASE:-xenial}
+export DIB_OS_ELEMENT=${DIB_OS_ELEMENT:-ubuntu-minimal}
+
+# for centos 7: "vim,less,bridge-utils,iputils,rsyslog,curl"
+export DIB_OS_PACKAGES=${DIB_OS_PACKAGES:-"vlan,vim,less,bridge-utils,sudo,language-pack-en,iputils-ping,rsyslog,curl,python,debootstrap,ifenslave,ifenslave-2.6,lsof,lvm2,tcpdump,nfs-kernel-server,chrony"}
+
+# Additional dib elements
+export EXTRA_DIB_ELEMENTS=${EXTRA_DIB_ELEMENTS:-"openssh-server"}
+
+# Source Ansible
+# NOTE(TheJulia): Ansible stable-1.9 source method tosses an error deep
+# under the hood which -x will detect, so for this step, we need to suspend
+# and then re-enable the feature.
+set +x +o nounset
+$SCRIPT_HOME/env-setup.sh
+source ${ANSIBLE_INSTALL_ROOT}/ansible/hacking/env-setup
+ANSIBLE=$(which ansible-playbook)
+set -x -o nounset
+
+logs_on_exit() {
+ $SCRIPT_HOME/collect-test-info.sh
+}
+trap logs_on_exit EXIT
+
+# Change working directory
+cd $BIFROST_HOME/playbooks
+
+# Syntax check of dynamic inventory test path
+for task in syntax-check list-tasks; do
+ ${ANSIBLE} -vvvv \
+ -i inventory/localhost \
+ test-bifrost-create-vm.yaml \
+ --${task}
+ ${ANSIBLE} -vvvv \
+ -i inventory/localhost \
+ ${TEST_PLAYBOOK} \
+ --${task} \
+ -e testing_user=${TESTING_USER}
+done
+
+# Create the test VMS
+${ANSIBLE} -vvvv \
+ -i inventory/localhost \
+ test-bifrost-create-vm.yaml \
+ -e test_vm_num_nodes=${TEST_VM_NUM_NODES} \
+ -e test_vm_memory_size=${VM_MEMORY_SIZE} \
+ -e enable_venv=${ENABLE_VENV} \
+ -e test_vm_domain_type=${VM_DOMAIN_TYPE} \
+ -e baremetal_json_file=${BAREMETAL_DATA_FILE}
+
+# Execute the installation and VM startup test.
+${ANSIBLE} -vvvv \
+ -i inventory/bifrost_inventory.py \
+ ${TEST_PLAYBOOK} \
+ -e use_cirros=${USE_CIRROS} \
+ -e testing_user=${TESTING_USER} \
+ -e test_vm_num_nodes=${TEST_VM_NUM_NODES} \
+ -e inventory_dhcp=${INVENTORY_DHCP} \
+ -e inventory_dhcp_static_ip=${INVENTORY_DHCP_STATIC_IP} \
+ -e enable_venv=${ENABLE_VENV} \
+ -e enable_inspector=${USE_INSPECTOR} \
+ -e inspect_nodes=${INSPECT_NODES} \
+ -e download_ipa=${DOWNLOAD_IPA} \
+ -e create_ipa_image=${CREATE_IPA_IMAGE} \
+ -e write_interfaces_file=${WRITE_INTERFACES_FILE} \
+ -e ipv4_gateway=192.168.122.1 \
+ -e wait_timeout=${PROVISION_WAIT_TIMEOUT}
+EXITCODE=$?
+
+if [ $EXITCODE != 0 ]; then
+ echo "****************************"
+ echo "Test failed. See logs folder"
+ echo "****************************"
+fi
+
+exit $EXITCODE
diff --git a/prototypes/openstack-ansible/scripts/osa_deploy.sh b/prototypes/openstack-ansible/scripts/osa_deploy.sh
index 95f593194..79625d211 100755
--- a/prototypes/openstack-ansible/scripts/osa_deploy.sh
+++ b/prototypes/openstack-ansible/scripts/osa_deploy.sh
@@ -4,7 +4,6 @@ export OSA_PATH=/opt/openstack-ansible
export LOG_PATH=$OSA_PATH/log
export PLAYBOOK_PATH=$OSA_PATH/playbooks
export OSA_BRANCH=${OSA_BRANCH:-"master"}
-
JUMPHOST_IP="192.168.122.2"
sudo /bin/rm -rf $LOG_PATH
diff --git a/prototypes/openstack-ansible/var/ubuntu.yml b/prototypes/openstack-ansible/var/ubuntu.yml
index 71f54ecb5..9464384b3 100644
--- a/prototypes/openstack-ansible/var/ubuntu.yml
+++ b/prototypes/openstack-ansible/var/ubuntu.yml
@@ -2,5 +2,7 @@
OSA_URL: https://git.openstack.org/openstack/openstack-ansible
OSA_PATH: /opt/openstack-ansible
OSA_ETC_PATH: /etc/openstack_deploy
+OSA_BRANCH: "{{ lookup('env','OSA_BRANCH') }}"
+
JUMPHOST_IP: 192.168.122.2
host_info: {'jumphost':{'MGMT_IP': '172.29.236.10','VLAN_IP': '192.168.122.2', 'STORAGE_IP': '172.29.244.10'},'controller00':{'MGMT_IP': '172.29.236.11','VLAN_IP': '192.168.122.3', 'STORAGE_IP': '172.29.244.11'},'controller01':{'MGMT_IP': '172.29.236.12','VLAN_IP': '192.168.122.4', 'STORAGE_IP': '172.29.244.12'},'controller02':{'MGMT_IP': '172.29.236.13','VLAN_IP': '192.168.122.5', 'STORAGE_IP': '172.29.240.13'},'compute00':{'MGMT_IP': '172.29.236.14','VLAN_IP': '192.168.122.6','VLAN_IP_SECOND': '173.29.241.1','VXLAN_IP': '172.29.240.14', 'STORAGE_IP': '172.29.244.14'},'compute01':{'MGMT_IP': '172.29.236.15','VLAN_IP': '192.168.122.7','VLAN_IP_SECOND': '173.29.241.2','VXLAN_IP': '172.29.240.15', 'STORAGE_IP': '172.29.244.15'}}
diff --git a/prototypes/puppet-infracloud/creds/clouds.yaml b/prototypes/puppet-infracloud/creds/clouds.yaml
index eb44db66c..cc27da28a 100644
--- a/prototypes/puppet-infracloud/creds/clouds.yaml
+++ b/prototypes/puppet-infracloud/creds/clouds.yaml
@@ -1,3 +1,4 @@
+---
clouds:
opnfv:
verify: False
diff --git a/prototypes/puppet-infracloud/hiera/common.yaml b/prototypes/puppet-infracloud/hiera/common.yaml
index 1943f660b..634d96cb5 100644
--- a/prototypes/puppet-infracloud/hiera/common.yaml
+++ b/prototypes/puppet-infracloud/hiera/common.yaml
@@ -1,3 +1,4 @@
+---
keystone_rabbit_password: pass
neutron_rabbit_password: pass
nova_rabbit_password: pass
diff --git a/prototypes/puppet-infracloud/hiera/common_baremetal.yaml b/prototypes/puppet-infracloud/hiera/common_baremetal.yaml
index a8d69a05d..015612c99 100644
--- a/prototypes/puppet-infracloud/hiera/common_baremetal.yaml
+++ b/prototypes/puppet-infracloud/hiera/common_baremetal.yaml
@@ -1,3 +1,4 @@
+---
keystone_rabbit_password: pass
neutron_rabbit_password: pass
nova_rabbit_password: pass
@@ -134,8 +135,8 @@ ironic_inventory:
ipv4_subnet_mask: 255.255.255.192
name: controller00.opnfvlocal
nics:
- - mac: a4:bf:01:01:a9:fc
- - mac: 00:1e:67:f6:9b:35
+ - mac: a4:bf:01:01:a9:fc
+ - mac: 00:1e:67:f6:9b:35
properties:
cpu_arch: x86_64
cpus: '44'
@@ -156,8 +157,8 @@ ironic_inventory:
ipv4_subnet_mask: 255.255.255.0
name: compute00.opnfvlocal
nics:
- - mac: a4:bf:01:01:a9:d4
- - mac: 00:1e:67:f6:9b:37
+ - mac: a4:bf:01:01:a9:d4
+ - mac: 00:1e:67:f6:9b:37
properties:
cpu_arch: x86_64
cpus: '44'
diff --git a/utils/lab-reconfiguration/foreman.yaml b/utils/lab-reconfiguration/foreman.yaml
index 48ab9ab6e..0a37be2e1 100644
--- a/utils/lab-reconfiguration/foreman.yaml
+++ b/utils/lab-reconfiguration/foreman.yaml
@@ -1,3 +1,4 @@
+---
# Vnic configuration for foreman deploy
network:
diff --git a/utils/lab-reconfiguration/fuel.yaml b/utils/lab-reconfiguration/fuel.yaml
index eb9028b2c..15e64c452 100644
--- a/utils/lab-reconfiguration/fuel.yaml
+++ b/utils/lab-reconfiguration/fuel.yaml
@@ -1,3 +1,4 @@
+---
# Vnic configuration for fuel deploy
network:
diff --git a/utils/test/dashboard/dashboard/functest/testcases.yaml b/utils/test/dashboard/dashboard/functest/testcases.yaml
index 9c33d2e6b..85cb8b292 100644
--- a/utils/test/dashboard/dashboard/functest/testcases.yaml
+++ b/utils/test/dashboard/dashboard/functest/testcases.yaml
@@ -1,3 +1,4 @@
+---
functest:
-
name: tempest_smoke_serial
diff --git a/utils/test/dashboard/dashboard/qtip/testcases.yaml b/utils/test/dashboard/dashboard/qtip/testcases.yaml
index cd337cd73..dfa9cc2db 100644
--- a/utils/test/dashboard/dashboard/qtip/testcases.yaml
+++ b/utils/test/dashboard/dashboard/qtip/testcases.yaml
@@ -1,3 +1,4 @@
+---
qtip:
-
name: compute_test_suite
@@ -18,7 +19,7 @@ qtip:
fields:
- field: details.index
-
- name:storage_test_suite
+ name: storage_test_suite
format: qpi
test_family: storage
visualizations:
diff --git a/utils/test/reporting/functest/testCase.py b/utils/test/reporting/functest/testCase.py
index f77136e11..c89e619c0 100644
--- a/utils/test/reporting/functest/testCase.py
+++ b/utils/test/reporting/functest/testCase.py
@@ -28,6 +28,7 @@ class TestCase(object):
'tempest_smoke_serial': 'Tempest (smoke)',
'tempest_full_parallel': 'Tempest (full)',
'tempest_defcore': 'Tempest (Defcore)',
+ 'refstack_defcore': 'Refstack',
'rally_sanity': 'Rally (smoke)',
'bgpvpn': 'bgpvpn',
'rally_full': 'Rally (full)',
@@ -47,6 +48,11 @@ class TestCase(object):
'snaps_smoke': 'SNAPS',
'snaps_health_check': 'Health (dhcp)',
'netready': 'Netready',
+ 'fds': 'FDS',
+ 'cloudify_ims': 'vIMS (Cloudify)',
+ 'orchestra_ims': 'OpenIMS (OpenBaton)',
+ 'opera_ims': 'vIMS (Open-O)',
+ 'vyos_vrouter': 'vyos',
'barometer': 'Barometer'}
try:
self.displayName = display_name_matrix[self.name]
@@ -127,6 +133,7 @@ class TestCase(object):
'tempest_smoke_serial': 'tempest_smoke_serial',
'tempest_full_parallel': 'tempest_full_parallel',
'tempest_defcore': 'tempest_defcore',
+ 'refstack_defcore': 'refstack_defcore',
'rally_sanity': 'rally_sanity',
'bgpvpn': 'bgpvpn',
'rally_full': 'rally_full',
@@ -146,6 +153,11 @@ class TestCase(object):
'snaps_smoke': 'snaps_smoke',
'snaps_health_check': 'snaps_health_check',
'netready': 'gluon_vping',
+ 'fds': 'fds',
+ 'cloudify_ims': 'cloudify_ims',
+ 'orchestra_ims': 'orchestra_ims',
+ 'opera_ims': 'opera_ims',
+ 'vyos_vrouter': 'vyos_vrouter',
'barometer': 'barometercollectd'}
try:
return test_match_matrix[self.name]
diff --git a/utils/test/reporting/reporting.yaml b/utils/test/reporting/reporting.yaml
index 33c7cc257..8c5ce1383 100644
--- a/utils/test/reporting/reporting.yaml
+++ b/utils/test/reporting/reporting.yaml
@@ -1,3 +1,4 @@
+---
general:
installers:
- apex
@@ -20,12 +21,12 @@ general:
directories:
# Relative to the path where the repo is cloned:
- dir_reporting: utils/tests/reporting/
- dir_log: utils/tests/reporting/log/
- dir_conf: utils/tests/reporting/conf/
- dir_utils: utils/tests/reporting/utils/
- dir_templates: utils/tests/reporting/templates/
- dir_display: utils/tests/reporting/display/
+ dir_reporting: utils/tests/reporting/
+ dir_log: utils/tests/reporting/log/
+ dir_conf: utils/tests/reporting/conf/
+ dir_utils: utils/tests/reporting/utils/
+ dir_templates: utils/tests/reporting/templates/
+ dir_display: utils/tests/reporting/display/
url: testresults.opnfv.org/reporting/
@@ -49,8 +50,8 @@ functest:
test_conf: https://git.opnfv.org/cgit/functest/plain/functest/ci/testcases.yaml
log_level: ERROR
jenkins_url: https://build.opnfv.org/ci/view/functest/job/
- exclude_noha: False
- exclude_virtual: False
+ exclude_noha: "False"
+ exclude_virtual: "False"
yardstick:
test_conf: https://git.opnfv.org/cgit/yardstick/plain/tests/ci/report_config.yaml
@@ -58,7 +59,7 @@ yardstick:
storperf:
test_list:
- - snia_steady_state
+ - snia_steady_state
log_level: ERROR
qtip:
diff --git a/utils/test/testapi/update/test.yml b/utils/test/testapi/update/test.yml
index a8868720d..943105c5f 100644
--- a/utils/test/testapi/update/test.yml
+++ b/utils/test/testapi/update/test.yml
@@ -1,7 +1,7 @@
---
- hosts: "{{ host }}"
remote_user: "{{ user }}"
- become: yes
+ become: "yes"
become_method: sudo
vars:
user: "root"
diff --git a/utils/test/testapi/update/update.yml b/utils/test/testapi/update/update.yml
index e6663d905..18b75b6bf 100644
--- a/utils/test/testapi/update/update.yml
+++ b/utils/test/testapi/update/update.yml
@@ -1,7 +1,7 @@
---
- hosts: "{{ host }}"
remote_user: "{{ user }}"
- become: yes
+ become: "yes"
become_method: sudo
vars:
user: "root"
@@ -47,4 +47,4 @@
- name: remove temporary update directory
file:
path: "{{ update_path }}"
- state: absent \ No newline at end of file
+ state: absent
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/README.md b/utils/test/vnfcatalogue/VNF_Catalogue/README.md
index 32ad65416..22d429072 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/README.md
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/README.md
@@ -5,8 +5,13 @@
First install the dependencies
- ```npm install```
+ ```npm install```
+
+set time zone(Important)
+ Set same timezone in both nodejs server and mysql server. Something
+ similar to below can be used:
+ ``` SET GLOBAL time_zone = '+00:00'; ```
Then Start the Server
- ```npm start```
+ ```npm start```
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/app.js b/utils/test/vnfcatalogue/VNF_Catalogue/app.js
index 0f842b62d..4b6add2be 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/app.js
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/app.js
@@ -13,9 +13,17 @@ var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
+var validator = require('express-validator');
var routes = require('./routes/index');
var search_projects = require('./routes/search_projects');
+var project_profile = require('./routes/project_profile');
+var add_project = require('./routes/add_project');
+var add_tag = require('./routes/add_tag');
+var search_tag = require('./routes/search_tag');
+var search_vnf = require('./routes/search_vnf');
+var vnf_tag_association = require('./routes/vnf_tag_association');
+
var app = express();
@@ -23,27 +31,35 @@ var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
+db_pool = require('./database').pool;
+
// Database
-var db = require('mysql2');
+//var db = require('mysql2');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
+app.use(validator());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Make our db accessible to our router
app.use(function(req,res,next){
- req.db = db;
+ //db_pool size 50 default
+ req.db_pool = db_pool;
next();
});
app.use('/', routes);
app.use('/search_projects', search_projects);
-
-
+app.use('/project_profile', project_profile);
+app.use('/add_project', add_project);
+app.use('/add_tag', add_tag);
+app.use('/search_tag', search_tag);
+app.use('/search_vnf', search_vnf);
+app.use('/vnf_tag_association', vnf_tag_association);
// Some Error handling for now #TODO Remove
/// catch 404 and forwarding to error handler
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/database.js b/utils/test/vnfcatalogue/VNF_Catalogue/database.js
new file mode 100644
index 000000000..b31310480
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/database.js
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var mysql = require('mysql');
+
+var pool = mysql.createPool({
+ host: 'localhost',
+ user: 'myuser',
+ password: 'mypassword',
+ database: 'vnf_catalogue',
+ connectionLimit: 50,
+ supportBigNumbers: true,
+ multipleStatements: true,
+ dateStrings: 'date'
+});
+
+exports.pool = pool;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/package.json b/utils/test/vnfcatalogue/VNF_Catalogue/package.json
index 7c6a86730..414b42425 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/package.json
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/package.json
@@ -13,6 +13,11 @@
"jade": "~1.11.0",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0",
- "mysql2": "*"
+ "mysql": "*",
+ "express-validator": "*",
+ "nodemon": "*",
+ "async": "*",
+ "multer": "*",
+ "octonode": "*"
}
-} \ No newline at end of file
+}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js
new file mode 100644
index 000000000..11235e75b
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js
@@ -0,0 +1,7 @@
+/*!
+ * typeahead.js 0.10.4
+ * https://github.com/twitter/typeahead.js
+ * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
+ */
+
+!function(a){var b=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},toStr:function(a){return b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},noop:function(){}}}(),c="0.10.4",d=function(){"use strict";function a(a){return a=b.toStr(a),a?a.split(/\s+/):[]}function c(a){return a=b.toStr(a),a?a.split(/\W+/):[]}function d(a){return function(){var c=[].slice.call(arguments,0);return function(d){var e=[];return b.each(c,function(c){e=e.concat(a(b.toStr(d[c])))}),e}}}return{nonword:c,whitespace:a,obj:{nonword:d(c),whitespace:d(a)}}}(),e=function(){"use strict";function c(c){this.maxSize=b.isNumber(c)?c:100,this.reset(),this.maxSize<=0&&(this.set=this.get=a.noop)}function d(){this.head=this.tail=null}function e(a,b){this.key=a,this.val=b,this.prev=this.next=null}return b.mixin(c.prototype,{set:function(a,b){var c,d=this.list.tail;this.size>=this.maxSize&&(this.list.remove(d),delete this.hash[d.key]),(c=this.hash[a])?(c.val=b,this.list.moveToFront(c)):(c=new e(a,b),this.list.add(c),this.hash[a]=c,this.size++)},get:function(a){var b=this.hash[a];return b?(this.list.moveToFront(b),b.val):void 0},reset:function(){this.size=0,this.hash={},this.list=new d}}),b.mixin(d.prototype,{add:function(a){this.head&&(a.next=this.head,this.head.prev=a),this.head=a,this.tail=this.tail||a},remove:function(a){a.prev?a.prev.next=a.next:this.head=a.next,a.next?a.next.prev=a.prev:this.tail=a.prev},moveToFront:function(a){this.remove(a),this.add(a)}}),c}(),f=function(){"use strict";function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+b.escapeRegExChars(this.prefix))}function c(){return(new Date).getTime()}function d(a){return JSON.stringify(b.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return b.isNumber(g)?f.setItem(this._ttlKey(a),d(c()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return b.isNumber(d)&&c()>d?!0:!1}}:{get:b.noop,set:b.noop,remove:b.noop,clear:b.noop,isExpired:b.noop},b.mixin(a.prototype,g),a}(),g=function(){"use strict";function c(b){b=b||{},this.cancelled=!1,this.lastUrl=null,this._send=b.transport?d(b.transport):a.ajax,this._get=b.rateLimiter?b.rateLimiter(this._get):this._get,this._cache=b.cache===!1?new e(0):i}function d(c){return function(d,e){function f(a){b.defer(function(){h.resolve(a)})}function g(a){b.defer(function(){h.reject(a)})}var h=a.Deferred();return c(d,e,f,g),h}}var f=0,g={},h=6,i=new e(10);return c.setMaxPendingRequests=function(a){h=a},c.resetCache=function(){i.reset()},b.mixin(c.prototype,{_get:function(a,b,c){function d(b){c&&c(null,b),k._cache.set(a,b)}function e(){c&&c(!0)}function i(){f--,delete g[a],k.onDeckRequestArgs&&(k._get.apply(k,k.onDeckRequestArgs),k.onDeckRequestArgs=null)}var j,k=this;this.cancelled||a!==this.lastUrl||((j=g[a])?j.done(d).fail(e):h>f?(f++,g[a]=this._send(a,b).done(d).fail(e).always(i)):this.onDeckRequestArgs=[].slice.call(arguments,0))},get:function(a,c,d){var e;return b.isFunction(c)&&(d=c,c={}),this.cancelled=!1,this.lastUrl=a,(e=this._cache.get(a))?b.defer(function(){d&&d(null,e)}):this._get(a,c,d),!!e},cancel:function(){this.cancelled=!0}}),c}(),h=function(){"use strict";function c(b){b=b||{},b.datumTokenizer&&b.queryTokenizer||a.error("datumTokenizer and queryTokenizer are both required"),this.datumTokenizer=b.datumTokenizer,this.queryTokenizer=b.queryTokenizer,this.reset()}function d(a){return a=b.filter(a,function(a){return!!a}),a=b.map(a,function(a){return a.toLowerCase()})}function e(){return{ids:[],children:{}}}function f(a){for(var b={},c=[],d=0,e=a.length;e>d;d++)b[a[d]]||(b[a[d]]=!0,c.push(a[d]));return c}function g(a,b){function c(a,b){return a-b}var d=0,e=0,f=[];a=a.sort(c),b=b.sort(c);for(var g=a.length,h=b.length;g>d&&h>e;)a[d]<b[e]?d++:a[d]>b[e]?e++:(f.push(a[d]),d++,e++);return f}return b.mixin(c.prototype,{bootstrap:function(a){this.datums=a.datums,this.trie=a.trie},add:function(a){var c=this;a=b.isArray(a)?a:[a],b.each(a,function(a){var f,g;f=c.datums.push(a)-1,g=d(c.datumTokenizer(a)),b.each(g,function(a){var b,d,g;for(b=c.trie,d=a.split("");g=d.shift();)b=b.children[g]||(b.children[g]=e()),b.ids.push(f)})})},get:function(a){var c,e,h=this;return c=d(this.queryTokenizer(a)),b.each(c,function(a){var b,c,d,f;if(e&&0===e.length)return!1;for(b=h.trie,c=a.split("");b&&(d=c.shift());)b=b.children[d];return b&&0===c.length?(f=b.ids.slice(0),void(e=e?g(e,f):f)):(e=[],!1)}),e?b.map(f(e),function(a){return h.datums[a]}):[]},reset:function(){this.datums=[],this.trie=e()},serialize:function(){return{datums:this.datums,trie:this.trie}}}),c}(),i=function(){"use strict";function d(a){return a.local||null}function e(d){var e,f;return f={url:null,thumbprint:"",ttl:864e5,filter:null,ajax:{}},(e=d.prefetch||null)&&(e=b.isString(e)?{url:e}:e,e=b.mixin(f,e),e.thumbprint=c+e.thumbprint,e.ajax.type=e.ajax.type||"GET",e.ajax.dataType=e.ajax.dataType||"json",!e.url&&a.error("prefetch requires url to be set")),e}function f(c){function d(a){return function(c){return b.debounce(c,a)}}function e(a){return function(c){return b.throttle(c,a)}}var f,g;return g={url:null,cache:!0,wildcard:"%QUERY",replace:null,rateLimitBy:"debounce",rateLimitWait:300,send:null,filter:null,ajax:{}},(f=c.remote||null)&&(f=b.isString(f)?{url:f}:f,f=b.mixin(g,f),f.rateLimiter=/^throttle$/i.test(f.rateLimitBy)?e(f.rateLimitWait):d(f.rateLimitWait),f.ajax.type=f.ajax.type||"GET",f.ajax.dataType=f.ajax.dataType||"json",delete f.rateLimitBy,delete f.rateLimitWait,!f.url&&a.error("remote requires url to be set")),f}return{local:d,prefetch:e,remote:f}}();!function(c){"use strict";function e(b){b&&(b.local||b.prefetch||b.remote)||a.error("one of local, prefetch, or remote is required"),this.limit=b.limit||5,this.sorter=j(b.sorter),this.dupDetector=b.dupDetector||k,this.local=i.local(b),this.prefetch=i.prefetch(b),this.remote=i.remote(b),this.cacheKey=this.prefetch?this.prefetch.cacheKey||this.prefetch.url:null,this.index=new h({datumTokenizer:b.datumTokenizer,queryTokenizer:b.queryTokenizer}),this.storage=this.cacheKey?new f(this.cacheKey):null}function j(a){function c(b){return b.sort(a)}function d(a){return a}return b.isFunction(a)?c:d}function k(){return!1}var l,m;return l=c.Bloodhound,m={data:"data",protocol:"protocol",thumbprint:"thumbprint"},c.Bloodhound=e,e.noConflict=function(){return c.Bloodhound=l,e},e.tokenizers=d,b.mixin(e.prototype,{_loadPrefetch:function(b){function c(a){f.clear(),f.add(b.filter?b.filter(a):a),f._saveToStorage(f.index.serialize(),b.thumbprint,b.ttl)}var d,e,f=this;return(d=this._readFromStorage(b.thumbprint))?(this.index.bootstrap(d),e=a.Deferred().resolve()):e=a.ajax(b.url,b.ajax).done(c),e},_getFromRemote:function(a,b){function c(a,c){b(a?[]:f.remote.filter?f.remote.filter(c):c)}var d,e,f=this;if(this.transport)return a=a||"",e=encodeURIComponent(a),d=this.remote.replace?this.remote.replace(this.remote.url,a):this.remote.url.replace(this.remote.wildcard,e),this.transport.get(d,this.remote.ajax,c)},_cancelLastRemoteRequest:function(){this.transport&&this.transport.cancel()},_saveToStorage:function(a,b,c){this.storage&&(this.storage.set(m.data,a,c),this.storage.set(m.protocol,location.protocol,c),this.storage.set(m.thumbprint,b,c))},_readFromStorage:function(a){var b,c={};return this.storage&&(c.data=this.storage.get(m.data),c.protocol=this.storage.get(m.protocol),c.thumbprint=this.storage.get(m.thumbprint)),b=c.thumbprint!==a||c.protocol!==location.protocol,c.data&&!b?c.data:null},_initialize:function(){function c(){e.add(b.isFunction(f)?f():f)}var d,e=this,f=this.local;return d=this.prefetch?this._loadPrefetch(this.prefetch):a.Deferred().resolve(),f&&d.done(c),this.transport=this.remote?new g(this.remote):null,this.initPromise=d.promise()},initialize:function(a){return!this.initPromise||a?this._initialize():this.initPromise},add:function(a){this.index.add(a)},get:function(a,c){function d(a){var d=f.slice(0);b.each(a,function(a){var c;return c=b.some(d,function(b){return e.dupDetector(a,b)}),!c&&d.push(a),d.length<e.limit}),c&&c(e.sorter(d))}var e=this,f=[],g=!1;f=this.index.get(a),f=this.sorter(f).slice(0,this.limit),f.length<this.limit?g=this._getFromRemote(a,d):this._cancelLastRemoteRequest(),g||(f.length>0||!this.transport)&&c&&c(f)},clear:function(){this.index.reset()},clearPrefetchCache:function(){this.storage&&this.storage.clear()},clearRemoteCache:function(){this.transport&&g.resetCache()},ttAdapter:function(){return b.bind(this.get,this)}}),e}(this);var j=function(){return{wrapper:'<span class="twitter-typeahead"></span>',dropdown:'<span class="tt-dropdown-menu"></span>',dataset:'<div class="tt-dataset-%CLASS%"></div>',suggestions:'<span class="tt-suggestions"></span>',suggestion:'<div class="tt-suggestion"></div>'}}(),k=function(){"use strict";var a={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),b.isMsie()&&b.isMsie()<=7&&b.mixin(a.input,{marginTop:"-1px"}),a}(),l=function(){"use strict";function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return b.mixin(c.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),c}(),m=function(){"use strict";function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0,f=a.length;!d&&f>e;e+=1)d=a[e].apply(b,c)===!1;return!d}return d}function g(){var a;return a=window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}function h(a,b){return a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var i=/\s+/,j=g();return{onSync:c,onAsync:b,off:d,trigger:e}}(),n=function(a){"use strict";function c(a,c,d){for(var e,f=[],g=0,h=a.length;h>g;g++)f.push(b.escapeRegExChars(a[g]));return e=d?"\\b("+f.join("|")+")\\b":"("+f.join("|")+")",c?new RegExp(e):new RegExp(e,"i")}var d={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(e){function f(b){var c,d,f;return(c=h.exec(b.data))&&(f=a.createElement(e.tagName),e.className&&(f.className=e.className),d=b.splitText(c.index),d.splitText(c[0].length),f.appendChild(d.cloneNode(!0)),b.parentNode.replaceChild(f,d)),!!c}function g(a,b){for(var c,d=3,e=0;e<a.childNodes.length;e++)c=a.childNodes[e],c.nodeType===d?e+=b(c)?1:0:g(c,b)}var h;e=b.mixin({},d,e),e.node&&e.pattern&&(e.pattern=b.isArray(e.pattern)?e.pattern:[e.pattern],h=c(e.pattern,e.caseSensitive,e.wordsOnly),g(e.node,f))}}(window.document),o=function(){"use strict";function c(c){var e,f,h,i,j=this;c=c||{},c.input||a.error("input is missing"),e=b.bind(this._onBlur,this),f=b.bind(this._onFocus,this),h=b.bind(this._onKeydown,this),i=b.bind(this._onInput,this),this.$hint=a(c.hint),this.$input=a(c.input).on("blur.tt",e).on("focus.tt",f).on("keydown.tt",h),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=b.noop),b.isMsie()?this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){g[a.which||a.keyCode]||b.defer(b.bind(j._onInput,j,a))}):this.$input.on("input.tt",i),this.query=this.$input.val(),this.$overflowHelper=d(this.$input)}function d(b){return a('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function e(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function f(a){return a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var g;return g={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},b.mixin(c.prototype,m,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(a){var b=g[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(a,b){var c,d,e;switch(a){case"tab":d=this.getHint(),e=this.getInputValue(),c=d&&d!==e&&!f(b);break;case"up":case"down":c=!f(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var c;switch(a){case"tab":c=!f(b);break;default:c=!0}return c},_checkInputValue:function(){var a,b,c;a=this.getInputValue(),b=e(a,this.query),c=b?this.query.length!==a.length:!1,this.query=a,b?c&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),b?this.clearHint():this._checkInputValue()},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),d=""!==a&&c&&!this.hasOverflow(),!d&&this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var a=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var a,c,d;return a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:document.selection?(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null}}),c}(),p=function(){"use strict";function c(c){c=c||{},c.templates=c.templates||{},c.source||a.error("missing source"),c.name&&!f(c.name)&&a.error("invalid dataset name: "+c.name),this.query=null,this.highlight=!!c.highlight,this.name=c.name||b.getUniqueId(),this.source=c.source,this.displayFn=d(c.display||c.displayKey),this.templates=e(c.templates,this.displayFn),this.$el=a(j.dataset.replace("%CLASS%",this.name))}function d(a){function c(b){return b[a]}return a=a||"value",b.isFunction(a)?a:c}function e(a,c){function d(a){return"<p>"+c(a)+"</p>"}return{empty:a.empty&&b.templatify(a.empty),header:a.header&&b.templatify(a.header),footer:a.footer&&b.templatify(a.footer),suggestion:a.suggestion||d}}function f(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var g="ttDataset",h="ttValue",i="ttDatum";return c.extractDatasetName=function(b){return a(b).data(g)},c.extractValue=function(b){return a(b).data(h)},c.extractDatum=function(b){return a(b).data(i)},b.mixin(c.prototype,m,{_render:function(c,d){function e(){return p.templates.empty({query:c,isEmpty:!0})}function f(){function e(b){var c;return c=a(j.suggestion).append(p.templates.suggestion(b)).data(g,p.name).data(h,p.displayFn(b)).data(i,b),c.children().each(function(){a(this).css(k.suggestionChild)}),c}var f,l;return f=a(j.suggestions).css(k.suggestions),l=b.map(d,e),f.append.apply(f,l),p.highlight&&n({className:"tt-highlight",node:f[0],pattern:c}),f}function l(){return p.templates.header({query:c,isEmpty:!o})}function m(){return p.templates.footer({query:c,isEmpty:!o})}if(this.$el){var o,p=this;this.$el.empty(),o=d&&d.length,!o&&this.templates.empty?this.$el.html(e()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null):o&&this.$el.html(f()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null),this.trigger("rendered")}},getRoot:function(){return this.$el},update:function(a){function b(b){c.canceled||a!==c.query||c._render(a,b)}var c=this;this.query=a,this.canceled=!1,this.source(a,b)},cancel:function(){this.canceled=!0},clear:function(){this.cancel(),this.$el.empty(),this.trigger("rendered")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=null}}),c}(),q=function(){"use strict";function c(c){var e,f,g,h=this;c=c||{},c.menu||a.error("menu is required"),this.isOpen=!1,this.isEmpty=!0,this.datasets=b.map(c.datasets,d),e=b.bind(this._onSuggestionClick,this),f=b.bind(this._onSuggestionMouseEnter,this),g=b.bind(this._onSuggestionMouseLeave,this),this.$menu=a(c.menu).on("click.tt",".tt-suggestion",e).on("mouseenter.tt",".tt-suggestion",f).on("mouseleave.tt",".tt-suggestion",g),b.each(this.datasets,function(a){h.$menu.append(a.getRoot()),a.onSync("rendered",h._onRendered,h)})}function d(a){return new p(a)}return b.mixin(c.prototype,m,{_onSuggestionClick:function(b){this.trigger("suggestionClicked",a(b.currentTarget))},_onSuggestionMouseEnter:function(b){this._removeCursor(),this._setCursor(a(b.currentTarget),!0)},_onSuggestionMouseLeave:function(){this._removeCursor()},_onRendered:function(){function a(a){return a.isEmpty()}this.isEmpty=b.every(this.datasets,a),this.isEmpty?this._hide():this.isOpen&&this._show(),this.trigger("datasetRendered")},_hide:function(){this.$menu.hide()},_show:function(){this.$menu.css("display","block")},_getSuggestions:function(){return this.$menu.find(".tt-suggestion")},_getCursor:function(){return this.$menu.find(".tt-cursor").first()},_setCursor:function(a,b){a.first().addClass("tt-cursor"),!b&&this.trigger("cursorMoved")},_removeCursor:function(){this._getCursor().removeClass("tt-cursor")},_moveCursor:function(a){var b,c,d,e;if(this.isOpen){if(c=this._getCursor(),b=this._getSuggestions(),this._removeCursor(),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return void this.trigger("cursorRemoved");-1>d&&(d=b.length-1),this._setCursor(e=b.eq(d)),this._ensureVisible(e)}},_ensureVisible:function(a){var b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$menu.scrollTop(),e=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),0>b?this.$menu.scrollTop(d+b):c>e&&this.$menu.scrollTop(d+(c-e))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){this.$menu.css("ltr"===a?k.ltr:k.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(a){var b=null;return a.length&&(b={raw:p.extractDatum(a),value:p.extractValue(a),datasetName:p.extractDatasetName(a)}),b},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},update:function(a){function c(b){b.update(a)}b.each(this.datasets,c)},empty:function(){function a(a){a.clear()}b.each(this.datasets,a),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){function a(a){a.destroy()}this.$menu.off(".tt"),this.$menu=null,b.each(this.datasets,a)}}),c}(),r=function(){"use strict";function c(c){var e,f,g;c=c||{},c.input||a.error("missing input"),this.isActivated=!1,this.autoselect=!!c.autoselect,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.$node=d(c.input,c.withHint),e=this.$node.find(".tt-dropdown-menu"),f=this.$node.find(".tt-input"),g=this.$node.find(".tt-hint"),f.on("blur.tt",function(a){var c,d,g;c=document.activeElement,d=e.is(c),g=e.has(c).length>0,b.isMsie()&&(d||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){f.focus()}))}),e.on("mousedown.tt",function(a){a.preventDefault()}),this.eventBus=c.eventBus||new l({el:f}),this.dropdown=new q({menu:e,datasets:c.datasets}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new o({input:f,hint:g}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._setLanguageDirection()}function d(b,c){var d,f,h,i;d=a(b),f=a(j.wrapper).css(k.wrapper),h=a(j.dropdown).css(k.dropdown),i=d.clone().css(k.hint).css(e(d)),i.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly",!0).attr({autocomplete:"off",spellcheck:"false",tabindex:-1}),d.data(g,{dir:d.attr("dir"),autocomplete:d.attr("autocomplete"),spellcheck:d.attr("spellcheck"),style:d.attr("style")}),d.addClass("tt-input").attr({autocomplete:"off",spellcheck:!1}).css(c?k.input:k.inputWithNoHint);try{!d.attr("dir")&&d.attr("dir","auto")}catch(l){}return d.wrap(f).parent().prepend(c?i:null).append(h)}function e(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function f(a){var c=a.find(".tt-input");b.each(c.data(g),function(a,d){b.isUndefined(a)?c.removeAttr(d):c.attr(d,a)}),c.detach().removeData(g).removeClass("tt-input").insertAfter(a),a.remove()}var g="ttAttrs";return b.mixin(c.prototype,{_onSuggestionClicked:function(a,b){var c;(c=this.dropdown.getDatumForSuggestion(b))&&this._select(c)},_onCursorMoved:function(){var a=this.dropdown.getDatumForCursor();this.input.setInputValue(a.value,!0),this.eventBus.trigger("cursorchanged",a.raw,a.datasetName)},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint()},_onDatasetRendered:function(){this._updateHint()},_onOpened:function(){this._updateHint(),this.eventBus.trigger("opened")},_onClosed:function(){this.input.clearHint(),this.eventBus.trigger("closed")},_onFocused:function(){this.isActivated=!0,this.dropdown.open()},_onBlurred:function(){this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()},_onEnterKeyed:function(a,b){var c,d;c=this.dropdown.getDatumForCursor(),d=this.dropdown.getDatumForTopSuggestion(),c?(this._select(c),b.preventDefault()):this.autoselect&&d&&(this._select(d),b.preventDefault())},_onTabKeyed:function(a,b){var c;(c=this.dropdown.getDatumForCursor())?(this._select(c),b.preventDefault()):this._autocomplete(!0)},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(a,b){this.input.clearHintIfInvalid(),b.length>=this.minLength?this.dropdown.update(b):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var a;this.dir!==(a=this.input.getLanguageDirection())&&(this.dir=a,this.$node.css("direction",a),this.dropdown.setLanguageDirection(a))},_updateHint:function(){var a,c,d,e,f,g;a=this.dropdown.getDatumForTopSuggestion(),a&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(c=this.input.getInputValue(),d=o.normalizeQuery(c),e=b.escapeRegExChars(d),f=new RegExp("^(?:"+e+")(.+$)","i"),g=f.exec(a.value),g?this.input.setHint(c+g[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(a){var b,c,d,e;b=this.input.getHint(),c=this.input.getQuery(),d=a||this.input.isCursorAtEnd(),b&&c!==b&&d&&(e=this.dropdown.getDatumForTopSuggestion(),e&&this.input.setInputValue(e.value),this.eventBus.trigger("autocompleted",e.raw,e.datasetName))},_select:function(a){this.input.setQuery(a.value),this.input.setInputValue(a.value,!0),this._setLanguageDirection(),this.eventBus.trigger("selected",a.raw,a.datasetName),this.dropdown.close(),b.defer(b.bind(this.dropdown.empty,this.dropdown))},open:function(){this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(a){a=b.toStr(a),this.isActivated?this.input.setInputValue(a):(this.input.setQuery(a),this.input.setInputValue(a,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),f(this.$node),this.$node=null}}),c}();!function(){"use strict";var c,d,e;c=a.fn.typeahead,d="ttTypeahead",e={initialize:function(c,e){function f(){var f,g,h=a(this);b.each(e,function(a){a.highlight=!!c.highlight}),g=new r({input:h,eventBus:f=new l({el:h}),withHint:b.isUndefined(c.hint)?!0:!!c.hint,minLength:c.minLength,autoselect:c.autoselect,datasets:e}),h.data(d,g)}return e=b.isArray(e)?e:[].slice.call(arguments,1),c=c||{},this.each(f)},open:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.open()}return this.each(b)},close:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.close()}return this.each(b)},val:function(b){function c(){var c,e=a(this);(c=e.data(d))&&c.setVal(b)}function e(a){var b,c;return(b=a.data(d))&&(c=b.getVal()),c}return arguments.length?this.each(c):e(this.first())},destroy:function(){function b(){var b,c=a(this);(b=c.data(d))&&(b.destroy(),c.removeData(d))}return this.each(b)}},a.fn.typeahead=function(b){var c;return e[b]&&"initialize"!==b?(c=this.filter(function(){return!!a(this).data(d)}),e[b].apply(c,[].slice.call(arguments,1))):e.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return a.fn.typeahead=c,this}}()}(window.jQuery); \ No newline at end of file
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js
index 3ae20d1a9..f610456e1 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js
@@ -8,20 +8,80 @@
*******************************************************************************/
$(document).ready( function() {
+ $('select').material_select();
+ $('.modal').modal();
$(".button-collapse").sideNav();
+ $('.carousel').carousel();
+
$('#Search').click(function() {
var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);
window.location.href = '/search_projects?tags=' + tags;
return false;
});
+
$('#SearchSpan').click(function(){
var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);
window.location.href = '/search_projects?tags=' + tags;
return false;
});
+
$('div.form-group-custom i.material-icons').click(function(e){
var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);
window.location.href = '/search_projects?tags=' + tags;
return false;
});
+
+ $("#add_project_button").on('click',function(){
+ event.preventDefault();
+ var vnf_name = $("#vnf_name").val() ;
+
+ var formData = new FormData($('form#add_project_form')[0]);
+ var license = $('#license option:selected').val();
+ formData.append('license', license);
+ var opnfv_indicator = $('#opnfv_indicator option:selected').val();
+ formData.append('opnfv_indicator', opnfv_indicator);
+
+ $.ajax({
+ url: '/add_project',
+ type: 'post',
+ //dataType: 'json',
+ processData: false, // tell jQuery not to process the data
+ contentType: false, // tell jQuery not to set contentType
+ data: formData,
+ success: function(data) {
+ $('#modal1').modal('close');
+ $('form#add_project_form').trigger('reset');
+ Materialize.toast('Successfully submitted the VNF!', 3000, 'rounded');
+ },
+ error: function (error) {
+ if(error['responseJSON']) {
+ Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');
+ } else if(error['responseText']) {
+ var response_message = JSON.parse(error['responseText']);
+ Materialize.toast(response_message['error'], 3000, 'rounded');
+ }
+ //$('#modal1').modal('open');
+ }
+ });
+ });
+ $("#add_tag_button").on('click',function(){
+ event.preventDefault();
+ var tag_name = $("#tag_name").val() ;
+
+ $.ajax({
+ url: '/add_tag',
+ type: 'post',
+ dataType: 'json',
+ data: $('form#add_tag_form').serialize(),
+ success: function(data) {
+ $('#modal2').modal('close');
+ $('form#add_tag_form').trigger('reset');
+ Materialize.toast('Successfully submitted the TAG!', 3000, 'rounded');
+ },
+ error: function (error) {
+ Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');
+ }
+ });
+ });
+
});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js
new file mode 100644
index 000000000..2047a92a8
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+$(document).ready( function() {
+
+ //getVnfs : get 5 main VNFs using typeahead
+ var getVnfs = new Bloodhound({
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('vnf_name'),
+ queryTokenizer: Bloodhound.tokenizers.obj.whitespace('vnf_name'),
+ remote: {
+ url: '/search_vnf?key=%QUERY',
+ wildcard: '%QUERY'
+ },
+ limit: 5
+ });
+
+ getVnfs.initialize();
+ $('#scrollable-dropdown-menu #vnf_name.typeahead').typeahead(
+ {
+ hint: true,
+ highlight: true,
+ minLength: 1
+ },
+ {
+ name: 'vnf_name',
+ display: 'vnf_name',
+ limit: 5,
+ source: getVnfs.ttAdapter()
+ });
+
+ //getTags : get 5 main tags using typeahead
+ var getTags = new Bloodhound({
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('tag_name'),
+ queryTokenizer: Bloodhound.tokenizers.obj.whitespace('tag_name'),
+ remote: {
+ url: '/search_tag?key=%QUERY',
+ wildcard: '%QUERY'
+ },
+ limit: 5
+ });
+
+ getTags.initialize();
+ $('#scrollable-dropdown-menu #tag_name.typeahead').typeahead(
+ {
+ hint: true,
+ highlight: true,
+ minLength: 1
+ },
+ {
+ name: 'tag_name',
+ display: 'tag_name',
+ limit: 5,
+ source: getTags.ttAdapter()
+ });
+
+ $("#add_vnf_tag_association_button").on('click',function(){
+ event.preventDefault();
+ var vnf_name = $("#vnf_name").val() ;
+
+ $.ajax({
+ url: '/vnf_tag_association',
+ type: 'post',
+ dataType: 'json',
+ data: $('form#add_vnf_tag_association_form').serialize(),
+ success: function(data) {
+ $('#modal3').modal('close');
+ $('form#add_vnf_tag_association_form').trigger('reset');
+ Materialize.toast('Successfully added the TAG to the VNF!', 3000, 'rounded');
+ },
+ error: function (error) {
+ Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');
+ }
+ });
+ });
+
+});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js
new file mode 100644
index 000000000..26c28c945
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js
@@ -0,0 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+$(document).ready( function() {
+ var ob = JSON.parse(json);
+});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css
new file mode 100644
index 000000000..03527f088
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css
@@ -0,0 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+.container-custom {
+ max-width: 100% !important;
+}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css
new file mode 100644
index 000000000..4598cffec
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+input.search-input-rest
+{
+ font-weight: 400;
+ margin: 0px 0;
+ height: 30px;
+ padding: 10px 30px;
+ min-width: 90%;
+ max-width: 90%;
+ /*max-width: 500px;
+ */
+ border-radius: 5px;
+ border: 2px solid #333333;
+ box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
+ color: #333333;
+ font-size: 22px;
+}
+.material-search-custom {
+ left : -30px;
+
+ padding-left: 10px;
+}
+.form-group-custom {
+ width : 400px;
+ position: relative;
+ float: right;
+ left: -40%;
+}
+.form-control-custom {
+ padding-top: 10px;
+ padding-left: 50px;
+}
+input[type="search"]:focus:not([readonly]) {
+ transition: all 0s !important;
+ border-radius: 5px;
+ border: 2px solid #333333;
+ box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
+ color: #333333;
+}
+.gray {
+ background: rgb(249,249,249);
+}
+span.glyphicon.glyphicon-search.form-control-feedback,
+ div.form-group-custom i.material-icons {
+ top: 0.5em;
+ left: 16.0em;
+ cursor:pointer;
+ z-index: 30;
+ position: absolute;
+}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css
index 8875f7fe5..c00071160 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css
@@ -7,36 +7,13 @@
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
-input[type="text"]:focus:not([readonly]) {
- transition: all 0s !important;
- border-radius: 5px;
- border: 2px solid #333333;
- box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
- color: #333333;
-}
-.gray {
- background: rgb(249,249,249);
-}
-.material-search-custom {
- left : -30px;
-
- padding-left: 10px;
-}
-.form-group-custom {
- width : 400px;
- position: relative;
- float: right;
- left: -40%;
-}
-.form-control-custom {
- padding-top: 10px;
- padding-left: 50px;
-}
.card-shadow-custom {
box-shadow: 0 2px 3px 0 rgba(0,0,0,0.50);
border-bottom: 2px solid #8B19A2;
}
.row-custom {
+ display: flex;
+ flex-flow: row wrap;
width: 100%;
margin: 1em 1em 1em 1em;
padding-right: 20px;
@@ -56,8 +33,7 @@ input[type="text"]:focus:not([readonly]) {
display: inline-block;
}
.card-image-picture-custom {
- margin: 1em 0em 0em 3.5em;
- display: inline-block;
+ margin: auto;
}
.collection .collection-item.active {
background-color: rgb(255,245,114);
@@ -125,8 +101,12 @@ a.a-custom-more:hover {
span.glyphicon.glyphicon-search.form-control-feedback,
div.form-group-custom i.material-icons {
top: 0.5em;
- left: 16.5em;
+ left: 16.0em;
cursor:pointer;
z-index: 30;
position: absolute;
}
+.card-image-custom {
+ display: flex;
+ flex-flow: column wrap;
+}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css
index 4769cfcc0..f5355ba9d 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css
@@ -152,23 +152,6 @@ form.search-form input.search-input
color: #333333;
font-size: 22px;
}
-input.search-input-rest
-{
- font-weight: 400;
- margin: 0px 0;
- height: 30px;
- padding: 10px 30px;
- min-width: 90%;
- max-width: 90%;
- /*max-width: 500px;
- */
- border-radius: 5px;
- border: 2px solid #333333;
- box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
- color: #333333;
- font-size: 22px;
-}
-
form.search-form button.search-button
{
@@ -306,7 +289,7 @@ footer
{
height: 100px;
}
-input[type="text"]:focus:not([readonly]) {
+input[type="search"]:focus:not([readonly]) {
transition: all 0s !important;
border-radius: 5px;
border: 2px solid #333333;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png b/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png
new file mode 100644
index 000000000..fe18194ec
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png
Binary files differ
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js
new file mode 100644
index 000000000..229620d20
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+var multer = require('multer');
+
+
+var storage = multer.diskStorage({
+ destination: function (req, file, callback) {
+ callback(null, './public/uploads');
+ },
+ filename: function (req, file, callback) {
+ console.log(file);
+ console.log(req.body);
+ callback(null, file.fieldname + '-' + Date.now() + '.jpg');
+ }
+});
+
+var fileFilter = function (req, file, cb) {
+ if (file.mimetype !== 'image/png') {
+ //req.fileValidationError = 'goes wrong on the mimetype';
+ cb(null, false);
+ } else {
+ cb(null, true);
+ }
+}
+
+var upload = multer({ fileFilter: fileFilter, storage : storage}).single('file_upload');
+
+
+router.post('/', function(req, res) {
+ upload(req,res,function(err) {
+ console.log(req.body);
+ console.log(req.file)
+ if(req.file == null && req.body['file_url'] != '') {
+ response = 'File Upload error: wrong Filetype';
+ res.status(500);
+ res.end(JSON.stringify({'error': response}));
+
+ }
+ if(err) {
+ console.log(err);
+ response = 'File Upload error: ' + err;
+ console.log(response);
+ //return res.end(req.fileValidationError);
+ res.status(500);
+ res.send({'error': response});
+ return;
+ }
+
+ console.log(req.file);
+ req.body['photo_url'] = (req.file) ? req.file['filename'] : 'logo.png';
+ console.log(req.body);
+
+ req.checkBody("vnf_name", "VNF Name must not be empty").notEmpty();
+ req.checkBody("repo_url", "Repository URL must not be empty").notEmpty();
+ req.checkBody("license", "Please select a License").notEmpty();
+ req.checkBody("opnfv_indicator", "Please select an OPNFV Indicator").notEmpty();
+ req.checkBody("repo_url", "Must be a Github URL").matches('.*github\.com.*');
+
+ var errors = req.validationErrors();
+ console.log(errors);
+
+ var response = ''; for(var i = 0; i < errors.length; i++) {
+ console.log(errors[i]['msg']);
+ response = response + errors[i]['msg'] + '; ';
+ }
+
+ if(errors) { res.status(500);
+ res.send({'error': response});
+ return;
+ }
+
+ var vnf_details = req.body;
+ delete vnf_details.file_url;
+
+ db_pool.getConnection(function(err, connection) {
+ // Use the connection
+
+ sql_query = 'INSERT INTO photo(photo_url) values(\'' + req.body['photo_url'] + '\')\;SELECT LAST_INSERT_ID() photo_id';
+ // TODO look above query prone to sql_injections
+
+ console.log(sql_query);
+ connection.query(sql_query, function (error, results, fields) {
+ console.log('hola');
+ console.log(results[1][0].photo_id);
+ //connection.query(sql_query, vnf_details, function (error, results, fields) {
+ delete vnf_details.photo_url;
+ vnf_details['photo_id'] = results[1][0].photo_id;
+ sql_query = 'INSERT INTO vnf SET ?'
+ connection.query(sql_query, vnf_details, function (error, results, fields) {
+ // And done with the connection.
+ connection.release();
+ if (error) throw error;
+
+ // Handle error after the release.
+ res.end('{"success" : "Updated Successfully", "status" : 200}');
+ return;
+ // Don't use the connection here, it has been returned to the pool.
+ });
+ });
+ });
+
+
+ });
+
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js
new file mode 100644
index 000000000..511f4ccb0
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+router.post('/', function(req, res) {
+ console.log(req.body);
+ req.checkBody("tag_name", "TAG Name must not be empty").notEmpty();
+
+ var errors = req.validationErrors();
+ console.log(errors);
+
+ var response = ''; for(var i = 0; i < errors.length; i++) {
+ console.log(errors[i]['msg']);
+ response = response + errors[i]['msg'] + '; ';
+ }
+
+ if(errors) { res.status(500);
+ res.send({'error': response});
+ return;
+ }
+
+ var tag_details = req.body;
+
+ db_pool.getConnection(function(err, connection) {
+ // Use the connection
+ sql_query = 'INSERT INTO tag SET ?'
+ connection.query(sql_query, tag_details, function (error, results, fields) {
+ // And done with the connection.
+ res.end('{"success" : "Updated Successfully", "status" : 200}');
+ return;
+ connection.release();
+ // Handle error after the release.
+ if (error) throw error;
+ // Don't use the connection here, it has been returned to the pool.
+ });
+ });
+
+
+ res.end('{"success" : "Updated Successfully", "status" : 200}');
+ return;
+
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js
new file mode 100644
index 000000000..be0664276
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+router.get('/', function(req, res) {
+ var tags = req.param('tags');
+ console.log(tags);
+ res.render('project_profile', { title: 'Express' });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js
index 49fceeb3c..96f68db7a 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js
@@ -9,11 +9,86 @@
var express = require('express');
var router = express.Router();
+var async = require('async');
+
+
+var renderer = function(res, err, results) {
+ console.log(results);
+ res.render('search_projects', { title: 'Express', json: results });
+}
+
+var get_tags = function(result, callback) {
+ db_pool.getConnection(function(err, connection) {
+ sql_query = 'select tag_name from tag where tag_id in (select tag_id from vnf_tags where vnf_id = ' + result['vnf_id'] + ') limit 5';
+ // TODO find why it works and not above
+ connection.query(sql_query, function (error, results, fields) {
+ console.log(results);
+ result['tags'] = results;
+ callback(null, result);
+ //connection.release();
+ if (error) throw error;
+ });
+ });
+}
+
+
+var get_images = function(result, callback) {
+ db_pool.getConnection(function(err, connection) {
+ sql_query = 'select photo_url from photo where photo_id = ' + result['photo_id'];
+ // TODO find why it works here and not when declared outside the method
+ console.log(sql_query);
+ connection.query(sql_query, function (error, results, fields) {
+ console.log(results[0].photo_url);
+ result['photo_url'] = results[0].photo_url;
+ callback(null, result);
+ //connection.release();
+ if (error) throw error;
+ });
+ });
+}
+
+var sql_data = function(tags, renderer, res) {
+ var tag_array = "\'" + tags.map(function (item) { return item; }).join("\',\'") + "\'";
+ console.log(tag_array);
+ var condition = '';
+ db_pool.getConnection(function(err, connection) {
+ sql_query = 'select tag_id from tag where tag_name in (' + tag_array + ')';
+ connection.query(sql_query, function (error, results, fields) {
+ condition = 'SELECT * FROM vnf as v';
+ for (var i in results) {
+ condition += (i == 0) ? ' WHERE ' : ' AND ';
+ condition += 'v.vnf_id IN (SELECT vnf_id from vnf_tags where tag_id = ' + results[i]['tag_id'] + ')';
+ }
+
+ connection.query(condition, function (error, results, fields) {
+ console.log(results);
+ async.map(results, get_images, function(error, results) {
+ async.map(results, get_tags, renderer.bind(null, res));
+ });
+ //connection.release();
+ if (error) throw error;
+ });
+
+ connection.release();
+ if (error) throw error;
+ });
+ });
+
+}
router.get('/', function(req, res) {
+
+ console.log(typeof(req.param('tags')));
var tags = req.param('tags');
- console.log(tags);
- res.render('search_projects', { title: 'Express' });
+
+ if(tags) {
+ tags = tags.toLowerCase().split(/[ ,]+/);
+ console.log(tags);
+ sql_data(tags, renderer, res);
+ } else {
+ res.render('search_projects', { title: 'Express', json: false});
+ }
+
});
module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js
new file mode 100644
index 000000000..cbe8caefd
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* Post Controller for Tag autocomplete form */
+router.get('/', function(req, res) {
+ tag_partial = req.param('key');
+ db_pool.getConnection(function(err, connection) {
+
+ sql_query = 'select tag_name from tag where tag_name like "%'+ tag_partial + '%" limit 5';
+ // TODO find why it works and not above
+ connection.query(sql_query, function (error, results, fields) {
+ console.log(results);
+
+ var data=[];
+ for(i = 0; i < results.length; i++) {
+ data.push(results[i].tag_name.replace(/\r?\n|\r/g, ''));
+ }
+ console.log(results);
+ connection.release();
+ res.end(JSON.stringify(results));
+
+ if (error) throw error;
+ });
+ });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js
new file mode 100644
index 000000000..a5cf09ca7
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* Post Controller for Search Vnf autocomplete form */
+router.get('/', function(req, res) {
+ tag_partial = req.param('key');
+ db_pool.getConnection(function(err, connection) {
+
+ sql_query = 'select vnf_name from vnf where vnf_name like "%'+ tag_partial + '%" limit 5';
+ // TODO find why it works and not above
+ connection.query(sql_query, function (error, results, fields) {
+ console.log(results);
+
+ var data=[];
+ for(i = 0; i < results.length; i++) {
+ data.push(results[i].vnf_name.replace(/\r?\n|\r/g, ''));
+ }
+ console.log(results);
+ connection.release();
+ res.end(JSON.stringify(results));
+
+ if (error) throw error;
+ });
+ });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js
new file mode 100644
index 000000000..d1a3d726e
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* Post controller for VNF_TAG Association */
+router.post('/', function(req, res) {
+ req.checkBody("tag_name", "TAG Name must not be empty").notEmpty();
+ req.checkBody("vnf_name", "VNF Name must not be empty").notEmpty();
+
+ var errors = req.validationErrors();
+ console.log(errors);
+
+ var response = ''; for(var i = 0; i < errors.length; i++) {
+ console.log(errors[i]['msg']);
+ response = response + errors[i]['msg'] + '; ';
+ }
+
+ if(errors) { res.status(500);
+ res.send({'error': response});
+ return;
+ }
+
+ var tag_name = req.param('tag_name');
+ var vnf_name = req.param('vnf_name');
+
+ db_pool.getConnection(function(err, connection) {
+ // Use the connection
+ //sql_query = 'INSERT INTO tag SET ?'
+ sql_query = 'insert into vnf_tags(vnf_id, tag_id) values ((select vnf_id from vnf where vnf_name = \'' + vnf_name + '\'), (select tag_id from tag where tag_name = \'' + tag_name + '\'))';
+ console.log(sql_query);
+ connection.query(sql_query, function (error, results, fields) {
+ // And done with the connection.
+
+ connection.release();
+ res.end('{"success" : "Updated Successfully", "status" : 200}');
+
+ // Handle error after the release.
+ if (error) throw error;
+ // Don't use the connection here, it has been returned to the pool.
+ });
+ });
+
+ res.end('{"success" : "Updated Successfully", "status" : 200}');
+ //res.render('vnf_tag_association', { title: 'Express' });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade
new file mode 100644
index 000000000..dde8cfe75
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade
@@ -0,0 +1,164 @@
+
+.search-box
+ script(src='/3rd_party/typeahead.js')
+ script(type='text/javascript', src='/javascripts/mode_edit.js')
+ .fixed-action-btn.fixed-action-btn_custom
+ a.btn-floating.btn-large.red
+ i.large.material-icons mode_edit
+ ul
+ li
+ a.btn-floating.red.tooltipped(href='#modal2', data-position='left', data-delay='50', data-tooltip='Add a TAG')
+ i.large.material-icons attach_file
+ li
+ a.btn-floating.green.tooltipped(href='#modal1', data-position='left', data-delay='50', data-tooltip='Add a VNF')
+ i.large.material-icons add
+ li
+ a.btn-floating.blue.tooltipped(href='#modal3', data-position='left', data-delay='50', data-tooltip='Add a TAG to a VNF')
+ i.large.material-icons share
+ #modal1.modal
+ .modal-content
+ h4.center
+ i.material-icons library_add
+ | Add a VNF
+ .row
+ form#add_project_form.col.s12(action='/add_project', enctype='multipart/form-data', method='post')
+ .row.modal-form-row
+ .input-field.col.s12
+ input#vnf_name.validate(type='text', name='vnf_name')
+ label.left-align(for='vnf_name') Name
+ .row
+ .input-field.col.s12
+ input#repo_url.validate(type='text', name='repo_url')
+ label.left-align(for='repo_url') Github URL
+ .row
+ .input-field.col.s12
+ select#license
+ option(value='', name='license', disabled='', selected='') Choose the License
+ option(value='MIT') MIT
+ option(value='GPL') GPL
+ option(value='GPL_V2') GPL_V2
+ option(value='BSD') BSD
+ option(value='APACHE') APACHE
+ label License
+ .row
+ .input-field.col.s12
+ select#opnfv_indicator
+ option(value='', name='opnfv_indicator', disabled='', selected='') Choose the OPNFV Indicator
+ option(value='silver') silver
+ option(value='gold') gold
+ option(value='platinum') platinum
+ label OPNFV Indicator
+
+ .row
+ .file-field.input-field
+ .btn
+ span Photo (Optional)
+ input#file_upload(type='file', name='file_upload')
+ .file-path-wrapper
+ input.file-path.validate(type='text', name='file_url')
+
+ .row
+ .input-field.col.s12
+ input#submitter_id.validate(type='hidden', name='submitter_id', value=1)
+
+ .row
+ button#add_project_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+ | Submit VNF
+ i.material-icons.right send
+ #modal2.modal
+ .modal-content
+ h4.center
+ i.material-icons library_add
+ | Add a TAG
+ .row
+ form#add_tag_form.col.s12(action='/add_tag', method='post')
+ .row.modal-form-row
+ .input-field.col.s12
+ input#tag_name.validate(type='text', name='tag_name')
+ label.left-align(for='tag_name') Name
+ button#add_tag_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+ | Submit TAG
+ i.material-icons.right send
+ #modal3.modal
+ h4.center
+ i.material-icons library_add
+ | Add a TAG to a VNF
+ .row
+ form#add_vnf_tag_association_form.col.s12(action='/vnf_tag_association', method='post')
+
+ .row.modal-form-row.modal-form-row-custom
+ .input-field.col.s2 VNF Name
+ #scrollable-dropdown-menu.input-field.col.s4
+ input#vnf_name.typeahead(type='text', name='vnf_name')
+ //
+ label.left-align(for='tag_name') VNF Name
+ .input-field.col.s2 TAG Name
+ #scrollable-dropdown-menu.input-field.col.s4
+ input#tag_name.validate.typeahead(type='text', name='tag_name')
+ //
+ label.left-align(for='tag_name') TAG Name
+
+ button#add_vnf_tag_association_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+ | Submit
+ i.material-icons.right send
+ style.
+ .select-dropdown{
+ overflow-y: auto !important;
+ }
+ .dropdown-content {
+ max-height: 200px !important;
+ }
+ .backdrop{
+ background-color: rgb(253,225,109);
+ }
+ .bg {
+ }
+ .modal-form-row-custom {
+ min-height: 200px !important;
+ }
+ #scrollable-dropdown-menu .tt-menu {
+ max-height: 150px;
+ overflow-y: auto;
+ }
+
+ .typeahead, .tt-query, .tt-hint {
+ border: 2px solid #CCCCCC;
+ border-radius: 8px 8px 8px 8px;
+ font-size: 24px;
+ height: 30px;
+ line-height: 30px;
+ outline: medium none;
+ padding: 8px 12px;
+ width: 396px;
+ }
+
+ .tt-query {
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
+ }
+ .tt-hint {
+ color: #999999;
+ }
+ .tt-dropdown-menu {
+ background-color: #FFFFFF;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 8px 8px 8px 8px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ margin-top: 12px;
+ padding: 8px 0;
+ width: 200px;
+ }
+ .tt-suggestion {
+ font-size: 18px;
+ line-height: 24px;
+ padding: 3px 20px;
+ }
+ .tt-suggestion.tt-cursor {
+ background-color: #0097CF;
+ color: #FFFFFF;
+ }
+ .tt-suggestion p {
+ margin: 0;
+ }
+ .tt-dropdown-menu, .gist {
+ text-align: left;
+ }
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade
index e60c3ba26..bf0cd149e 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade
@@ -7,10 +7,11 @@ extends layout
which accompanies this distribution, and is available at
http://www.apache.org/licenses/LICENSE-2.0
block content
+ link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css')
.search-box
h1 VNF Catalogue
form.search-form
- input.search-input(type='text', placeholder='Search...', id='Tags')
+ input.search-input(type='search', placeholder='Search...', id='Tags')
.space-10
button.search-button(type='submit', value='Search', id='Search') Search
.content.content-height-overwrite
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade
index 89142f813..33c09e338 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade
@@ -9,7 +9,6 @@ html(lang='en')
html
head
title= title
- link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css')
link(rel='stylesheet', href='/3rd_party/materialize/css/materialize.css')
script(type='text/javascript', src='https://code.jquery.com/jquery-3.1.1.min.js')
script(src='/javascripts/global.js')
@@ -49,5 +48,7 @@ html
a(href='#') Sign up
li.signin
a(href='#') Sign in
+ block search
+ block add_project
block content
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade
new file mode 100644
index 000000000..7b37bd423
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade
@@ -0,0 +1,84 @@
+extends layout
+
+//
+ Copyright (c) 2017 Kumar Rishabh and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Apache License, Version 2.0
+ which accompanies this distribution, and is available at
+ http://www.apache.org/licenses/LICENSE-2.0
+block search
+ include search
+block content
+ .content
+ .container.container-custom
+ .carousel
+ a.carousel-item(href='#one!')
+ img(src='http://lorempixel.com/250/250/nature/1')
+ a.carousel-item(href='#two!')
+ img(src='http://lorempixel.com/250/250/nature/2')
+ a.carousel-item(href='#three!')
+ img(src='http://lorempixel.com/250/250/nature/3')
+ a.carousel-item(href='#four!')
+ img(src='http://lorempixel.com/250/250/nature/4')
+ a.carousel-item(href='#five!')
+ img(src='http://lorempixel.com/250/250/nature/5')
+ .card.card-shadow-custom.horizontal
+ .row.row-custom
+ .col.s5.card-title-div-custom
+ span.card-title.card-title-span-custom Card Title
+ .col.s5.card-title-div-custom
+ i.material-icons grade
+ span.card-title PenguinScore: 42
+ .col.s2.card-title-div-custom-right
+ form(action='#')
+ input#search_result_1(type='checkbox')
+ label(for='search_result_1') Compare
+ //
+ <div class="card-action">
+ <a href="#">This is a link</a>
+ </div>
+ .col.s4.card-image.card-image-custom
+ img.card-image-picture-custom(src='/images/logo.png')
+ .col.s8.card-stacked
+ .card-content
+ p
+ .collection.collection-custom
+ a.collection-item(href='#!')
+ span
+ i.material-icons code
+ | Lines Of Code: 1.03M
+ a.collection-item(href='#!')
+ span
+ i.material-icons code
+ | Lines Of Code: 1.03M
+ a.collection-item(href='#!')
+ span
+ i.material-icons code
+ | Lines Of Code: 1.03M
+ a.collection-item(href='#!')
+ span
+ i.material-icons code
+ | Lines Of Code: 1.03M
+ .card-action
+ | Tags:
+ .chip
+ a.a-custom(href='#!') Tag1
+ .chip
+ a.a-custom(href='#!') Tag2
+ .chip
+ a.a-custom(href='#!') Tag3
+ .chip
+ a.a-custom(href='#!') Tag4
+ .chip
+ a.a-custom(href='#!') Tag5
+ a.a-custom-more(href='#!') more
+ .divider
+ .card-action-custom.col.s12.card-action
+ | License:
+ a(href='#') MIT
+ | Complexity:
+ a(href='#') Atomic
+ footer
+ | © 2017 XYZ Company
+ link(rel='stylesheet', href='/stylesheets/search_projects.css')
+
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade
new file mode 100644
index 000000000..77b24881e
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade
@@ -0,0 +1,5 @@
+.search-box
+ link(rel='stylesheet', href='/stylesheets/search_form.css')
+ .form-group-custom.form-group.has-feedback
+ input.search-input-rest.form-control(type='search', placeholder='Search...', id='Tags')
+ i.material-icons search \ No newline at end of file
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade
index 6670d212c..ac91aa68d 100644
--- a/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade
@@ -6,70 +6,78 @@ extends layout
are made available under the terms of the Apache License, Version 2.0
which accompanies this distribution, and is available at
http://www.apache.org/licenses/LICENSE-2.0
+block search
+ include search
+block add_project
+ include add_project
block content
- .search-box
- .form-group-custom.form-group.has-feedback
- input.search-input-rest.form-control(type='text', placeholder='Search...', id='Tags')
- i.material-icons search
.content
- .container
- .card.card-shadow-custom.horizontal
- .row.row-custom
- .col.s5.card-title-div-custom
- span.card-title.card-title-span-custom Card Title
- .col.s5.card-title-div-custom
- i.material-icons grade
- span.card-title PenguinScore: 42
- .col.s2.card-title-div-custom-right
- form(action='#')
- input#search_result_1(type='checkbox')
- label(for='search_result_1') Compare
- //
- <div class="card-action">
- <a href="#">This is a link</a>
- </div>
- .col.s4.card-image
- img.card-image-picture-custom(src='/images/logo.png')
- .col.s8.card-stacked
- .card-content
- p
- .collection.collection-custom
- a.collection-item(href='#!')
- span
- i.material-icons code
- | Lines Of Code: 1.03M
- a.collection-item(href='#!')
- span
- i.material-icons code
- | Lines Of Code: 1.03M
- a.collection-item(href='#!')
- span
- i.material-icons code
- | Lines Of Code: 1.03M
- a.collection-item(href='#!')
- span
- i.material-icons code
- | Lines Of Code: 1.03M
- .card-action
- | Tags:
- .chip
- a.a-custom(href='#!') Tag1
- .chip
- a.a-custom(href='#!') Tag2
- .chip
- a.a-custom(href='#!') Tag3
- .chip
- a.a-custom(href='#!') Tag4
- .chip
- a.a-custom(href='#!') Tag5
- a.a-custom-more(href='#!') more
- .divider
- .card-action-custom.col.s12.card-action
- | License:
- a(href='#') MIT
- | Complexity:
- a(href='#') Atomic
+ each key, index in json
+ .container.container-custom
+ .card.card-shadow-custom.horizontal
+ .row.row-custom
+ .col.s5.card-title-div-custom
+ span.card-title.card-title-span-custom #{key.vnf_name}
+ .col.s5.card-title-div-custom
+ i.material-icons grade
+ span.card-title PenguinScore: 42
+ .col.s2.card-title-div-custom-right
+ form(action='#')
+ input#search_result_1(type='checkbox', name='#{key.vnf_name}')
+ label(for='search_result_1') Compare
+ //
+ <div class="card-action">
+ <a href="#">This is a link</a>
+ </div>
+ .col.s4.card-image.card-image-custom
+ img.card-image-picture-custom(src='/uploads/#{key.photo_url}')
+ .col.s8.card-stacked
+ .card-content
+ p
+ .collection.collection-custom
+ a.collection-item(href='#!')
+ span
+ i.material-icons code
+ | Lines Of Code: #{key.lines_of_code}
+ a.collection-item(href='#!')
+ span
+ i.material-icons person
+ | Number of Developers: #{key.no_of_developers}
+ a.collection-item(href='#!')
+ span
+ i.material-icons star
+ | Number of Stars: #{key.no_of_stars}
+ a.collection-item(href='#!')
+ span
+ i.material-icons description
+ | Number of Versions: #{key.versions}
+ .card-action
+ | Tags:
+ each tag, index in key.tags
+ .chip
+ a.a-custom(href='/search_projects?tags=#{tag.tag_name}') #{tag.tag_name}
+ //
+ .chip
+ a.a-custom(href='#!') tag1
+ .chip
+ a.a-custom(href='#!') Tag2
+ .chip
+ a.a-custom(href='#!') Tag3
+ .chip
+ a.a-custom(href='#!') Tag4
+ .chip
+ a.a-custom(href='#!') Tag5
+ a.a-custom-more(href='#!') more
+ .divider
+ .card-action-custom.col.s12.card-action
+ | License:
+ a(href='#') #{key.license}
+ | Complexity:
+ a(href='#') Atomic
+ | Activity:
+ a(href='#') Medium
+ | OPNFV Indicator:
+ a(href='#') #{key.opnfv_indicator}
footer
| © 2017 XYZ Company
link(rel='stylesheet', href='/stylesheets/search_projects.css')
-
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade
new file mode 100644
index 000000000..c2e11601d
--- /dev/null
+++ b/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade
@@ -0,0 +1,167 @@
+doctype html
+//
+ Copyright (c) 2017 Kumar Rishabh and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Apache License, Version 2.0
+ which accompanies this distribution, and is available at
+ http://www.apache.org/licenses/LICENSE-2.0
+html(lang='en')
+html
+ head
+ title= title
+ //
+ link(rel='stylesheet', href='/3rd_party/materialize/css/materialize.css')
+ script(type='text/javascript', src='https://code.jquery.com/jquery-3.1.1.min.js')
+ //
+ script(src='/javascripts/global.js')
+ //
+ script(src='/3rd_party/materialize/js/materialize.js')
+ link(href='https://fonts.googleapis.com/icon?family=Material+Icons', rel='stylesheet')
+ link(rel='stylesheet', href='/stylesheets/style.css')
+ script(src='/3rd_party/typeahead.js')
+ script(src='/javascripts/mode_edit.js')
+ body
+ h4.center
+ i.material-icons library_add
+ | Add a TAG to a VNF
+ .row
+ form#add_tag_form.col.s12(action='/add_tag', method='post')
+ .row.modal-form-row
+ .input-field.col.s6 VNF Name
+ .input-field.col.s6 TAG Name
+ .row.modal-form-row
+ #scrollable-dropdown-menu.input-field.col.s6
+ input#tag_name.typeahead(type='text', name='tag_name')
+ //
+ label.left-align(for='tag_name') VNF Name
+
+ .input-field.col.s6
+ input#tag_name.validate(type='text', name='vnf_name')
+ //
+ label.left-align(for='tag_name') TAG Name
+ .row.modal-form-row
+ .input-field.col.s6
+ .input-field.col.s6
+ .row.modal-form-row
+ button#add_tag_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+ | Submit
+ i.material-icons.right send
+style.
+ #scrollable-dropdown-menu .tt-menu {
+ max-height: 150px;
+ overflow-y: auto;
+ }
+
+ .typeahead, .tt-query, .tt-hint {
+ border: 2px solid #CCCCCC;
+ border-radius: 8px 8px 8px 8px;
+ font-size: 24px;
+ height: 30px;
+ line-height: 30px;
+ outline: medium none;
+ padding: 8px 12px;
+ width: 396px;
+ }
+ .typeahead {
+ background-color: #FFFFFF;
+ }
+ .typeahead:focus {
+ border: 2px solid #0097CF;
+ }
+ .tt-query {
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
+ }
+ .tt-hint {
+ color: #999999;
+ }
+ .tt-dropdown-menu {
+ background-color: #FFFFFF;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 8px 8px 8px 8px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ margin-top: 12px;
+ padding: 8px 0;
+ width: 422px;
+ }
+ .tt-suggestion {
+ font-size: 18px;
+ line-height: 24px;
+ padding: 3px 20px;
+ }
+ .tt-suggestion.tt-cursor {
+ background-color: #0097CF;
+ color: #FFFFFF;
+ }
+ .tt-suggestion p {
+ margin: 0;
+ }
+ .tt-dropdown-menu, .gist {
+ text-align: left;
+ }
+ /*
+ html {
+ overflow-y: scroll;
+ }
+ .container {
+ margin: 0 auto;
+ max-width: 750px;
+ text-align: center;
+ }
+
+ html {
+ color: #333333;
+ font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 18px;
+ line-height: 1.2;
+ }
+ .title, .example-name {
+ font-family: Prociono;
+ }
+ p {
+ margin: 0 0 10px;
+ }
+ .title {
+ font-size: 64px;
+ margin: 20px 0 0;
+ }
+ .example {
+ padding: 30px 0;
+ }
+ .example-name {
+ font-size: 32px;
+ margin: 20px 0;
+ }
+ .demo {
+ margin: 50px 0;
+ position: relative;
+ }
+ */
+ /*
+ .gist {
+ font-size: 14px;
+ }
+ .example-twitter-oss .tt-suggestion {
+ padding: 8px 20px;
+ }
+ .example-twitter-oss .tt-suggestion + .tt-suggestion {
+ border-top: 1px solid #CCCCCC;
+ }
+ .example-twitter-oss .repo-language {
+ float: right;
+ font-style: italic;
+ }
+ .example-twitter-oss .repo-name {
+ font-weight: bold;
+ }
+ .example-twitter-oss .repo-description {
+ font-size: 14px;
+ }
+ .example-sports .league-name {
+ border-bottom: 1px solid #CCCCCC;
+ margin: 0 20px 5px;
+ padding: 3px 0;
+ }
+ .example-arabic .tt-dropdown-menu {
+ text-align: right;
+ }
+ */
diff --git a/utils/test/vnfcatalogue/cronjobs/README.md b/utils/test/vnfcatalogue/cronjobs/README.md
new file mode 100644
index 000000000..cf27ff8c7
--- /dev/null
+++ b/utils/test/vnfcatalogue/cronjobs/README.md
@@ -0,0 +1,24 @@
+# CRONJOB Directory
+
+## Helper to setup cronjob to fill the vnf table
+
+There are two important parameters that need to be set in github.js
+before running cronjob.
+
+
+```
+ access_token : generate an access token from github account for accessing
+ the github apis. This is necessary as the non access token limit tends to
+ be 50 api calls per hour.
+ delta : the threshold between the last update of the row of the vnf table
+ and current time. It is measured in seconds.
+```
+
+Enter the details namely username and password in the **database.js**.
+Then setup the cronjob by putting the following line in the crontab
+
+In the crontab
+
+```bash
+ node github
+```
diff --git a/utils/test/vnfcatalogue/cronjobs/database.js b/utils/test/vnfcatalogue/cronjobs/database.js
new file mode 100644
index 000000000..a1d926e44
--- /dev/null
+++ b/utils/test/vnfcatalogue/cronjobs/database.js
@@ -0,0 +1,14 @@
+var mysql = require('mysql');
+
+var pool = mysql.createPool({
+ host: 'localhost',
+ user: 'myuser',
+ password: 'mypassword',
+ database: 'vnf_catalogue',
+ connectionLimit: 50,
+ supportBigNumbers: true,
+ multipleStatements: true,
+ dateStrings: 'date'
+});
+
+exports.pool = pool;
diff --git a/utils/test/vnfcatalogue/cronjobs/github.js b/utils/test/vnfcatalogue/cronjobs/github.js
new file mode 100644
index 000000000..05cc6c155
--- /dev/null
+++ b/utils/test/vnfcatalogue/cronjobs/github.js
@@ -0,0 +1,129 @@
+// Important Add your access token here default rate of github is limited to 60 API calls per hour
+var access_token = '*';
+// Important set the delta threshold for repo details updation. For instance if the threshold is
+// set to 1 day(60 * 60 * 24), the cronjob will only update the row if the difference between current
+// time and last_updated time stamp of a repo is greater than one day
+var delta = 60 * 60 * 24;
+
+
+var github = require('octonode');
+db_pool = require('./database').pool;
+async = require('async');
+
+var current_time = Math.floor(new Date().getTime() / 1000);//toISOString().slice(0, 19).replace('T', ' ');
+console.log(current_time);
+
+var get_val_from_header = function(header_link) {
+ // small hack by parsing the header and setting per_page = 1, hence no pagination fetch required
+ result_intermediate = header_link.split(';');
+ result_intermediate = result_intermediate[result_intermediate.length - 2];
+ var reg = /&page=([0-9].*)>/g;
+ var match = reg.exec(result_intermediate);
+ return parseInt(match[1]);
+}
+
+var get_stargazers = function(result, ghrepo, primary_callback, cb) {
+ ghrepo.stargazers({per_page: 1}, function(err, data, headers) {
+ //console.log(JSON.stringify(data));
+ try {
+ result['no_of_stars'] = get_val_from_header(headers['link']);
+ cb(null, result, ghrepo, primary_callback);
+ } catch(err) {
+ result['no_of_stars'] = null;
+ cb(null, result, ghrepo, primary_callback);
+ }
+ });
+}
+
+var get_branches = function(result, ghrepo, primary_callback, cb) {
+ ghrepo.branches({per_page: 1}, function(err, data, headers) {
+ try {
+ result['versions'] = get_val_from_header(headers['link']);
+ cb(null, result, ghrepo, primary_callback);
+ } catch(err) {
+ result['versions'] = null;
+ cb(null, result, ghrepo, primary_callback);
+ }
+ });
+}
+
+var get_contributors = function(result, ghrepo, primary_callback, cb) {
+ ghrepo.contributors({per_page: 1}, function(err, data, headers) {
+ try {
+ result['no_of_developers'] = get_val_from_header(headers['link']);
+ cb(null, result, primary_callback);
+ } catch(err) {
+ result['no_of_developers'] = null;
+ cb(null, result, primary_callback);
+
+ }
+ });
+}
+
+var get_lines_of_code = function(result, cb) {
+ // #TODO
+}
+
+var secondary_callback = function (err, result, primary_callback) {
+ console.log(result);
+ if((result['last_updated'] == null) || (current_time - result['last_updated'] > delta)) {
+ db_pool.getConnection(function(err, connection) {
+ //Use the connection
+ var last_updated = current_time;
+ var no_of_stars = result['no_of_stars'];
+ var versions = result['versions'];
+ var no_of_developers = result['no_of_developers'];
+ sql_query = 'update vnf set last_updated = FROM_UNIXTIME(' + last_updated;
+ sql_query += '), no_of_stars = ' + no_of_stars + ', versions = ' + versions;
+ sql_query += ', no_of_developers = ' + no_of_developers + ' where vnf_id = ';
+ sql_query += result['vnf_id'];
+ console.log(sql_query);
+ connection.query(sql_query, function (error, results, fields) {
+ if (error) throw error;
+ //And done with the connection.
+ primary_callback(null, result['vnf_id'] + ' updated');
+ connection.release();
+ // Handle error after the release.
+ // Don't use the connection here, it has been returned to the pool.
+ });
+ });
+ } else {
+ primary_callback(null, result['vnf_id'] + ' not updated');
+ }
+}
+
+var get_stats = function(vnf_details, callback) {
+ repo = vnf_details['repo_url'];
+ repo = repo.split("/");
+ github_id = repo[repo.length - 2] + '/' + repo[repo.length - 1];
+
+ var async = require('async');
+ var client = github.client(access_token);
+ var ghrepo = client.repo(github_id);
+
+ result = {}
+ result['vnf_id'] = vnf_details['vnf_id'];
+ result['last_updated'] = vnf_details['last_updated'];
+
+ async.waterfall([
+ async.apply(get_stargazers, result, ghrepo, callback),
+ get_branches,
+ get_contributors,
+ //get_lines_of_code,
+ ], secondary_callback);
+}
+
+db_pool.getConnection(function(err, connection) {
+ sql_query = 'select vnf_id, repo_url, UNIX_TIMESTAMP(last_updated) last_updated from vnf';
+ console.log(sql_query);
+ connection.query(sql_query, function (error, results, fields) {
+ if (error) throw error;
+ async.map(results, get_stats, function(error, results) {
+ //console.log(results);
+ console.log(results);
+ process.exit();
+
+ });
+ });
+});
+
diff --git a/utils/test/vnfcatalogue/helpers/migrate.js b/utils/test/vnfcatalogue/helpers/migrate.js
index ec209053c..d884d9c68 100644
--- a/utils/test/vnfcatalogue/helpers/migrate.js
+++ b/utils/test/vnfcatalogue/helpers/migrate.js
@@ -11,8 +11,8 @@ var knex = require('knex')({
client: 'mysql',
connection: {
host : 'localhost',
- user : '*',
- password : '*',
+ user : 'myuser',
+ password : 'mypassword',
database : 'vnf_catalogue',
charset : 'utf8'
}
@@ -28,6 +28,14 @@ function createTable(tableName) {
if (Schema[tableName][key].type === 'text' && Schema[tableName][key].hasOwnProperty('fieldtype')) {
column = table[Schema[tableName][key].type](key, Schema[tableName][key].fieldtype);
}
+ else if (Schema[tableName][key].type === 'enum' && Schema[tableName][key].hasOwnProperty('values') && Schema[tableName][key].nullable === true) {
+ console.log(Schema[tableName][key].values);
+ column = table[Schema[tableName][key].type](key, Schema[tableName][key].values).nullable();
+ }
+ else if (Schema[tableName][key].type === 'enum' && Schema[tableName][key].hasOwnProperty('values')) {
+ console.log(Schema[tableName][key].values);
+ column = table[Schema[tableName][key].type](key, Schema[tableName][key].values).notNullable();
+ }
else if (Schema[tableName][key].type === 'string' && Schema[tableName][key].hasOwnProperty('maxlength')) {
column = table[Schema[tableName][key].type](key, Schema[tableName][key].maxlength);
}
diff --git a/utils/test/vnfcatalogue/helpers/schema.js b/utils/test/vnfcatalogue/helpers/schema.js
index 2aaf99ae2..4a7559ad0 100644
--- a/utils/test/vnfcatalogue/helpers/schema.js
+++ b/utils/test/vnfcatalogue/helpers/schema.js
@@ -31,10 +31,16 @@ var Schema = {
lines_of_code: {type: 'integer', nullable: true, unsigned: true},
versions: {type: 'integer', nullable: true, unsigned: true},
no_of_developers: {type: 'integer', nullable: true, unsigned: true},
+ no_of_stars: {type: 'integer', nullable: true, unsigned: true},
+ license: {type: 'enum', nullable: false, values: ['MIT', 'GPL', 'GPL_V2', 'BSD', 'APACHE']},
+ opnfv_indicator: {type: 'enum', nullable: false, values: ['gold', 'silver', 'platinum']},
+ complexity: {type: 'enum', nullable: true, values: ['low', 'medium', 'high']},
+ activity: {type: 'enum', nullable: true, values: ['low', 'medium', 'high']},
+ last_updated: {type: 'dateTime', nullable: true},
},
tag: {
tag_id: {type: 'increments', nullable: false, primary: true},
- name: {type: 'string', maxlength: 150, nullable: false}
+ tag_name: {type: 'string', maxlength: 150, nullable: false}
},
vnf_tags: {
vnf_tag_id: {type: 'increments', nullable: false, primary: true},