diff options
29 files changed, 3257 insertions, 1 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..4640904 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# TODO diff --git a/onap-client/setup.py b/onap-client/setup.py index a80f832..be6077c 100644 --- a/onap-client/setup.py +++ b/onap-client/setup.py @@ -47,7 +47,7 @@ for file in os.listdir("etc/payloads"): setuptools.setup( name="onap-client", - version="0.1.0", + version="0.2.0", author="Steven Stark", author_email="steven.stark@att.com", description="Python API wrapper for ONAP applications", diff --git a/ovp_testsuite/README.md b/ovp_testsuite/README.md new file mode 100644 index 0000000..4640904 --- /dev/null +++ b/ovp_testsuite/README.md @@ -0,0 +1 @@ +# TODO diff --git a/ovp_testsuite/blank-spec.json b/ovp_testsuite/blank-spec.json new file mode 100644 index 0000000..c046820 --- /dev/null +++ b/ovp_testsuite/blank-spec.json @@ -0,0 +1,100 @@ +{ + "parameters": { + "vendor_name": "", + "software_product_name": "", + "file_path": "", + "vnf_name": "", + "service_name": "", + "service_instance_name": "", + "vnf_instance_name": "", + "tenant_name": "", + "cloud_owner": "", + "cloud_region": "", + "api_type": "", + "service_type": "", + "customer_name": "", + "project_name": "", + "platform": "", + "owning_entity_name": "", + "line_of_business": "" + }, + "spec": [ + { + "type": "LICENSE_MODEL", + "resource_spec": { + "vendor_name": "{{vendor_name}}", + "license_agreement_name": "{{vendor_name}}" + } + }, + { + "type": "VSP", + "resource_spec": { + "software_product_name": "{{software_product_name}}", + "license_model_name": "{{vendor_name}}", + "vendor_name": "{{vendor_name}}", + "file_path": "{{file_path}}", + "category": "Application L4+", + "sub_category": "Web Server", + "description": "New VSP" + } + }, + { + "type": "VNF", + "resource_spec": { + "vnf_name": "{{vnf_name}}", + "software_product_name": "{{software_product_name}}" + } + }, + { + "type": "SERVICE", + "resource_spec": { + "service_name": "{{service_name}}", + "instantiation_type": "A-la-carte", + "contact_id": "cs0008", + "category_name": "Network L4+", + "tag": "automation", + "project_code": "123457", + "environment_context": "General_Revenue-Bearing", + "ecomp_generated_naming": "false", + "description": "Brand New Service", + "service_type": "abcd", + "service_role": "1234", + "resources": [{ + "resource_name": "{{vnf_name}}", + "catalog_resource_name": "{{vnf_name}}", + "origin_type": "VF" + }], + "wait_for_distribution": true + } + }, + { + "type": "SERVICE_INSTANCE", + "resource_spec": { + "service_instance_name": "{{service_instance_name}}", + "model_name": "{{service_name}}", + "tenant_name": "{{tenant_name}}", + "cloud_owner": "{{cloud_owner}}", + "cloud_region": "{{cloud_region}}", + "api_type": "{{api_type}}", + "service_type": "{{service_type}}", + "customer_name": "{{customer_name}}", + "project_name": "{{project_name}}", + "owning_entity_name": "{{owning_entity_name}}" + } + }, + { + "type": "VNF_INSTANCE", + "resource_spec": { + "vnf_instance_name": "{{vnf_instance_name}}", + "service_instance_name": "{{service_instance_name}}", + "model_name": "{{vnf_name}}", + "tenant_name": "{{tenant_name}}", + "cloud_owner": "{{cloud_owner}}", + "cloud_region": "{{cloud_region}}", + "api_type": "{{api_type}}", + "platform": "{{platform}}", + "line_of_business": "{{line_of_business}}" + } + } + ] +}
\ No newline at end of file diff --git a/ovp_testsuite/config.yaml b/ovp_testsuite/config.yaml new file mode 100644 index 0000000..e525ecb --- /dev/null +++ b/ovp_testsuite/config.yaml @@ -0,0 +1,56 @@ +onap_client: + sdc: + SDC_BE_ENDPOINT: https://sdc-be:8443 + SDC_FE_ENDPOINT: https://sdc-fe:9443 + SDC_HC_ENDPOINT: https://sdc-fe:9443 + SDC_BE_ONBOARD_ENDPOINT: https://sdc-onboarding-be:8445 + SDC_DESIGNER_USER_ID: cs0008 + SDC_TESTER_USER_ID: jm0007 + SDC_OPS_USER_ID: op0001 + SDC_GOVERNOR_USER_ID: gv0001 + SDC_DESIGNER_PASSWORD: demo123456! + GLOBAL_SDC_USERNAME: beep + GLOBAL_SDC_PASSWORD: boop + SDC_CONSUMER_CATALOG_PATH: /sdc/v1/catalog + SDC_SCREEN_PATH: /sdc2/rest/v1/screen + SDC_HEALTH_CHECK_PATH: /sdc1/rest/healthCheck + SDC_CATALOG_SERVICES_PATH: /sdc2/rest/v1/catalog/services + SDC_VENDOR_SOFTWARE_PRODUCT_PATH: /onboarding-api/v1.0/vendor-software-products + SDC_CATALOG_RESOURCES_PATH: /sdc2/rest/v1/catalog/resources + SDC_VENDOR_LICENSE_MODEL_PATH: /onboarding-api/v1.0/vendor-license-models + SDC_VENDOR_ITEMS_PATH: /onboarding-api/v1.0/items + SDC_FE_CATALOG_RESOURCES_PATH: /sdc1/feProxy/rest/v1/catalog/resources + ABSTRACT_NODE_PREFIX: abstract_ + SERVICE_DISTRIBUTION: + - "request_service_certification" + - "start_service_certification" + - "finish_service_certification" + - "approve_service_certification" + POLL_INTERVAL: 30 + aai: + AAI_BE_ENDPOINT: https://aai:8443 + AAI_BUSINESS_PATH: /aai/v16/business + AAI_CLOUD_INFRASTRUCTURE_PATH: /aai/v16/cloud-infrastructure + AAI_HEALTH_CHECK_PATH: /aai/util/echo + AAI_USERNAME: AAI + AAI_PASSWORD: AAI + sdnc: + SDNC_ENDPOINT: https://sdnc:8443 + SDNC_OPERATIONS_PATH: /restconf/operations + SDNC_CONFIG_PATH: /restconf/config + SDNC_USERNAME: admin + SDNC_PASSWORD: Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U + vid: + VID_ENDPOINT: https://vid:8443 + VID_MAINTENANCE_PATH: /vid/maintenance + VID_HEALTH_CHECK_PATH: /vid/healthCheck + VID_USERNAME: VID + VID_PASSWORD: VID + so: + SO_ENDPOINT: http://so:8080 + SO_HEALTH_CHECK_PATH: /globalhealthcheck + SO_USERNAME: bpel + SO_PASSWORD: password1$ + SO_SERVICE_INSTANCE_PATH: /onap/so/infra/serviceInstantiation/v7/serviceInstances + SO_ORCHESTRATION_PATH: /onap/so/infra/orchestrationRequests/v7 + LOG_LEVEL: INFO diff --git a/ovp_testsuite/create_configmap.sh b/ovp_testsuite/create_configmap.sh new file mode 100755 index 0000000..417984c --- /dev/null +++ b/ovp_testsuite/create_configmap.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +NAMESPACE=$1 +CONFIGMAP=$2 + +kubectl -n $NAMESPACE create configmap $CONFIGMAP --from-file="$DIR/config.yaml" +if [ $? -ne 0 ]; then + echo "Failed to create configmap, exiting..." + exit 1 +fi diff --git a/ovp_testsuite/create_pod.sh b/ovp_testsuite/create_pod.sh new file mode 100755 index 0000000..f405fe3 --- /dev/null +++ b/ovp_testsuite/create_pod.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +NAMESPACE=$1 +PODNAME=$2 +CONFIGMAP=$3 + +cat <<EOF | kubectl -n $NAMESPACE create -f - +apiVersion: v1 +kind: Pod +metadata: + name: $PODNAME +spec: + containers: + - name: $PODNAME + image: python:3.7-alpine + volumeMounts: + - name: $CONFIGMAP + mountPath: /etc/onap_client + command: ["/bin/sh"] + args: + - -c + - apk update && \ + apk add bash && \ + apk add git && \ + apk add gcc && \ + apk add python3-dev && \ + apk add musl-dev && \ + apk add libffi-dev && \ + apk add openssl-dev && \ + apk add libxml2-dev && \ + apk add libxml2 && \ + apk add libxslt-dev && \ + apk add tk && \ + sh -c 'pip install virtualenv; while true; do sleep 60; done;' + restartPolicy: Never + volumes: + - name: $CONFIGMAP + configMap: + name: $CONFIGMAP + defaultMode: 0755 +EOF + +podstatus="" +COUNTER=0 + +while [ "$podstatus" != "Error" ] && [ "$podstatus" != "Running" ] && [ $COUNTER -lt 60 ]; do + podstatus=`kubectl -n $NAMESPACE get pods | grep $PODNAME | head -1 | awk '{print $3}'` + echo "$PODNAME is $podstatus" + COUNTER=$((COUNTER +1)) + if [ "$podstatus" = "Running" ]; then + break + fi + sleep 30 +done + +if [ "$podstatus" = "Error" ]; then + echo "failed creating pod to execute test, exiting..." + exit 1 +fi + +kubectl -n $NAMESPACE cp "$DIR/../onap-client" "$PODNAME:/tmp/onap_client" +kubectl exec -n $NAMESPACE $PODNAME -- sh -c "cd /tmp/onap_client; pip install -r requirements.txt; pip install . --upgrade" +if [ $? -ne 0 ]; then + echo "Failed to create pod, exiting..." + exit 1 +fi diff --git a/ovp_testsuite/examples/vLB/preloads/base_template_preload.json b/ovp_testsuite/examples/vLB/preloads/base_template_preload.json new file mode 100644 index 0000000..71a9b36 --- /dev/null +++ b/ovp_testsuite/examples/vLB/preloads/base_template_preload.json @@ -0,0 +1,70 @@ +{ + "input": { + "request-information": { + "request-id": "robot12", + "order-version": "1", + "notification-url": "openecomp.org", + "order-number": "1", + "request-action": "PreloadVfModuleRequest" + }, + "sdnc-request-header": { + "svc-request-id": "robot12", + "svc-notification-url": "http://openecomp.org:8080/adapters/rest/SDNCNotify", + "svc-action": "reserve" + }, + "preload-vf-module-topology-information": { + "vnf-topology-identifier-structure": { + "vnf-name": "", + "vnf-type": "" + }, + "vnf-resource-assignments": { + "availability-zones": { + "availability-zone": [] + }, + "vnf-networks": {} + }, + "vf-module-topology": { + "vf-module-topology-identifier": { + "vf-module-type": "", + "vf-module-name": "" + }, + "vf-module-parameters": { + "param": [ + { + "name": "vlb_private_net_id", + "value": "zdfw1lb01_private" + }, + { + "name": "vlb_private_net_cidr", + "value": "192.168.10.0/24" + }, + { + "name": "vlb_0_int_pktgen_private_port_0_mac", + "value": "fa:16:3e:00:01:10" + }, + { + "name": "pktgen_private_net_id", + "value": "zdfw1pktgen01_private" + }, + { + "name": "pktgen_private_net_cidr", + "value": "192.168.9.0/24" + }, + { + "name": "vpg_0_int_pktgen_private_port_0_mac", + "value": "fa:16:3e:00:01:20" + }, + { + "name": "key_name", + "value": "vlb_key" + }, + { + "name": "pub_key", + "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCimjj/DSIHCeC60kimJqw4QFxge/YjfnrXx76tVvm6iNfPGbwu/LzOzS0xDQSw8lcmM71Ys09OBSw9+6HqpBsKL+hDZxWYAyY/qfl0fXWirKoIZbUy6xYHDJEv9z0sMa3NG3d2jRVkANKx9rrpcM2p5GeLalyGTEibNI2ZHQL9L2qjKfHrchi3oQvkMYzj38lzUc6+Sawp/kx2iLgFKQDkRbSSNRUCiB+rmK1ZBIt0XzIogEfQCSDOQVFm4vqtga1QJOtoJzmad1oP6m9YpqPOi7DZxRt373xAdOHRmQJKk9iQhwBaNm8wHTYKUfoKh+chDeVgA/1JECIhgxcqjKUf stark@DUMMYCOMP" + } + ] + } + } + } + } +}
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/preloads/vdns_preload.json b/ovp_testsuite/examples/vLB/preloads/vdns_preload.json new file mode 100644 index 0000000..7dd117f --- /dev/null +++ b/ovp_testsuite/examples/vLB/preloads/vdns_preload.json @@ -0,0 +1,110 @@ +{ + "input": { + "request-information": { + "request-id": "robot12", + "order-version": "1", + "notification-url": "openecomp.org", + "order-number": "1", + "request-action": "PreloadVfModuleRequest" + }, + "sdnc-request-header": { + "svc-request-id": "robot12", + "svc-notification-url": "http://openecomp.org:8080/adapters/rest/SDNCNotify", + "svc-action": "reserve" + }, + "preload-vf-module-topology-information": { + "vnf-topology-identifier-structure": { + "vnf-name": "", + "vnf-type": "" + }, + "vnf-resource-assignments": { + "availability-zones": { + "availability-zone": [] + }, + "vnf-networks": {} + }, + "vf-module-topology": { + "vf-module-topology-identifier": { + "vf-module-type": "", + "vf-module-name": "" + }, + "vf-module-parameters": { + "param": [ + { + "name": "vlb_onap_private_ip_0", + "value": "192.168.100.10" + }, + { + "name": "vlb_int_private_ip_0", + "value": "192.168.10.111" + }, + { + "name": "vlb_int_pktgen_private_ip_0", + "value": "192.168.9.111" + }, + { + "name": "vlb_private_net_cidr", + "value": "192.168.10.0/24" + }, + { + "name": "vdns_image_name", + "value": "xenial-server-cloudimg-amd64-disk1" + }, + { + "name": "vdns_flavor_name", + "value": "m1.medium" + }, + { + "name": "vdns_int_private_ip_0", + "value": "192.168.10.211" + }, + { + "name": "vdns_onap_private_ip_0", + "value": "192.168.100.17" + }, + { + "name": "vdns_name_0", + "value": "stark_vdnc01" + }, + { + "name": "onap_private_net_id", + "value": "private" + }, + { + "name": "onap_private_subnet_id", + "value": "private-subnet" + }, + { + "name": "onap_private_net_cidr", + "value": "192.168.100.0/26" + }, + { + "name": "public_net_id", + "value": "public" + }, + { + "name": "nb_api_version", + "value": "1.2.0" + }, + { + "name": "install_script_version", + "value": "1.6.0-SNAPSHOT" + }, + { + "name": "cloud_env", + "value": "openstack" + }, + { + "name": "sec_group", + "value": "default" + }, + { + "name": "nexus_artifact_repo", + "value": "https://nexus.onap.org" + } + ] + } + } + } + } +}
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/preloads/vlb.json b/ovp_testsuite/examples/vLB/preloads/vlb.json new file mode 100644 index 0000000..50aabae --- /dev/null +++ b/ovp_testsuite/examples/vLB/preloads/vlb.json @@ -0,0 +1,142 @@ +{ + "input": { + "request-information": { + "request-id": "robot12", + "order-version": "1", + "notification-url": "openecomp.org", + "order-number": "1", + "request-action": "PreloadVfModuleRequest" + }, + "sdnc-request-header": { + "svc-request-id": "robot12", + "svc-notification-url": "http://openecomp.org:8080/adapters/rest/SDNCNotify", + "svc-action": "reserve" + }, + "preload-vf-module-topology-information": { + "vnf-topology-identifier-structure": { + "vnf-name": "", + "vnf-type": "" + }, + "vnf-resource-assignments": { + "availability-zones": { + "availability-zone": [] + }, + "vnf-networks": {} + }, + "vf-module-topology": { + "vf-module-topology-identifier": { + "vf-module-type": "", + "vf-module-name": "" + }, + "vf-module-parameters": { + "param": [ + { + "name": "vlb_image_name", + "value": "xenial-server-cloudimg-amd64-disk1" + }, + { + "name": "vlb_flavor_name", + "value": "m1.medium" + }, + { + "name": "vlb_name_0", + "value": "starkvlb01" + }, + { + "name": "vlb_int_private_ip_0", + "value": "192.168.10.111" + }, + { + "name": "vlb_onap_private_ip_0", + "value": "192.168.100.10" + }, + { + "name": "vlb_int_pktgen_private_ip_0", + "value": "192.168.9.111" + }, + { + "name": "vlb_private_net_cidr", + "value": "192.168.10.0/24" + }, + { + "name": "pktgen_private_net_cidr", + "value": "192.168.9.0/24" + }, + { + "name": "vpg_int_pktgen_private_ip_0", + "value": "192.168.9.110" + }, + { + "name": "vpg_onap_private_ip_0", + "value": "192.168.100.20" + }, + { + "name": "vdns_int_private_ip_0", + "value": "192.168.10.211" + }, + { + "name": "vdns_onap_private_ip_0", + "value": "192.168.100.17" + }, + { + "name": "onap_private_net_id", + "value": "private" + }, + { + "name": "onap_private_subnet_id", + "value": "private-subnet" + }, + { + "name": "onap_private_net_cidr", + "value": "192.168.100.0/26" + }, + { + "name": "public_net_id", + "value": "public" + }, + { + "name": "vip", + "value": "192.168.9.112" + }, + { + "name": "gre_ipaddr", + "value": "192.168.10.112" + }, + { + "name": "dcae_collector_ip", + "value": "10.0.4.1" + }, + { + "name": "dcae_collector_port", + "value": "30235" + }, + { + "name": "nb_api_version", + "value": "1.2.0" + }, + { + "name": "install_script_version", + "value": "1.6.0-SNAPSHOT" + }, + { + "name": "demo_artifacts_version", + "value": "1.6.0-SNAPSHOT" + }, + { + "name": "cloud_env", + "value": "openstack" + }, + { + "name": "sec_group", + "value": "default" + }, + { + "name": "nexus_artifact_repo", + "value": "https://nexus.onap.org" + } + ] + } + } + } + } +}
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/preloads/vpkg.json b/ovp_testsuite/examples/vLB/preloads/vpkg.json new file mode 100644 index 0000000..1663a63 --- /dev/null +++ b/ovp_testsuite/examples/vLB/preloads/vpkg.json @@ -0,0 +1,106 @@ +{ + "input": { + "request-information": { + "request-id": "robot12", + "order-version": "1", + "notification-url": "openecomp.org", + "order-number": "1", + "request-action": "PreloadVfModuleRequest" + }, + "sdnc-request-header": { + "svc-request-id": "robot12", + "svc-notification-url": "http://openecomp.org:8080/adapters/rest/SDNCNotify", + "svc-action": "reserve" + }, + "preload-vf-module-topology-information": { + "vnf-topology-identifier-structure": { + "vnf-name": "", + "vnf-type": "" + }, + "vnf-resource-assignments": { + "availability-zones": { + "availability-zone": [] + }, + "vnf-networks": {} + }, + "vf-module-topology": { + "vf-module-topology-identifier": { + "vf-module-type": "", + "vf-module-name": "" + }, + "vf-module-parameters": { + "param": [ + { + "name": "vpg_image_name", + "value": "xenial-server-cloudimg-amd64-disk1" + }, + { + "name": "vpg_flavor_name", + "value": "m1.medium" + }, + { + "name": "vpg_name_0", + "value": "starkvpg01" + }, + { + "name": "vlb_int_pktgen_private_ip_0", + "value": "192.168.9.111" + }, + { + "name": "pktgen_private_net_cidr", + "value": "192.168.9.0/24" + }, + { + "name": "vpg_int_pktgen_private_ip_0", + "value": "192.168.9.110" + }, + { + "name": "vpg_onap_private_ip_0", + "value": "192.168.100.20" + }, + { + "name": "onap_private_net_id", + "value": "private" + }, + { + "name": "onap_private_subnet_id", + "value": "private-subnet" + }, + { + "name": "onap_private_net_cidr", + "value": "192.168.100.0/26" + }, + { + "name": "public_net_id", + "value": "public" + }, + { + "name": "nb_api_version", + "value": "1.2.0" + }, + { + "name": "install_script_version", + "value": "1.6.0-SNAPSHOT" + }, + { + "name": "demo_artifacts_version", + "value": "1.6.0-SNAPSHOT" + }, + { + "name": "cloud_env", + "value": "openstack" + }, + { + "name": "sec_group", + "value": "default" + }, + { + "name": "nexus_artifact_repo", + "value": "https://nexus.onap.org" + } + ] + } + } + } + } +}
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/base_template.env b/ovp_testsuite/examples/vLB/templates/base_template.env new file mode 100644 index 0000000..ac81b89 --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/base_template.env @@ -0,0 +1,19 @@ +parameters: + + # NETWORK_ROLE: private + vlb_private_net_id: zdfw1lb01_private + vlb_private_net_cidr: 192.168.10.0/24 + vlb_0_int_pktgen_private_port_0_mac: fa:16:3e:00:01:10 + + # NETWORK_ROLE: pktgen_private + pktgen_private_net_id: zdfw1pktgen01_private + pktgen_private_net_cidr: 192.168.9.0/24 + vpg_0_int_pktgen_private_port_0_mac: fa:16:3e:00:01:20 + + # METADATA + # vnf_name: vLBMS + # vnf_id: vLoadBalancer_demo_app + + # PRIVATE KEY + key_name: vlb_key + pub_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCVsoLHb2/NxPxb3ZjPCsMmQg4WIP5QatlMY31lHdotxSr0xh0E3DOI6G1bS3TXWfz7HZnoY3ozkvdX0seq8PI9xWnoLrzvo9oQfFv6FFn1e0Pj62EYJ3SGTgDXEU4QjwNHa5zy71Lk2vetl9OIr29X1kPNXuvlMUar3OVHIvxROQKjsbbXFrzxD/9kpdOtl344JId3rahgomPiKzjq/RS6jXJaVMDVaQJAS/C/SwjQirO21ZJL5+YT3sHl9wheAtQAmuhSW7WKw+IzhfguIVxbgSHYQ96oqvOWQIHV41fZ+vn++8+5I3buWmlErfyRe3Vf2dLt0xhn7VqZDA+h1OgJ SS820F@Stevens-MacBook-Pro.local
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/base_template.yaml b/ovp_testsuite/examples/vLB/templates/base_template.yaml new file mode 100644 index 0000000..1437206 --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/base_template.yaml @@ -0,0 +1,172 @@ +########################################################################## +# +#==================LICENSE_START========================================== +# +# +# Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#==================LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# +########################################################################## + +heat_template_version: 2013-05-23 + +description: Heat template that deploys common resources + +############## +# # +# PARAMETERS # +# # +############## + +parameters: + + vlb_private_net_id: + type: string + label: vLoadBalancer private network name or ID + description: Private network that connects vLoadBalancer with vDNSs + pktgen_private_net_id: + type: string + label: vPacketGen private network name or ID + description: Private network that connects vLoadBalancer with vPacketGen + vlb_private_net_cidr: + type: string + label: vLoadBalancer private network CIDR + description: The CIDR of the vLoadBalancer private network + pktgen_private_net_cidr: + type: string + label: vPacketGen private network CIDR + description: The CIDR of the vPacketGen private network + vnf_id: + type: string + label: VNF ID + description: The VNF ID is provided by ONAP + vnf_name: + type: string + label: VNF NAME + description: The VNF NAME is provided by ONAP + vlb_0_int_pktgen_private_port_0_mac: + type: string + label: vLB MAC address + description: MAC address of the vLB used by the vPacketGen VM + vpg_0_int_pktgen_private_port_0_mac: + type: string + label: vPacketGen MAC address + description: MAC address of the vPacketGen used by the vLB VM + key_name: + type: string + label: Key pair name + description: Public/Private key pair name + pub_key: + type: string + label: Public key + description: Public key to be installed on the compute instance + + +############# +# # +# RESOURCES # +# # +############# + +resources: + + random-str_0: + type: OS::Heat::RandomString + properties: + length: 4 + + my_keypair_0: + type: OS::Nova::KeyPair + properties: + name: + str_replace: + template: vnfname_base_rand + params: + base: { get_param: key_name } + rand: { get_resource: random-str_0 } + vnfname: { get_param: vnf_name } + public_key: { get_param: pub_key } + save_private_key: false + + # NETWORK_ROLE: private + int_private_network: + type: OS::Neutron::Net + properties: + name: + str_replace: + template: vnfname_privatenetid + params: + privatenetid: { get_param: vlb_private_net_id } + vnfname: { get_param: vnf_name } + + # NETWORK_ROLE: private + int_private_subnet_0: + type: OS::Neutron::Subnet + properties: + name: + str_replace: + template: vnfname_privatenetid_subnet + params: + privatenetid: { get_param: vlb_private_net_id } + vnfname: { get_param: vnf_name } + network: { get_resource: int_private_network } + cidr: { get_param: vlb_private_net_cidr } + + # NETWORK_ROLE: pktgen_private + int_pktgen_private_network: + type: OS::Neutron::Net + properties: + name: + str_replace: + template: vnfname_privatenetid + params: + privatenetid: { get_param: pktgen_private_net_id } + vnfname: { get_param: vnf_name } + + # NETWORK_ROLE: pktgen_private + int_pktgen_private_subnet_0: + type: OS::Neutron::Subnet + properties: + name: + str_replace: + template: vnfname_privatenetid_subnet + params: + privatenetid: { get_param: pktgen_private_net_id } + vnfname: { get_param: vnf_name } + network: { get_resource: int_pktgen_private_network } + cidr: { get_param: pktgen_private_net_cidr } + + +outputs: + int_private_subnet_id: + value: { get_resource: int_private_subnet_0 } + int_private_net_id: + value: { get_resource: int_private_network } + int_pktgen_private_subnet_id: + value: { get_resource: int_pktgen_private_subnet_0 } + int_pktgen_private_net_id: + value: { get_resource: int_pktgen_private_network } + keypair: + value: { get_resource: my_keypair_0 } + vnf_id: + value: { get_param: vnf_id } + vnf_name: + value: { get_param: vnf_name } + vlb_0_mac_address: + value: { get_param: vlb_0_int_pktgen_private_port_0_mac } + vpg_0_mac_address: + value: { get_param: vpg_0_int_pktgen_private_port_0_mac }
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/vdns.env b/ovp_testsuite/examples/vLB/templates/vdns.env new file mode 100644 index 0000000..65fe16c --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/vdns.env @@ -0,0 +1,38 @@ +parameters: + # VM_TYPE: vlb + vlb_int_private_ip_0: 192.168.10.111 + # vlb_onap_private_ip_0: PUT THE PRIVATE ADDRESS OF THE VLB IN THE ONAP NETWORK SPACE HERE + vlb_int_pktgen_private_ip_0: 192.168.9.111 + vlb_private_net_cidr: 192.168.10.0/24 + keypair: vlb_key + + # VM_TYPE: vdns + vdns_image_name: xenial-server-cloudimg-arm64-disk1 + vdns_flavor_name: m1.medium + vdns_int_private_ip_0: 192.168.10.212 + # vdns_onap_private_ip_0: ASSIGN A PRIVATE ADDRESS IN THE ONAP NETWORK SPACE TO THE VDNS + # vdns_name_0: zdfw1lb01dns01 + + # NETWORK_ROLE: onap_private + # onap_private_net_id: PUT THE ONAP PRIVATE NETWORK NAME HERE + # onap_private_subnet_id: PUT THE ONAP PRIVATE NETWORK NAME HERE + # onap_private_net_cidr: PUT THE ONAP NETWORK CIDR HERE + + # NETWORK_ROLE: private + # int_private_net_id: vLBMS_zdfw1lb01_private + # int_private_subnet_id: vLBMS_zdfw1lb01_private_subnet + + # NETWORK_ROLE: public + # public_net_id: PUT THE NETWORK ID HERE + + # METADATA + # vnf_id: vLoadBalancer_demo_app + # vf_module_id: vLoadBalancer + # vnf_name: vLBMS + + # APP/USER_DATA + nb_api_version: 1.2.0 + install_script_version: 1.5.0-SNAPSHOT + cloud_env: PUT openstack OR rackspace HERE + sec_group: PUT THE ONAP SECURITY GROUP HERE + nexus_artifact_repo: https://nexus.onap.org
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/vdns.yaml b/ovp_testsuite/examples/vLB/templates/vdns.yaml new file mode 100644 index 0000000..d3f6e7d --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/vdns.yaml @@ -0,0 +1,215 @@ +########################################################################## +# +#==================LICENSE_START========================================== +# +# +# Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#==================LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# +########################################################################## + +heat_template_version: 2013-05-23 + +description: Heat template that deploys a vDNS for ONAP + +############## +# # +# PARAMETERS # +# # +############## + +parameters: + vdns_image_name: + type: string + label: Image name or ID + description: Image to be used for compute instance + vdns_flavor_name: + type: string + label: Flavor + description: Type of instance (flavor) to be used + public_net_id: + type: string + label: Public network name or ID + description: Public network that enables remote connection to VNF + int_private_net_id: + type: string + label: vLoadBalancer private network name or ID + description: Private network that connects vLoadBalancer with vDNSs + int_private_subnet_id: + type: string + label: vLoadBalancer private subnet name or ID + description: Private subnet of the network that connects vLoadBalancer with vDNSs + onap_private_net_id: + type: string + label: ONAP management network name or ID + description: Private network that connects ONAP component and the VNF + onap_private_subnet_id: + type: string + label: ONAP management sub-network name or ID + description: Private sub-network that connects ONAP component and the VNF + vlb_private_net_cidr: + type: string + label: vLoadBalancer private network CIDR + description: The CIDR of the vLoadBalancer private network + onap_private_net_cidr: + type: string + label: ONAP private network CIDR + description: The CIDR of the protected private network + vlb_int_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the private network + description: Private IP address that is assigned to the vLoadBalancer to communicate with the vDNSs + vlb_onap_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the ONAP management network + description: Private IP address that is assigned to the vLoadBalancer to communicate with ONAP components + vlb_int_pktgen_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the vPacketGen network + description: Private IP address that is assigned to the vLoadBalancer to communicate with vPacketGen + vdns_int_private_ip_0: + type: string + label: vDNS private IP address towards the private network + description: Private IP address that is assigned to the vDNS to communicate with the vLoadBalancer + vdns_onap_private_ip_0: + type: string + label: vDNS private IP address towards the ONAP management network + description: Private IP address that is assigned to the vDNS to communicate with ONAP components + vdns_name_0: + type: string + label: vDNS name + description: Name of the vDNS + vnf_id: + type: string + label: VNF ID + description: The VNF ID is provided by ONAP + vnf_name: + type: string + label: VNF NAME + description: The VNF NAME is provided by ONAP + vf_module_id: + type: string + label: vFirewall module ID + description: The vLoadBalancer Module ID is provided by ONAP + keypair: + type: string + label: Key pair name + description: Public/Private key pair name + install_script_version: + type: string + label: Installation script version number + description: Version number of the scripts that install the vFW demo app + nb_api_version: + type: string + label: Northbound API version + description: Version number of the health check and config APIs + cloud_env: + type: string + label: Cloud environment + description: Cloud environment (e.g., openstack, rackspace) + nexus_artifact_repo: + type: string + description: Root URL for the Nexus repository for Maven artifacts. + sec_group: + type: string + description: ONAP Security Group + +############# +# # +# RESOURCES # +# # +############# + +resources: + + # NETWORK_ROLE: private + # VM_TYPE: vdns + vdns_0_int_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: int_private_net_id } + fixed_ips: [{"subnet": { get_param: int_private_subnet_id }, "ip_address": { get_param: vdns_int_private_ip_0 }}] + security_groups: + - { get_param: sec_group } + + # NETWORK_ROLE: onap_private + # VM_TYPE: vdns + vdns_0_onap_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: onap_private_net_id } + fixed_ips: [{"subnet": { get_param: onap_private_subnet_id }, "ip_address": { get_param: vdns_onap_private_ip_0 }}] + security_groups: + - { get_param: sec_group } + + # VM_TYPE: vdns + vdns_server_0: + type: OS::Nova::Server + properties: + image: { get_param: vdns_image_name } + flavor: { get_param: vdns_flavor_name } + name: { get_param: vdns_name_0 } + key_name: { get_param: keypair } + networks: + - network: { get_param: public_net_id } + - port: { get_resource: vdns_0_int_private_port_0 } + - port: { get_resource: vdns_0_onap_private_port_0 } + metadata: + vnf_id: { get_param: vnf_id } + vf_module_id: { get_param: vf_module_id } + vnf_name: { get_param: vnf_name } + user_data_format: RAW + user_data: + str_replace: + params: + __lb_oam_int__: { get_param: vlb_onap_private_ip_0 } + __lb_private_ipaddr__: { get_param: vlb_int_private_ip_0 } + __lb_to_pktgen_if__: { get_param: vlb_int_pktgen_private_ip_0} + __local_private_ipaddr__: { get_param: vdns_int_private_ip_0 } + __oam_private_ipaddr__: { get_param: vdns_onap_private_ip_0 } + __nb_api_version__: { get_param: nb_api_version } + __install_script_version__: { get_param: install_script_version } + __vlb_private_net_cidr__: { get_param: vlb_private_net_cidr } + __onap_private_net_cidr__: { get_param: onap_private_net_cidr } + __cloud_env__: { get_param: cloud_env } + __nexus_artifact_repo__: { get_param: nexus_artifact_repo } + template: | + #!/bin/bash + + # Create configuration files + mkdir /opt/config + echo "__lb_oam_int__" > /opt/config/lb_oam_int.txt + echo "__lb_private_ipaddr__" > /opt/config/lb_private_ipaddr.txt + echo "__lb_to_pktgen_if__" > /opt/config/lb_to_pktgen_if.txt + echo "__local_private_ipaddr__" > /opt/config/local_private_ipaddr.txt + echo "__oam_private_ipaddr__" > /opt/config/oam_private_ipaddr.txt + echo "__nb_api_version__" > /opt/config/nb_api_version.txt + echo "__install_script_version__" > /opt/config/install_script_version.txt + echo "__vlb_private_net_cidr__" > /opt/config/vlb_private_net_cidr.txt + echo "__onap_private_net_cidr__" > /opt/config/onap_private_net_cidr.txt + echo "__cloud_env__" > /opt/config/cloud_env.txt + echo "__nexus_artifact_repo__" > /opt/config/nexus_artifact_repo.txt + + # Download and run install script + apt-get update + apt-get -y install unzip + if [[ "__install_script_version__" =~ "SNAPSHOT" ]]; then REPO=snapshots; else REPO=releases; fi + curl -k -L "__nexus_artifact_repo__/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.demo.vnf.vlbms&a=vlbms-scripts&e=zip&v=__install_script_version__" -o /opt/vlbms-scripts-__install_script_version__.zip + unzip -j /opt/vlbms-scripts-__install_script_version__.zip -d /opt v_dns_install.sh + cd /opt + chmod +x v_dns_install.sh + ./v_dns_install.sh
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/vlb.env b/ovp_testsuite/examples/vLB/templates/vlb.env new file mode 100644 index 0000000..4991957 --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/vlb.env @@ -0,0 +1,50 @@ +parameters: + # VM_TYPE: vlb + vlb_image_name: xenial-server-cloudimg-arm64-disk1 + vlb_flavor_name: m1.medium + # vlb_name_0: zdfw1lb01lb01 + vlb_int_private_ip_0: 192.168.10.111 + # vlb_onap_private_ip_0: PUT THE PRIVATE ADDRESS OF THE VLB IN THE ONAP NETWORK SPACE HERE + vlb_int_pktgen_private_ip_0: 192.168.9.111 + vlb_private_net_cidr: 192.168.10.0/24 + pktgen_private_net_cidr: 192.168.9.0/24 + vpg_int_pktgen_private_ip_0: 192.168.9.110 + # vpg_onap_private_ip_0: ASSIGN A PRIVATE ADDRESS IN THE ONAP NETWORK SPACE TO THE VPKTGEN + vdns_int_private_ip_0: 192.168.10.211 + # vdns_onap_private_ip_0: ASSIGN A PRIVATE ADDRESS IN THE ONAP NETWORK SPACE TO THE VDNS + vlb_0_mac_address: fa:16:3e:00:01:10 + vpg_0_mac_address: fa:16:3e:00:01:20 + keypair: vlb_key + + # NETWORK_ROLE: onap_private + # onap_private_net_id: PUT THE ONAP PRIVATE NETWORK NAME HERE + # onap_private_subnet_id: PUT THE ONAP PRIVATE NETWORK NAME HERE + onap_private_net_cidr: PUT THE ONAP NETWORK CIDR HERE + + # NETWORK_ROLE: private + # int_private_net_id: vLBMS_zdfw1lb01_private + # int_private_subnet_id: vLBMS_zdfw1lb01_private_subnet + + # NETWORK_ROLE: pktgen_private + # int_pktgen_private_net_id: vLBMS_zdfw1pktgen01_private + # int_pktgen_private_subnet_id: vLBMS_zdfw1pktgen01_private_subnet + + # NETWORK_ROLE: public + # public_net_id: PUT THE NETWORK ID HERE + + # METADATA + # vnf_id: vLoadBalancer_demo_app + # vf_module_id: vLoadBalancer + # vnf_name: vLBMS + + # APP/USER_DATA + vip: 192.168.9.112 + gre_ipaddr: 192.168.10.112 + dcae_collector_ip: 10.0.4.1 + dcae_collector_port: 30235 + nb_api_version: 1.2.0 + install_script_version: 1.5.0-SNAPSHOT + demo_artifacts_version: 1.5.0-SNAPSHOT + cloud_env: PUT openstack OR rackspace HERE + sec_group: PUT THE ONAP SECURITY GROUP HERE + nexus_artifact_repo: https://nexus.onap.org
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/vlb.yaml b/ovp_testsuite/examples/vLB/templates/vlb.yaml new file mode 100644 index 0000000..7e5db42 --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/vlb.yaml @@ -0,0 +1,302 @@ +########################################################################## +# +#==================LICENSE_START========================================== +# +# +# Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#==================LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# +########################################################################## + +heat_template_version: 2013-05-23 + +description: Heat template that deploys a vLB for ONAP + +############## +# # +# PARAMETERS # +# # +############## + +parameters: + vlb_image_name: + type: string + label: Image name or ID + description: Image to be used for compute instance + vlb_flavor_name: + type: string + label: Flavor + description: Type of instance (flavor) to be used + public_net_id: + type: string + label: Public network name or ID + description: Public network that enables remote connection to VNF + int_private_net_id: + type: string + label: vLoadBalancer private network name or ID + description: Private network that connects vLoadBalancer with vDNSs + int_private_subnet_id: + type: string + label: vLoadBalancer private subnet name or ID + description: Private subnet of the network that connects vLoadBalancer with vDNSs + int_pktgen_private_net_id: + type: string + label: vPacketGen private network name or ID + description: Private network that connects vLoadBalancer with vPacketGen + int_pktgen_private_subnet_id: + type: string + label: vPacketGen private subnet name or ID + description: Private subnet of the network that connects vLoadBalancer with vPacketGen + onap_private_net_id: + type: string + label: ONAP management network name or ID + description: Private network that connects ONAP component and the VNF + onap_private_subnet_id: + type: string + label: ONAP management sub-network name or ID + description: Private sub-network that connects ONAP component and the VNF + vlb_private_net_cidr: + type: string + label: vLoadBalancer private network CIDR + description: The CIDR of the vLoadBalancer private network + pktgen_private_net_cidr: + type: string + label: vPacketGen private network CIDR + description: The CIDR of the vPacketGen private network + onap_private_net_cidr: + type: string + label: ONAP private network CIDR + description: The CIDR of the protected private network + vlb_int_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the private network + description: Private IP address that is assigned to the vLoadBalancer to communicate with the vDNSs + vlb_onap_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the ONAP management network + description: Private IP address that is assigned to the vLoadBalancer to communicate with ONAP components + vlb_int_pktgen_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the vPacketGen network + description: Private IP address that is assigned to the vLoadBalancer to communicate with vPacketGen + vdns_int_private_ip_0: + type: string + label: vDNS private IP address towards the private network + description: Private IP address that is assigned to the vDNS to communicate with the vLoadBalancer + vdns_onap_private_ip_0: + type: string + label: vDNS private IP address towards the ONAP management network + description: Private IP address that is assigned to the vDNS to communicate with ONAP components + vpg_int_pktgen_private_ip_0: + type: string + label: vPacketGen private IP address towards the vPacketGen private network + description: Private IP address that is assigned to the vPacketGen to communicate with the vLoadBalancer + vpg_onap_private_ip_0: + type: string + label: vPacketGen private IP address towards the ONAP management network + description: Private IP address that is assigned to the vPacketGen to communicate with ONAP components + vlb_0_mac_address: + type: string + label: vLB MAC address + description: MAC address of the vLB used by the vPacketGen VM + vpg_0_mac_address: + type: string + label: vPacketGen MAC address + description: MAC address of the vPacketGen used by the vLB VM + vip: + type: string + label: Virtual Private IP of the vLoadBalancer + description: Virtual Private IP that is assigned to the vLoadBalancer's VPP layer + gre_ipaddr: + type: string + label: IP Address of the GRE tunnel + description: IP address assigned to the GRE tunnel on the vLoadBalancer + vlb_name_0: + type: string + label: vLoadBalancer name + description: Name of the vLoadBalancer + vnf_id: + type: string + label: VNF ID + description: The VNF ID is provided by ONAP + vnf_name: + type: string + label: VNF NAME + description: The VNF NAME is provided by ONAP + vf_module_id: + type: string + label: vFirewall module ID + description: The vLoadBalancer Module ID is provided by ONAP + dcae_collector_ip: + type: string + label: DCAE collector IP address + description: IP address of the DCAE collector + dcae_collector_port: + type: string + label: DCAE collector port + description: Port of the DCAE collector + keypair: + type: string + label: Key pair name + description: Public/Private key pair name + demo_artifacts_version: + type: string + label: Artifacts version used in demo vnfs + description: Version number for downloading the vPacketGen streams for VPP and VES + nb_api_version: + type: string + label: Northbound API version + description: Version number of the health check and config APIs + install_script_version: + type: string + label: Installation script version number + description: Version number of the scripts that install the vLB demo app + cloud_env: + type: string + label: Cloud environment + description: Cloud environment (e.g., openstack, rackspace) + nexus_artifact_repo: + type: string + description: Root URL for the Nexus repository for Maven artifacts. + sec_group: + type: string + description: ONAP Security Group + +############# +# # +# RESOURCES # +# # +############# + +resources: + + # NETWORK_ROLE: private + # VM_TYPE: vlb + vlb_0_int_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: int_private_net_id } + fixed_ips: [{"subnet": { get_param: int_private_subnet_id }, "ip_address": { get_param: vlb_int_private_ip_0 }}] + security_groups: + - { get_param: sec_group } + + # NETWORK_ROLE: onap_private + # VM_TYPE: vlb + vlb_0_onap_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: onap_private_net_id } + fixed_ips: [{"subnet": { get_param: onap_private_subnet_id }, "ip_address": { get_param: vlb_onap_private_ip_0 }}] + security_groups: + - { get_param: sec_group } + + # NETWORK_ROLE: pktgen_private + # VM_TYPE: vlb + vlb_0_int_pktgen_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: int_pktgen_private_net_id } + fixed_ips: [{"subnet": { get_param: int_pktgen_private_subnet_id }, "ip_address": { get_param: vlb_int_pktgen_private_ip_0 }}] + mac_address: { get_param: vlb_0_mac_address } + security_groups: + - { get_param: sec_group } + + vlb_0_public_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: public_net_id } + + # VM_TYPE: vlb + vlb_server_0: + type: OS::Nova::Server + properties: + image: { get_param: vlb_image_name } + flavor: { get_param: vlb_flavor_name } + name: { get_param: vlb_name_0 } + key_name: { get_param: keypair } + networks: + - port: { get_resource: vlb_0_public_port_0 } + - port: { get_resource: vlb_0_int_private_port_0 } + - port: { get_resource: vlb_0_onap_private_port_0 } + - port: { get_resource: vlb_0_int_pktgen_private_port_0 } + metadata: + vnf_id: { get_param: vnf_id } + vf_module_id: { get_param: vf_module_id } + vnf_name: { get_param: vnf_name } + user_data_format: RAW + user_data: + str_replace: + params: + __dcae_collector_ip__: { get_param: dcae_collector_ip } + __dcae_collector_port__: { get_param: dcae_collector_port } + __ip_to_dns_net__: { get_param: vlb_int_private_ip_0 } + __ip_to_pktgen_net__: { get_param: vlb_int_pktgen_private_ip_0 } + __oam_vpktgen_ip__: { get_param: vpg_onap_private_ip_0 } + __oam_vdns_ip__: { get_param: vdns_onap_private_ip_0 } + __vip__: { get_param: vip } + __gre_ipaddr__: { get_param: gre_ipaddr } + __pktgen_ipaddr__: { get_param: vpg_int_pktgen_private_ip_0 } + __vdns_ipaddr__: { get_param: vdns_int_private_ip_0 } + __oam_private_ipaddr__: { get_param: vlb_onap_private_ip_0 } + __demo_artifacts_version__: { get_param: demo_artifacts_version } + __nb_api_version__: { get_param: nb_api_version } + __install_script_version__: { get_param: install_script_version } + __vlb_private_net_cidr__: { get_param: vlb_private_net_cidr } + __onap_private_net_cidr__: { get_param: onap_private_net_cidr } + __pktgen_private_net_cidr__: { get_param: pktgen_private_net_cidr } + __pktgen_mac__: { get_param: vpg_0_mac_address } + __cloud_env__: { get_param: cloud_env } + __nexus_artifact_repo__: { get_param: nexus_artifact_repo } + template: | + #!/bin/bash + + # Create configuration files + mkdir /opt/config + echo "__dcae_collector_ip__" > /opt/config/dcae_collector_ip.txt + echo "__dcae_collector_port__" > /opt/config/dcae_collector_port.txt + echo "__ip_to_dns_net__" > /opt/config/ip_to_dns_net.txt + echo "__ip_to_pktgen_net__" > /opt/config/ip_to_pktgen_net.txt + echo "__oam_vpktgen_ip__" > /opt/config/oam_vpktgen_ip.txt + echo "__oam_vdns_ip__" > /opt/config/oam_vdns_ip.txt + echo "__vip__" > /opt/config/vip.txt + echo "__gre_ipaddr__" > /opt/config/gre_ipaddr.txt + echo "__pktgen_ipaddr__" > /opt/config/pktgen_ipaddr.txt + echo "__vdns_ipaddr__" > /opt/config/vdns_ipaddr.txt + echo "__oam_private_ipaddr__" > /opt/config/oam_private_ipaddr.txt + echo "__demo_artifacts_version__" > /opt/config/demo_artifacts_version.txt + echo "__nb_api_version__" > /opt/config/nb_api_version.txt + echo "__install_script_version__" > /opt/config/install_script_version.txt + echo "__vlb_private_net_cidr__" > /opt/config/vlb_private_net_cidr.txt + echo "__pktgen_private_net_cidr__" > /opt/config/pktgen_private_net_cidr.txt + echo "__onap_private_net_cidr__" > /opt/config/onap_private_net_cidr.txt + echo "__pktgen_mac__" > /opt/config/pktgen_mac.txt + echo "__cloud_env__" > /opt/config/cloud_env.txt + echo "__nexus_artifact_repo__" > /opt/config/nexus_artifact_repo.txt + + # Download and run install script + apt-get update + apt-get -y install unzip + if [[ "__install_script_version__" =~ "SNAPSHOT" ]]; then REPO=snapshots; else REPO=releases; fi + curl -k -L "__nexus_artifact_repo__/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.demo.vnf.vlbms&a=vlbms-scripts&e=zip&v=__install_script_version__" -o /opt/vlbms-scripts-__install_script_version__.zip + unzip -j /opt/vlbms-scripts-__install_script_version__.zip -d /opt v_lb_install.sh + cd /opt + chmod +x v_lb_install.sh + ./v_lb_install.sh + +outputs: + oam_management_v4_address: + value: { get_attr: [vlb_0_public_port_0, fixed_ips, 0, ip_address] } diff --git a/ovp_testsuite/examples/vLB/templates/vpkg.env b/ovp_testsuite/examples/vLB/templates/vpkg.env new file mode 100644 index 0000000..2f5f735 --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/vpkg.env @@ -0,0 +1,38 @@ +parameters: + # VM_TYPE: vpg + # vpg_name_0: zdfw1lb01pg01 + vpg_image_name: xenial-server-cloudimg-arm64-disk1 + vpg_flavor_name: m1.medium + vpg_int_pktgen_private_ip_0: 192.168.9.110 + # vpg_onap_private_ip_0: ASSIGN A PRIVATE ADDRESS IN THE ONAP NETWORK SPACE TO THE VPKTGEN + vlb_int_pktgen_private_ip_0: 192.168.9.111 + vlb_0_mac_address: fa:16:3e:00:01:10 + vpg_0_mac_address: fa:16:3e:00:01:20 + keypair: vlb_key + + # NETWORK_ROLE: onap_private + # onap_private_net_id: PUT THE ONAP PRIVATE NETWORK NAME HERE + # onap_private_subnet_id: PUT THE ONAP PRIVATE NETWORK NAME HERE + # onap_private_net_cidr: PUT THE ONAP NETWORK CIDR HERE + + # NETWORK_ROLE: pktgen_private + # int_pktgen_private_net_id: vLBMS_zdfw1pktgen01_private + # int_pktgen_private_subnet_id: vLBMS_zdfw1pktgen01_private_subnet + pktgen_private_net_cidr: 192.168.9.0/24 + + # NETWORK_ROLE: public + # public_net_id: PUT THE NETWORK ID HERE + + # METADATA + # vnf_name: vLBMS + # vnf_id: vLoadBalancer_demo_app + # vf_module_id: vLoadBalancer + + # APP/USER_DATA + pg_int: 192.168.9.109 + nb_api_version: 1.2.0 + demo_artifacts_version: 1.5.0-SNAPSHOT + install_script_version: 1.5.0-SNAPSHOT + # cloud_env: PUT openstack OR rackspace HERE + # sec_group: PUT THE ONAP SECURITY GROUP HERE + nexus_artifact_repo: https://nexus.onap.org
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/templates/vpkg.yaml b/ovp_testsuite/examples/vLB/templates/vpkg.yaml new file mode 100644 index 0000000..e71e0bb --- /dev/null +++ b/ovp_testsuite/examples/vLB/templates/vpkg.yaml @@ -0,0 +1,226 @@ +########################################################################## +# +#==================LICENSE_START========================================== +# +# +# Copyright (c) 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#==================LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# +########################################################################## + +heat_template_version: 2013-05-23 + +description: Heat template that deploys a vPacketGen for ONAP + +############## +# # +# PARAMETERS # +# # +############## + +parameters: + vpg_image_name: + type: string + label: Image name or ID + description: Image to be used for compute instance + vpg_flavor_name: + type: string + label: Flavor + description: Type of instance (flavor) to be used + public_net_id: + type: string + label: Public network name or ID + description: Public network that enables remote connection to VNF + int_pktgen_private_net_id: + type: string + label: vPacketGen private network name or ID + description: Private network that connects vLoadBalancer with vPacketGen + int_pktgen_private_subnet_id: + type: string + label: vPacketGen private subnet name or ID + description: Private subnet of the network that connects vLoadBalancer with vPacketGen + onap_private_net_id: + type: string + label: ONAP management network name or ID + description: Private network that connects ONAP component and the VNF + onap_private_subnet_id: + type: string + label: ONAP management sub-network name or ID + description: Private sub-network that connects ONAP component and the VNF + pktgen_private_net_cidr: + type: string + label: vPacketGen private network CIDR + description: The CIDR of the vPacketGen private network + onap_private_net_cidr: + type: string + label: ONAP private network CIDR + description: The CIDR of the protected private network + vpg_int_pktgen_private_ip_0: + type: string + label: vPacketGen private IP address towards the vPacketGen private network + description: Private IP address that is assigned to the vPacketGen to communicate with the vLoadBalancer + vpg_onap_private_ip_0: + type: string + label: vPacketGen private IP address towards the ONAP management network + description: Private IP address that is assigned to the vPacketGen to communicate with ONAP components + vlb_int_pktgen_private_ip_0: + type: string + label: vLoadBalancer private IP address towards the vPacketGen network + description: Private IP address that is assigned to the vLoadBalancer to communicate with vPacketGen + vlb_0_mac_address: + type: string + label: vLB MAC address + description: MAC address of the vLB used by the vPacketGen VM + vpg_0_mac_address: + type: string + label: vPacketGen MAC address + description: MAC address of the vPacketGen used by the vLB VM + pg_int: + type: string + label: IP Address of the output vPacketGen interface + description: IP address assigned to the output interface of the vPacketGen's VPP layer + vpg_name_0: + type: string + label: vPKTGEN name + description: Name of the vPKTGEN + vnf_id: + type: string + label: VNF ID + description: The VNF ID is provided by ONAP + vnf_name: + type: string + label: VNF NAME + description: The VNF NAME is provided by ONAP + vf_module_id: + type: string + label: vFirewall module ID + description: The vLoadBalancer Module ID is provided by ONAP + keypair: + type: string + label: Key pair name + description: Public/Private key pair name + demo_artifacts_version: + type: string + label: Artifacts version used in demo vnfs + description: Version number for downloading the vPacketGen streams for VPP and VES + nb_api_version: + type: string + label: Northbound API version + description: Version number of the health check and config APIs + install_script_version: + type: string + label: Installation script version number + description: Version number of the scripts that install the vLB demo app + cloud_env: + type: string + label: Cloud environment + description: Cloud environment (e.g., openstack, rackspace) + nexus_artifact_repo: + type: string + description: Root URL for the Nexus repository for Maven artifacts. + sec_group: + type: string + description: ONAP Security Group + +############# +# # +# RESOURCES # +# # +############# + +resources: + + # NETWORK_ROLE: pktgen_private + # VM_TYPE: vpg + vpg_0_int_pktgen_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: int_pktgen_private_net_id } + fixed_ips: [{"subnet": { get_param: int_pktgen_private_subnet_id }, "ip_address": { get_param: vpg_int_pktgen_private_ip_0 }}] + mac_address: { get_param: vpg_0_mac_address } + security_groups: + - { get_param: sec_group } + + # NETWORK_ROLE: onap_private + # VM_TYPE: vpg + vpg_0_onap_private_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: onap_private_net_id } + fixed_ips: [{"subnet": { get_param: onap_private_subnet_id }, "ip_address": { get_param: vpg_onap_private_ip_0 }}] + security_groups: + - { get_param: sec_group } + + # VM_TYPE: vpg + vpg_server_0: + type: OS::Nova::Server + properties: + image: { get_param: vpg_image_name } + flavor: { get_param: vpg_flavor_name } + name: { get_param: vpg_name_0 } + key_name: { get_param: keypair } + metadata: + vnf_id: { get_param: vnf_id } + vf_module_id: { get_param: vf_module_id } + vnf_name: { get_param: vnf_name } + networks: + - network: { get_param: public_net_id } + - port: { get_resource: vpg_0_int_pktgen_private_port_0 } + - port: { get_resource: vpg_0_onap_private_port_0 } + user_data_format: RAW + user_data: + str_replace: + params: + __local_private_ipaddr__: { get_param: vpg_int_pktgen_private_ip_0 } + __oam_private_ipaddr__: { get_param: vpg_onap_private_ip_0 } + __onap_private_net_cidr__: { get_param: onap_private_net_cidr } + __pktgen_private_net_cidr__: { get_param: pktgen_private_net_cidr } + __vlb_ipaddr__: { get_param: vlb_int_pktgen_private_ip_0 } + __demo_artifacts_version__: { get_param: demo_artifacts_version } + __nb_api_version__: { get_param: nb_api_version } + __install_script_version__: { get_param: install_script_version } + __pg_int__: { get_param: pg_int } + __vlb_mac__: { get_param: vlb_0_mac_address } + __cloud_env__: { get_param: cloud_env } + __nexus_artifact_repo__: { get_param: nexus_artifact_repo } + template: | + #!/bin/bash + + # Create configuration files + mkdir /opt/config + echo "__oam_private_ipaddr__" > /opt/config/oam_private_ipaddr.txt + echo "__onap_private_net_cidr__" > /opt/config/onap_private_net_cidr.txt + echo "__local_private_ipaddr__" > /opt/config/local_private_ipaddr.txt + echo "__pktgen_private_net_cidr__" > /opt/config/pktgen_private_net_cidr.txt + echo "__vlb_ipaddr__" > /opt/config/vlb_ipaddr.txt + echo "__demo_artifacts_version__" > /opt/config/demo_artifacts_version.txt + echo "__nb_api_version__" > /opt/config/nb_api_version.txt + echo "__install_script_version__" > /opt/config/install_script_version.txt + echo "__pg_int__" > /opt/config/pg_int.txt + echo "__vlb_mac__" > /opt/config/vlb_mac.txt + echo "__cloud_env__" > /opt/config/cloud_env.txt + echo "__nexus_artifact_repo__" > /opt/config/nexus_artifact_repo.txt + + # Download and run install script + apt-get update + apt-get -y install unzip + if [[ "__install_script_version__" =~ "SNAPSHOT" ]]; then REPO=snapshots; else REPO=releases; fi + curl -k -L "__nexus_artifact_repo__/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.demo.vnf.vlbms&a=vlbms-scripts&e=zip&v=__install_script_version__" -o /opt/vlbms-scripts-__install_script_version__.zip + unzip -j /opt/vlbms-scripts-__install_script_version__.zip -d /opt v_packetgen_install.sh + cd /opt + chmod +x v_packetgen_install.sh + ./v_packetgen_install.sh
\ No newline at end of file diff --git a/ovp_testsuite/examples/vLB/vnf-details.json b/ovp_testsuite/examples/vLB/vnf-details.json new file mode 100644 index 0000000..44bd939 --- /dev/null +++ b/ovp_testsuite/examples/vLB/vnf-details.json @@ -0,0 +1,37 @@ +{ + "vnf_name": "vLB_Test_VNF", + "description": "Some Description", + "modules": [ + { + "filename": "base_template.yaml", + "isBase": "true", + "preload": "base_template_preload.json" + }, + { + "filename": "vpkg.yaml", + "isBase": "false", + "preload": "vpkg.json" + }, + { + "filename": "vlb.yaml", + "isBase": "false", + "preload": "vlb.json" + }, + { + "filename": "vdns.yaml", + "isBase": "false", + "preload": "vdns_preload.json" + } + ], + "api_type": "gr_api", + "customer": "ONAPCUSTOMER", + "service_type": "ONAPSERVICE", + "tenant_name": "onap_project", + "region_id": "ONAPREGION", + "cloud_owner": "ONAPOWNER", + "project_name": "testproject", + "owning_entity": "testentity", + "platform": "testplatform", + "line_of_business": "testlob", + "os_password": "supersecret" +} diff --git a/ovp_testsuite/instantiate-k8s.sh b/ovp_testsuite/instantiate-k8s.sh new file mode 100755 index 0000000..99c19f6 --- /dev/null +++ b/ovp_testsuite/instantiate-k8s.sh @@ -0,0 +1,177 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +RANDOM_STRING=`cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-zA-Z0-9' | head -c 4` +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +NAMESPACE= +VNF_FOLDER= +OUTPUT_DIR=/tmp/OVP-$RANDOM_STRING +PODNAME="ovp-test" +CONFIGMAP="ovp-test-suite-vol" + +function tar_output() { + OUTPUT=$1 + set +x + + echo "" + echo "================================================================" + echo "OVP Test Case has finished, generating output in $OUTPUT_DIR." + echo "" + echo "--------------------Results--------------------" + echo "Test Start Time: $STARTTIME" + echo "VVP Validation Scripts: $VVP_STATUS" + echo "ONAP Modeling and Instantiation: $MODELING_STATUS" + echo "Stack Validation: $STACK_VALIDATION_STATUS" + echo "" + + "$DIR/ovp-report.sh" $NAMESPACE $PODNAME $OUTPUT_DIR $RANDOM_STRING $STARTTIME $VVP_STATUS $MODELING_STATUS $STACK_VALIDATION_STATUS + pushd . + cd $OUTPUT + tar -cvzf ovp-test.tar.gz * + popd +} + +function check_required_parameter() { + # arg1 = parameter + # arg2 = parameter name + if [ -z "$1" ]; then + echo "$2 was not was provided. This parameter is required." + exit 1 + fi +} + +while test $# -gt 0; do + case "$1" in + -h|--help) + echo "./instantiate-k8s.sh [options]" + echo " " + echo "required:" + echo "-n, --namespace <namespace> namespace that onap is running under." + echo "-f, --folder <folder> path to folder containing heat templates, preloads, and vnf-details.json." + echo " " + echo "This script executes the OVP VNF instantiation testsuite." + echo "- It creates a container that will contain all of the installation requirements." + echo "- It models, distributes, and instantiates a heat-based VNF." + echo "- It copies the logs to an output directory, and creates a tarball for upload to the OVP portal." + echo "" + exit 0 + ;; + -n|--namespace) + shift + NAMESPACE=$1 + shift + ;; + -f|--folder) + shift + VNF_FOLDER=$1 + shift + ;; + *) + echo "Unknown Argument $1. Try running with --help." + exit 0 + ;; + esac +done + +set -x + +check_required_parameter "$NAMESPACE" "--namespace" +check_required_parameter "$VNF_FOLDER" "--folder" + +if [ -z $KUBECONFIG ]; then + echo "KUBECONFIG variable not found, exiting..." + exit 1 +fi + +kubectl -n $NAMESPACE get configmap $CONFIGMAP +if [ $? -ne 0 ]; then + "$DIR/create_configmap.sh" $NAMESPACE $CONFIGMAP + if [ $? -ne 0 ]; then + echo "Failed to create configmap, exiting..." + exit 1 + fi +fi + +kubectl -n $NAMESPACE get pod $PODNAME +if [ $? -ne 0 ]; then + "$DIR/create_pod.sh" $NAMESPACE $PODNAME $CONFIGMAP + if [ $? -ne 0 ]; then + echo "Failed to create pod, exiting..." + exit 1 + fi +fi + +mkdir "$OUTPUT_DIR" +echo "" +echo "Your output directory is $OUTPUT_DIR, look here for logs after the test has finished." +echo "" +sleep 5 + +if [ ! -d $VNF_FOLDER ]; then + echo "VNF Folder $VNF_FOLDER not found, exiting..." + exit 1 +fi + +kubectl -n $NAMESPACE cp $VNF_FOLDER $PODNAME:/tmp/$RANDOM_STRING +STARTTIME=`date +%s` + +trap 'tar_output "$OUTPUT_DIR"' EXIT + +VVP_STATUS=NOT_STARTED +MODELING_STATUS=NOT_STARTED +STACK_VALIDATION_STATUS=NOT_STARTED + +"$DIR/validation-scripts.sh" $NAMESPACE $PODNAME $OUTPUT_DIR $RANDOM_STRING +if [ $? -ne 0 ]; then + VVP_STATUS=FAIL + exit 1 +fi +VVP_STATUS=SUCCESS + +"$DIR/model-and-distribute.sh" $NAMESPACE $PODNAME $OUTPUT_DIR $RANDOM_STRING +if [ $? -ne 0 ]; then + MODELING_STATUS=FAIL + exit 1 +fi +MODELING_STATUS=SUCCESS + +"$DIR/stack-validation.sh" $NAMESPACE $PODNAME $OUTPUT_DIR $RANDOM_STRING +if [ $? -ne 0 ]; then + STACK_VALIDATION_STATUS=FAIL + exit 1 +fi +STACK_VALIDATION_STATUS=SUCCESS diff --git a/ovp_testsuite/model-and-distribute.py b/ovp_testsuite/model-and-distribute.py new file mode 100644 index 0000000..be71482 --- /dev/null +++ b/ovp_testsuite/model-and-distribute.py @@ -0,0 +1,167 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +import argparse +import copy +import json +import sys + +from onap_client.engine import SpecEngine +from onap_client.exceptions import ResourceAlreadyExistsException +from zipfile import ZipFile +from os import listdir +from os.path import isfile, join + + +def run_engine(spec): + engine = SpecEngine() + + engine.load_spec(spec) + + return engine.spec + +def load_spec(spec): + with open(spec, "r") as f: + jdata = json.loads(f.read()) + + return jdata + +def create_heat_zip(filepath, output_path): + onlyfiles = [f for f in listdir(filepath) if isfile(join(filepath, f))] + + with ZipFile(output_path, 'w') as zipObj: + for filename in onlyfiles: + zipObj.write(join(filepath, filename), arcname=filename) + +def resolve_spec(vnf_details, blank_spec, build_tag, heat_zip, vnf_folder): + blank_spec["parameters"]["vendor_name"] = "vendor{}".format(build_tag) + blank_spec["parameters"]["software_product_name"] = "vsp{}".format(build_tag) + blank_spec["parameters"]["file_path"] = heat_zip + blank_spec["parameters"]["vnf_name"] = "vnf{}".format(build_tag) + blank_spec["parameters"]["service_name"] = "service{}".format(build_tag) + blank_spec["parameters"]["service_instance_name"] = "SI{}".format(build_tag) + blank_spec["parameters"]["vnf_instance_name"] = "SI_VNF{}".format(build_tag) + blank_spec["parameters"]["tenant_name"] = vnf_details.get("tenant_name") + blank_spec["parameters"]["cloud_owner"] = vnf_details.get("cloud_owner") + blank_spec["parameters"]["cloud_region"] = vnf_details.get("region_id") + blank_spec["parameters"]["api_type"] = vnf_details.get("api_type").upper() + blank_spec["parameters"]["service_type"] = vnf_details.get("service_type") + blank_spec["parameters"]["customer_name"] = vnf_details.get("customer") + blank_spec["parameters"]["project_name"] = vnf_details.get("project_name") + blank_spec["parameters"]["platform"] = vnf_details.get("platform") + blank_spec["parameters"]["owning_entity_name"] = vnf_details.get("owning_entity") + blank_spec["parameters"]["line_of_business"] = vnf_details.get("line_of_business") + + for module in vnf_details.get("modules"): + blank_spec["spec"].append(resolve_module(module, vnf_folder, build_tag)) + + return blank_spec + + +def resolve_module(module, vnf_folder, build_tag): + module_spec = {"type": "MODULE_INSTANCE", "resource_spec": {}} + module_spec["resource_spec"]["module_instance_name"] = "SI_VNF_{}_{}".format(build_tag, module.get("filename").split(".")[0]) + module_spec["resource_spec"]["heat_template_name"] = module.get("filename") + module_spec["resource_spec"]["preload_path"] = "{}/preloads/{}".format(vnf_folder, module.get("preload")) + module_spec["resource_spec"]["vnf_instance_name"] = "{{vnf_instance_name}}" + module_spec["resource_spec"]["service_instance_name"] = "{{service_instance_name}}" + module_spec["resource_spec"]["tenant_name"] = "{{tenant_name}}" + module_spec["resource_spec"]["cloud_owner"] = "{{cloud_owner}}" + module_spec["resource_spec"]["cloud_region"] = "{{cloud_region}}" + module_spec["resource_spec"]["api_type"] = "{{api_type}}" + + return module_spec + + +def create_stack_details(full_spec, vnf_folder, build_tag): + resources = full_spec.get("spec") + stack_data = [] + for resource in resources: + if resource.get("type") == "MODULE_INSTANCE": + module_data = {} + module = resource.get("resource_spec") + module_data["template_name"] = "{}/templates/{}".format(vnf_folder, module.get("heat_template_name")) + module_data["preload_name"] = "{}".format(module.get("preload_path")) + module_data["stack_name"] = "{}".format(module.get("module_instance_name")) + stack_data.append(module_data) + + with open("/tmp/vnf-deployment-details-{}.json".format(build_tag), "w") as f: + json.dump(stack_data, f, indent=4) + +def main(vnf_folder, spec, build_tag): + modeling_spec = load_spec(spec) + vnf_details = load_spec("{}/vnf-details.json".format(vnf_folder)) + heat_zip = "/tmp/heat{}.zip".format(build_tag) + create_heat_zip("{}/templates".format(vnf_folder), heat_zip) + + spec = resolve_spec(vnf_details, modeling_spec, build_tag, heat_zip, vnf_folder) + + print(json.dumps(spec, indent=4)) + + full_spec = run_engine(spec) + + return full_spec + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="VNF Modeling Script") + + parser.add_argument( + "--vnf-folder", + required=True, + help="Full path to the folder containing preloads, templates, and vnf-details.json.", + ) + + parser.add_argument( + "--spec", + required=True, + help="Full path to the blank spec for modeling and instantiating a VNF.", + ) + + parser.add_argument( + "--build-tag", + required=True, + help="Unique build tag.", + ) + + arguments = parser.parse_args() + + vnf_folder = arguments.vnf_folder + spec = arguments.spec + build_tag = arguments.build_tag + + full_spec = main(vnf_folder, spec, build_tag) + + create_stack_details(full_spec, vnf_folder, build_tag) diff --git a/ovp_testsuite/model-and-distribute.sh b/ovp_testsuite/model-and-distribute.sh new file mode 100755 index 0000000..5348ecb --- /dev/null +++ b/ovp_testsuite/model-and-distribute.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +set -x + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +NAMESPACE=$1 +PODNAME=$2 +OUTPUT_DIR=$3 +BUILD_TAG=$4 + +kubectl -n $NAMESPACE cp $DIR/blank-spec.json $PODNAME:/tmp/blank-spec.json +kubectl -n $NAMESPACE cp $DIR/model-and-distribute.py $PODNAME:/tmp/modeling.py + +exec > >(tee -i $OUTPUT_DIR/log.txt) +exec 2>&1 + +kubectl -n $NAMESPACE exec $PODNAME -- sh -c "python /tmp/modeling.py --vnf-folder /tmp/$BUILD_TAG --spec /tmp/blank-spec.json --build-tag $BUILD_TAG" +if [ $? -ne 0 ]; then + echo "Failed during modeling/instantiation, exiting..." + exit 1 +fi diff --git a/ovp_testsuite/ovp-report.py b/ovp_testsuite/ovp-report.py new file mode 100644 index 0000000..d858990 --- /dev/null +++ b/ovp_testsuite/ovp-report.py @@ -0,0 +1,210 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +import datetime +import hashlib +import json +import os +import argparse +import time +import uuid + +from copy import deepcopy +from zipfile import ZipFile + +OUTPUT_DATA = { + "vnf_checksum": "", + "build_tag": str(uuid.uuid4()), + "version": "2019.12", + "test_date": "", + "duration": "", + "vnf_type": "heat", + "testcases_list": [ + { + "mandatory": "true", + "name": "onap-vvp.validate.heat", + "result": "NOT_STARTED", + "objective": "onap heat template validation", + "sub_testcase": [], + "portal_key_file": "report.json", + }, + { + "mandatory": "true", + "name": "onap-vvp.lifecycle_validate.heat", + "result": "NOT_STARTED", + "objective": "onap vnf lifecycle validation", + "sub_testcase": [ + {"name": "model-and-distribute", "result": "NOT_STARTED"}, + {"name": "instantiation", "result": "NOT_STARTED"}, + ], + "portal_key_file": "log.txt", + }, + { + "mandatory": "true", + "name": "stack_validation", + "result": "NOT_STARTED", + "objective": "onap vnf openstack validation", + "sub_testcase": [], + "portal_key_file": "stack-validation.json", + }, + ], +} + + +class OVPListener: + def __init__( + self, + template_directory, + start_time, + test_date + ): + self.report = deepcopy(OUTPUT_DATA) + self.test_date = test_date + self.build_directory = template_directory + self.output_directory = "/tmp" + self.start_time = int(start_time) + + self.initialize() + + def initialize(self): + self.template_directory = self.build_directory + self.report["vnf_checksum"] = sha256(self.template_directory) + self.report["test_date"] = self.test_date + self.report["duration"] = (int(time.time()) - self.start_time) + + def update_validation_scripts(self, status): + self.report["testcases_list"][0]["result"] = status + + def update_model_and_distribute(self, status): + self.report["testcases_list"][1]["sub_testcase"][0]["result"] = status + self.report["testcases_list"][1]["sub_testcase"][1]["result"] = status + self.report["testcases_list"][1]["result"] = status + + def update_stack_validation(self, status): + self.report["testcases_list"][2]["result"] = status + + def close(self): + with open("{}/results.json".format(self.output_directory), "w") as f: + json.dump(self.report, f, indent=4) + + +def sha256(template_directory): + heat_sha = None + zip_file = "{}/tmp.zip".format(template_directory) + onlyfiles = [f for f in os.listdir(template_directory) if os.path.isfile(os.path.join(template_directory, f))] + + with ZipFile(zip_file, 'w') as zipObj: + for filename in onlyfiles: + zipObj.write(os.path.join(template_directory, filename), arcname=filename) + + with open(zip_file, "rb") as f: + bytes = f.read() + heat_sha = hashlib.sha256(bytes).hexdigest() + + if os.path.exists(zip_file): + os.remove(zip_file) + + return heat_sha + +def main( + template_directory, + start_time, + test_date, + validation_scripts="NOT_STARTED", + stack_validation="NOT_STARTED", + model_and_distribute="NOT_STARTED", + ): + t = OVPListener(template_directory, start_time, test_date) + t.update_validation_scripts(validation_scripts) + t.update_model_and_distribute(model_and_distribute) + t.update_stack_validation(stack_validation) + t.close() + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Stack Validation Script") + + parser.add_argument( + "--validation-scripts", + required=False, + choices=["SUCCESS", "FAIL", "NOT_STARTED"], + default="NOT_STARTED", + help="Validation Script Status.", + ) + + parser.add_argument( + "--model-and-distribute", + required=False, + choices=["SUCCESS", "FAIL", "NOT_STARTED"], + default="NOT_STARTED", + help="Modeling Script Status.", + ) + + parser.add_argument( + "--stack-validation", + required=False, + choices=["SUCCESS", "FAIL", "NOT_STARTED"], + default="NOT_STARTED", + help="Stack Validation Script Status.", + ) + + parser.add_argument( + "--test-date", + required=True, + help="Test Date.", + ) + + parser.add_argument( + "--template-directory", + required=True, + help="Heat Template Directory.", + ) + + parser.add_argument( + "--start-time", + required=True, + help="Epoch start time.", + ) + + arguments = parser.parse_args() + + status = main( + arguments.template_directory, + arguments.start_time, + arguments.test_date, + validation_scripts=arguments.validation_scripts, + stack_validation=arguments.stack_validation, + model_and_distribute=arguments.model_and_distribute, + ) diff --git a/ovp_testsuite/ovp-report.sh b/ovp_testsuite/ovp-report.sh new file mode 100755 index 0000000..8282fb6 --- /dev/null +++ b/ovp_testsuite/ovp-report.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +set -x + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +NAMESPACE=$1 +PODNAME=$2 +OUTPUT_DIR=$3 +BUILD_TAG=$4 +START_TIME=$5 +VALIDATION_SCRIPTS=$6 +MODEL_AND_DISTRIBUTE=$7 +STACK_VALIDATION=$8 + +DATE=`date '+%Y-%m-%d %H:%M:%S'` +TEMPLATE_DIRECTORY=/tmp/$BUILD_TAG/templates + +ARG_LIST="--template-directory $TEMPLATE_DIRECTORY --start-time $START_TIME --test-date '$DATE'" + +if [ ! -z "$VALIDATION_SCRIPTS" ]; then + ARG_LIST="$ARG_LIST --validation-scripts $VALIDATION_SCRIPTS" +fi + +if [ ! -z "$MODEL_AND_DISTRIBUTE" ]; then + ARG_LIST="$ARG_LIST --model-and-distribute $MODEL_AND_DISTRIBUTE" +fi + +if [ ! -z "$STACK_VALIDATION" ]; then + ARG_LIST="$ARG_LIST --stack-validation $STACK_VALIDATION" +fi + +kubectl -n $NAMESPACE cp $DIR/ovp-report.py $PODNAME:/tmp/ovp-report.py + +kubectl -n $NAMESPACE exec $PODNAME -- sh -c "python /tmp/ovp-report.py $ARG_LIST" + +kubectl -n $NAMESPACE cp $PODNAME:tmp/results.json "$OUTPUT_DIR/results.json" diff --git a/ovp_testsuite/stack-validation.py b/ovp_testsuite/stack-validation.py new file mode 100644 index 0000000..21e7fef --- /dev/null +++ b/ovp_testsuite/stack-validation.py @@ -0,0 +1,447 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +import argparse +import json +import yaml +import requests +import sys + +from onap_client.client.clients import Client + +stack_url = "{}/stacks/{}" +stack_resources_url = "{}/stacks/{}/resources" + +oc = Client() + +# use this to import and run validation from robot +class HeatVNFValidation: + def __init__(self, manifest, vnf_deployment_details): + with open(manifest, "r") as f: + self.manifest = json.loads(f.read()) + + with open(vnf_deployment_details, "r") as f: + self.vnf_deployment_details = json.loads(f.read()) + + region = self.manifest.get("region_id") + owner = self.manifest.get("cloud_owner") + + esr_info = oc.aai.cloud_infrastructure.get_esr_list( + cloud_region=region, + cloud_owner=owner, + ).response_data.get("esr-system-info")[0] + self.auth_url = esr_info.get("service-url") + self.username = esr_info.get("user-name") + self.password = esr_info.get("password") + self.tenant = esr_info.get("default-tenant") + + def request_auth_token(self): + data = { + "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": self.username, + "domain": {"id": "default"}, + "password": self.password, + } + }, + }, + "scope": {"project": {"name": self.tenant, "domain": {"id": "default"}}}, + } + } + headers = {"Content-Type": "application/json"} + + return requests.request(method="POST", json=data, headers=headers, url="{}/v3/auth/tokens".format(self.auth_url)) + + + + def validate(self, orchestration_url, token, vnf_name): + validator = StackValidation(orchestration_url, token, self.vnf_deployment_details, vnf_name) + validator.create_summary() + validator.validate_summary() + + return validator.report + + +class StackValidation: + def __init__(self, orchestration_url, token, manifest, vnf_name): + """retrieves stack and template details, and creates + a report for submission to OVP portal. + + :orchestration_url heat service endpoint in openstack + :token keystone auth token + :manifest json that contains list of heat templates, env, + preloads, and stack names for each module in + a VNF + """ + self.modules = [] + self.url = orchestration_url + self.token = token + self.manifest = manifest + self.vnf_name = vnf_name + self.report = {} + self.base_outputs = [] + + self.load_manifest() + + def load_manifest(self): + for entry in self.manifest: + template = entry.get("template_name") + env_file = template.replace(".yaml", ".env").replace(".yml", ".env") + preload = entry.get("preload_name") + stack = entry.get("stack_name") + module = HeatModule( + template, + env_file, + stack, + preload + ) + module.get_data(self.url, self.token) + self.modules.append(module) + + def create_summary(self): + """creates a report dictionary to compare stack + resources, parameters, outputs w/ template""" + self.report["modules"] = [] + self.report["VNF Name"] = self.vnf_name + for module in self.modules: + stack = module.stack + preload = module.preload + template = module.template + + module_report = {} + module_report["stack_details"] = stack.stack_details + + module_report["resources"] = {} + module_report["resources"]["summary"] = "" + + module_report["parameters"] = {} + module_report["parameters"]["summary"] = "" + + module_report["outputs"] = {} + module_report["outputs"]["summary"] = "" + + module_report["outputs"]["stack_outputs"] = stack.outputs + module_report["outputs"]["template_outputs"] = template.outputs + if stack.stack_name.lower().find("base") != -1: + self.base_outputs = template.outputs + + module_report["resources"]["stack_resources"] = stack.resources + module_report["resources"]["template_resources"] = template.resources + + module_report["parameters"]["stack_parameters"] = stack.parameters + template.parameters.update(preload.parameters) + module_report["parameters"]["template_parameters"] = template.parameters + + + self.report["modules"].append(module_report) + + def validate_summary(self): + # validates resources, parameters, and outputs + self.validate_resources() + self.validate_parameters() + self.validate_outputs() + + self.report["summary"] = "SUCCESS" + for module in self.report["modules"]: + if module["resources"]["summary"] != "SUCCESS": + self.report["summary"] = "FAILED" + break + if module["parameters"]["summary"] != "SUCCESS": + self.report["summary"] = "FAILED" + break + if module["outputs"]["summary"] != "SUCCESS": + self.report["summary"] = "FAILED" + break + + def validate_resources(self): + """validates that all resources from a heat template + are present in instantiated heat stack""" + report = self.report + for module in report["modules"]: + module["resources"]["summary"] = "SUCCESS" + resources = module.get("resources", {}) + template_resources = resources.get("template_resources", []) + stack_resources = resources.get("stack_resources", []) + + if len(stack_resources) != len(template_resources): + module["resources"]["summary"] = "FAILED" + continue + + stack_rids = [] + for s_resource in stack_resources: + stack_rids.append(s_resource.get("resource_id")) + + template_rids = [] + for t_resource in template_resources: + template_rids.append(t_resource.get("resource_id")) + + if stack_rids.sort() != template_rids.sort(): + module["resources"]["summary"] = "FAILED" + continue + + def validate_parameters(self): + """validates that parameter name/value from template + == values from instantiated heat stack""" + report = self.report + for module in report["modules"]: + module["parameters"]["summary"] = "SUCCESS" + parameters = module.get("parameters", {}) + template_parameters = parameters.get("template_parameters", {}) + stack_parameters = parameters.get("stack_parameters", {}) + + for parameter, parameter_value in template_parameters.items(): + stack_parameter = stack_parameters.get(parameter) + if not stack_parameter: + print("FAILED ON {} not found in {}".format(parameter, module.get("stack_details").get("stack_name"))) + module["parameters"]["summary"] = "FAILED" + + elif stack_parameter != parameter_value and parameter not in self.base_outputs: + print("FAILED ON {} not equal in {}".format(parameter, module.get("stack_details").get("stack_name"))) + module["parameters"]["summary"] = "FAILED" + + def validate_outputs(self): + """validates that all outputs from a heat template + are present in instantiated heat stack""" + report = self.report + for module in report["modules"]: + module["outputs"]["summary"] = "SUCCESS" + outputs = module.get("outputs", {}) + template_outputs = outputs.get("template_outputs", {}) + stack_outputs = outputs.get("stack_outputs", []) + + for output in stack_outputs: + output_key = output.get("output_key") + if output_key not in template_outputs: + module["outputs"]["summary"] = "FAILED" + break + + +class HeatModule: + def __init__(self, heat_template, environment_file, stack_name, preload): + """ + creates module object that has stack, preload, and template objects + + :heat_template /path/to/heat/template.yaml + :environment_file /path/to/heat/env.env + :preload /path/to/preloads/file.json + :stack_name name of heat stack in openstack + """ + self.stack = HeatStack(stack_name) + self.template = HeatTemplate(heat_template, environment_file) + self.preload = HeatPreload(preload) + + def get_data(self, url, token): + self.stack.get_data(url, token) + self.template.get_data() + self.preload.get_data() + + +class HeatTemplate: + def __init__(self, heat_template, environment_file): + """ + creates template object that holds template resources, + parameters, and outputs of a heat template/env pair. + + :heat_template /path/to/heat/template.yaml + :environment_file /path/to/heat/env.env + """ + self.template = heat_template + self.env = environment_file + self.resources = [] + self.parameters = {} + self.outputs = [] + + def get_data(self): + with open(self.template, "r") as f: + ydata = yaml.safe_load(f) + + resources = ydata.get("resources", {}) + + for rid, resource in resources.items(): + self.resources.append( + {"resource_id": rid, "resource_type": resource.get("type", "")} + ) + + outputs = ydata.get("outputs", {}) + + for output, output_value in outputs.items(): + self.outputs.append(output) + + with open(self.env, "r") as f: + ydata = yaml.safe_load(f) + + self.parameters = ydata.get("parameters", {}) + + +class HeatPreload: + def __init__(self, preload): + """ + creates preload object that holds parameter name/values + + :preload /path/to/preloads/file.json + """ + self.preload = preload + self.parameters = {} + + def get_data(self): + with open(self.preload, "r") as f: + jdata = json.loads(f.read()) + + # get parameters regardless of API version + + vnf_api_parameters = ( + jdata.get("input", {}) + .get("vnf-topology-information", {}) + .get("vnf-parameters", []) + ) + + for parameter in vnf_api_parameters: + p_name = parameter.get("vnf-parameter-name") + p_value = parameter.get("vnf-parameter-value") + self.parameters[p_name] = p_value + + gr_api_parameters = ( + jdata.get("input", {}) + .get("preload-vf-module-topology-information", {}) + .get("vf-module-topology", {}) + .get("vf-module-parameters", {}) + .get("param", []) + ) + + for parameter in gr_api_parameters: + p_name = parameter.get("name") + p_value = parameter.get("value") + self.parameters[p_name] = p_value + + +class HeatStack: + def __init__(self, stack_name): + """ + creates stack object that hold stack resources, + parameters, and outputs + + :stack_name name of heat stack in openstack + """ + self.stack_name = stack_name + self.resources = [] + self.parameters = {} + self.outputs = [] + self.status = "" + self.stack_details = {} + + def get_data(self, orchestration_url, token): + url = stack_url.format(orchestration_url, self.stack_name) + r = requests.get(headers={"X-Auth-Token": token}, url=url) + + if r.status_code == 200: + response = r.json() + self.parameters = response.get("stack", {}).get("parameters", {}) + self.outputs = response.get("stack", {}).get("outputs", {}) + self.status = response.get("stack", {}).get("stack_status", "") + self.stack_details = response.get("stack", {}) + + url = stack_resources_url.format(orchestration_url, self.stack_name) + r = requests.get(headers={"X-Auth-Token": token}, url=url) + if r.status_code == 200: + response = r.json() + resources = response.get("resources", []) + for resource in resources: + self.resources.append( + { + "resource_id": resource.get("resource_name"), + "resource_type": resource.get("resource_type"), + "resource_status": resource.get("resource_status"), + } + ) + +def main(vnf_manifest, vnf_name, vnf_deployment_details): + try: + t = HeatVNFValidation(vnf_manifest, vnf_deployment_details) + response = t.request_auth_token() + jdata = json.loads(response.text) + token = response.headers.get("X-Subject-Token") + orchestration_url = None + for catalog_entry in jdata.get("token", {}).get("catalog", []): + if catalog_entry.get("type") == "orchestration": + for endpoint in catalog_entry.get("endpoints", []): + if endpoint.get("interface") == "public": + orchestration_url = endpoint.get("url") + break + + report = t.validate(orchestration_url, token, vnf_name) + print(json.dumps(report, indent=4)) + + with open("/tmp/stack-validation.json", "w") as f: + json.dump(report, f, indent=4) + except Exception as e: + print(e) + return False + + return report.get("summary") == "SUCCESS" + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Stack Validation Script") + + parser.add_argument( + "--vnf-manifest", + required=True, + help="JSON manifest for input VNF.", + ) + + parser.add_argument( + "--vnf-deployment-details", + required=True, + help="JSON manifest for deployed VNF.", + ) + + parser.add_argument( + "--vnf-name", + required=True, + help="Full path to the folder containing preloads, templates, and vnf-details.json.", + ) + + arguments = parser.parse_args() + + status = main(arguments.vnf_manifest, arguments.vnf_name, arguments.vnf_deployment_details) + + if status: + sys.exit(0) + + sys.exit(1) + diff --git a/ovp_testsuite/stack-validation.sh b/ovp_testsuite/stack-validation.sh new file mode 100755 index 0000000..1179578 --- /dev/null +++ b/ovp_testsuite/stack-validation.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +set -x + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +NAMESPACE=$1 +PODNAME=$2 +OUTPUT_DIR=$3 +BUILD_TAG=$4 + +kubectl -n $NAMESPACE cp $DIR/stack-validation.py $PODNAME:/tmp/stack-validation.py + +kubectl -n $NAMESPACE exec $PODNAME -- sh -c "python /tmp/stack-validation.py --vnf-manifest /tmp/$BUILD_TAG/vnf-details.json --vnf-name $BUILD_TAG --vnf-deployment-details /tmp/vnf-deployment-details-$BUILD_TAG.json" +if [ $? -ne 0 ]; then + kubectl -n $NAMESPACE cp $PODNAME:tmp/stack-validation.json "$OUTPUT_DIR/stack-validation.json" + echo "Stack validation failed, exiting..." + exit 1 +fi + +kubectl -n $NAMESPACE cp $PODNAME:tmp/stack-validation.json "$OUTPUT_DIR/stack-validation.json" diff --git a/ovp_testsuite/validation-scripts.py b/ovp_testsuite/validation-scripts.py new file mode 100644 index 0000000..f205cde --- /dev/null +++ b/ovp_testsuite/validation-scripts.py @@ -0,0 +1,184 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +import argparse +import os +import subprocess +import sys + +VVP_BRANCH = "master" +VVP_URL = "https://gerrit.onap.org/r/vvp/validation-scripts" + + +# use this to import and run validation from robot +class HeatValidationScripts: + def __init__(self): + pass + + def validate(self, build_dir, template_directory, output_directory): + """ + :build_dir: directory to install virtualenv + and clone validation scripts + :template_directory: directory with heat templates + :output_directory: directory to store output files + """ + t = VVP(build_dir, template_directory, output_directory) + t.install_requirements() + status = t.run_vvp() + + return status + + +class VVP: + def __init__(self, build_dir, template_directory, output_directory): + self._build_dir = build_dir + self.initialize() + + self.virtualenv = "{}/test_env".format(build_dir) + self.vvp = "{}/validation_scripts".format(build_dir) + self.template_directory = template_directory + self.output_directory = output_directory + + def initialize(self): + self.create_venv(self._build_dir) + self.clone_vvp(self._build_dir) + + def create_venv(self, build_dir): + if not os.path.exists("{}/test_env".format(build_dir)): + try: + subprocess.call( + ["python3.7", "-m", "virtualenv", "--clear", "{}/test_env".format(build_dir)] + ) + except OSError as e: + print("error creating virtual environment for vvp {}".format(e)) + raise + + def clone_vvp(self, build_dir): + if not os.path.exists("{}/validation_scripts".format(build_dir)): + try: + subprocess.call( + [ + "git", + "clone", + "-b", + VVP_BRANCH, + VVP_URL, + "{}/validation_scripts".format(build_dir), + ] + ) + except OSError as e: + print("error cloning vvp validation scripts {}".format(e)) + raise + + def install_requirements(self): + try: + subprocess.call( + [ + "{}/bin/python".format(self.virtualenv), + "-m", + "pip", + "install", + "--upgrade", + "pip", + "wheel", + ] + ) + subprocess.call( + [ + "{}/bin/python".format(self.virtualenv), + "-m", + "pip", + "install", + "wheel", + "-r", + "{}/requirements.txt".format(self.vvp), + ] + ) + except OSError as e: + print("error installing vvp requirements {}".format(e)) + raise + + def run_vvp(self): + try: + ret = subprocess.call( + [ + "{}/bin/python".format(self.virtualenv), + "-m", + "pytest", + "--rootdir={}/ice_validator/".format(self.vvp), + "--template-directory={}".format(self.template_directory), + "--output-directory={}".format(self.output_directory), + "--category=environment_file", + "--category=openstack", + "{}/ice_validator/tests/".format(self.vvp), + ] + ) + except OSError as e: + print("error running vvp validation scripts {}".format(e)) + raise + + if ret != 0: + raise ValueError("Validation Script error detected") + +def main(build_directory, template_directory, output_directory): + t = HeatValidationScripts() + t.validate(build_directory, template_directory, output_directory) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--template-directory", + required=True, + help="Directory that contains heat templates.", + ) + + parser.add_argument( + "--output-directory", + required=True, + help="Directory to store output.", + ) + + parser.add_argument( + "--build-directory", + required=False, + default="/tmp/vvpbuild", + help="Directory to store install venv.", + ) + + arguments = parser.parse_args() + + main(arguments.build_directory, arguments.template_directory, arguments.output_directory) diff --git a/ovp_testsuite/validation-scripts.sh b/ovp_testsuite/validation-scripts.sh new file mode 100755 index 0000000..3213592 --- /dev/null +++ b/ovp_testsuite/validation-scripts.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2020 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +set -x +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +NAMESPACE=$1 +PODNAME=$2 +OUTPUT_DIR=$3 +BUILD_TAG=$4 + +kubectl -n $NAMESPACE cp $DIR/validation-scripts.py $PODNAME:/tmp/validation-scripts.py + +kubectl -n $NAMESPACE exec $PODNAME -- sh -c "python /tmp/validation-scripts.py --template-directory /tmp/$BUILD_TAG/templates --output-directory /tmp/vvp-output --build-directory /tmp/vvp_env" +if [ $? -ne 0 ]; then + echo "Validation Scripts failed, exiting..." + kubectl -n $NAMESPACE cp $PODNAME:tmp/vvp-output/report.json "$OUTPUT_DIR/report.json" + exit 1 +fi + +kubectl -n $NAMESPACE cp $PODNAME:tmp/vvp-output/report.json "$OUTPUT_DIR/report.json"
\ No newline at end of file |