Merge "Minor change so vpci in sample vnfd generated is between single quotes so it still works when the pci only contains numbers"
diff --git a/Makefile b/Makefile
index 6cf2d76..73cd1b9 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
 #
 BUILD_DIR = build
 
-NSDS := gw_corpa_ns ims_allin1_corpa mwc16_gen_ns mwc16_pe_ns VyOS_ns cirros_ns cirros_2vnf_ns ubuntu_xenial_ns ping_pong_ns knt_flownac_ns
+NSDS := gw_corpa_ns ims_allin1_corpa mwc16_gen_ns mwc16_pe_ns VyOS_ns cirros_ns cirros_2vnf_ns ubuntu_xenial_ns ping_pong_ns knt_flownac_ns knt_flownac-us_ns sandvine_pts_ns ref1_ns ref2_ns
 NSD_SRC_DIR := src/nsd
 NSD_BUILD_DIR := $(BUILD_DIR)/nsd
 
@@ -27,7 +27,7 @@
 NSD_PKGS := $(addsuffix .tar.gz, $(NSDS))
 NSD_BUILD_PKGS := $(addprefix $(NSD_BUILD_DIR)_pkgs/, $(NSD_PKGS))
 
-VNFDS := 6wind_vnf gw_corpa_pe1_vnf gw_corpa_pe2_vnf ims_allin1_2p_vnf tidgen_mwc16_vnf VyOS_vnf cirros_vnf ubuntu_xenial_vnf ping_vnf pong_vnf knt_fnc_vnf knt_fne_vnf
+VNFDS := 6wind_vnf gw_corpa_pe1_vnf gw_corpa_pe2_vnf ims_allin1_2p_vnf tidgen_mwc16_vnf VyOS_vnf cirros_vnf ubuntu_xenial_vnf ping_vnf pong_vnf knt_fnc_vnf knt_fne_vnf knt_fnu_vnf knt_fnd_vnf sandvine_pts_vnf ref11_vnf ref21_vnf ref12_vnf ref22_vnf
 VNFD_SRC_DIR := src/vnfd
 VNFD_BUILD_DIR := $(BUILD_DIR)/vnfd
 
@@ -81,5 +81,13 @@
 	# Copy the PE Charm into the PE vnf package directory before packaging
 	cp -rf $(BUILD_DIR)/juju-charms/builds/vyos-proxy $(VNFD_BUILD_DIR)/VyOS_vnf/charms
 
-$(BUILD_DIR)/vnfd_pkgs/%.tar.gz: $(VNFD_BUILD_DIR)/% $(VNFD_BUILD_DIR)/ims_allin1_2p_vnf/charms/clearwater-aio-proxy $(VNFD_BUILD_DIR)/6wind_vnf/charms/vpe-router $(VNFD_BUILD_DIR)/VyOS_vnf/charms/vyos-proxy
+$(VNFD_BUILD_DIR)/ping_vnf/charms/pingpong: $(VNFD_BUILD_DIR)/ping_vnf $(BUILD_DIR)/juju-charms
+	# Copy the pingpong Charm into the ping vnf package directory before packaging
+	cp -rf $(BUILD_DIR)/juju-charms/builds/pingpong $(VNFD_BUILD_DIR)/ping_vnf/charms
+
+$(VNFD_BUILD_DIR)/pong_vnf/charms/pingpong: $(VNFD_BUILD_DIR)/pong_vnf $(BUILD_DIR)/juju-charms
+	# Copy the pingpong Charm into the pong vnf package directory before packaging
+	cp -rf $(BUILD_DIR)/juju-charms/builds/pingpong $(VNFD_BUILD_DIR)/pong_vnf/charms
+
+$(BUILD_DIR)/vnfd_pkgs/%.tar.gz: $(VNFD_BUILD_DIR)/% $(VNFD_BUILD_DIR)/ims_allin1_2p_vnf/charms/clearwater-aio-proxy $(VNFD_BUILD_DIR)/6wind_vnf/charms/vpe-router $(VNFD_BUILD_DIR)/VyOS_vnf/charms/vyos-proxy $(VNFD_BUILD_DIR)/ping_vnf/charms/pingpong $(VNFD_BUILD_DIR)/pong_vnf/charms/pingpong
 	src/generate_descriptor_pkg.sh -d $(BUILD_DIR)/vnfd_pkgs $<
diff --git a/src/nsd/ping_pong_ns/ping_pong_nsd.yaml b/src/nsd/ping_pong_ns/ping_pong_nsd.yaml
index 26908e2..0791576 100644
--- a/src/nsd/ping_pong_ns/ping_pong_nsd.yaml
+++ b/src/nsd/ping_pong_ns/ping_pong_nsd.yaml
@@ -17,13 +17,25 @@
 
 nsd:nsd-catalog:
     nsd:nsd:
-    -   nsd:constituent-vnfd:
+     -  nsd:id: rift_ping_pong_ns
+        nsd:logo: rift_logo.png
+        nsd:name: ping_pong_ns
+        nsd:short-name: ping_pong_ns
+        nsd:vendor: RIFT.io
+        nsd:version: '1.0'
+        nsd:description: RIFT.io sample ping pong network service
+        nsd:constituent-vnfd:
         -   nsd:member-vnf-index: '1'
-            nsd:vnfd-id-ref: 8759e766-8b99-11e6-9664-02b76030c497
+            nsd:vnfd-id-ref: rift_ping_vnf
         -   nsd:member-vnf-index: '2'
-            nsd:vnfd-id-ref: 875b30d0-8b99-11e6-9664-02b76030c497
-        nsd:description: Toy NS
-        nsd:id: 875b9750-8b99-11e6-9664-02b76030c497
+            nsd:vnfd-id-ref: rift_pong_vnf
+        nsd:initial-config-primitive:
+        -   nsd:name: start traffic
+            nsd:parameter:
+            -   nsd:name: port
+                nsd:value: 5555
+            nsd:seq: '1'
+            nsd:user-defined-script: start_traffic.py
         nsd:input-parameter-xpath:
         -   nsd:xpath: /nsd:nsd-catalog/nsd:nsd/nsd:vendor
         nsd:ip-profiles:
@@ -32,55 +44,56 @@
                 nsd:gateway-address: 31.31.31.210
                 nsd:ip-version: ipv4
                 nsd:subnet-address: 31.31.31.0/24
+                nsd:dhcp-params:
+                  nsd:count: 200
+                  nsd:start-address: 31.31.31.2
             nsd:name: InterVNFLink
-        nsd:logo: rift_logo.png
-        nsd:name: ping_pong_nsd
         nsd:placement-groups:
         -   nsd:member-vnfd:
             -   nsd:member-vnf-index-ref: '1'
-                nsd:vnfd-id-ref: 8759e766-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_ping_vnf
             -   nsd:member-vnf-index-ref: '2'
-                nsd:vnfd-id-ref: 875b30d0-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_pong_vnf
             nsd:name: Orcus
             nsd:requirement: Place this VM on the Kuiper belt object Orcus
             nsd:strategy: COLOCATION
         -   nsd:member-vnfd:
             -   nsd:member-vnf-index-ref: '1'
-                nsd:vnfd-id-ref: 8759e766-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_ping_vnf
             -   nsd:member-vnf-index-ref: '2'
-                nsd:vnfd-id-ref: 875b30d0-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_pong_vnf
             nsd:name: Quaoar
             nsd:requirement: Place this VM on the Kuiper belt object Quaoar
             nsd:strategy: COLOCATION
-        nsd:short-name: ping_pong_nsd
-        nsd:vendor: RIFT.io
-        nsd:version: '1.0'
         nsd:vld:
-        -   nsd:description: Toy VL
-            nsd:id: ping_pong_mgmt1
-            nsd:name: ping_pong_mgmt
-            nsd:short-name: ping_pong_mgmt
+        -   nsd:id: mgmt_vl
+            nsd:vim-network-name: mgmt
+            nsd:description: Management VL
+            nsd:name: mgmt_vl
+            nsd:short-name: mgmt_vl
             nsd:type: ELAN
             nsd:vendor: RIFT.io
             nsd:version: '1.0'
+            nsd:mgmt-network: 'true'
             nsd:vnfd-connection-point-ref:
             -   nsd:member-vnf-index-ref: '1'
                 nsd:vnfd-connection-point-ref: ping_vnfd/cp0
-                nsd:vnfd-id-ref: 8759e766-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_ping_vnf
             -   nsd:member-vnf-index-ref: '2'
                 nsd:vnfd-connection-point-ref: pong_vnfd/cp0
-                nsd:vnfd-id-ref: 875b30d0-8b99-11e6-9664-02b76030c497
-        -   nsd:description: Toy VL
-            nsd:id: ping_pong_vld2
-            nsd:name: ping_pong_vld
-            nsd:short-name: ping_pong_vld
+                nsd:vnfd-id-ref: rift_pong_vnf
+        -   nsd:id: ping_pong_vl1
+            nsd:description: Data VL
+            nsd:ip-profile-ref: InterVNFLink
+            nsd:name: data_vl
+            nsd:short-name: data_vl
             nsd:type: ELAN
             nsd:vendor: RIFT.io
             nsd:version: '1.0'
             nsd:vnfd-connection-point-ref:
             -   nsd:member-vnf-index-ref: '1'
                 nsd:vnfd-connection-point-ref: ping_vnfd/cp1
-                nsd:vnfd-id-ref: 8759e766-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_ping_vnf
             -   nsd:member-vnf-index-ref: '2'
                 nsd:vnfd-connection-point-ref: pong_vnfd/cp1
-                nsd:vnfd-id-ref: 875b30d0-8b99-11e6-9664-02b76030c497
+                nsd:vnfd-id-ref: rift_pong_vnf
diff --git a/src/nsd/ping_pong_ns/scripts/start_traffic.py b/src/nsd/ping_pong_ns/scripts/start_traffic.py
new file mode 100755
index 0000000..f98bece
--- /dev/null
+++ b/src/nsd/ping_pong_ns/scripts/start_traffic.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python3
+
+############################################################################
+# Copyright 2016 RIFT.IO Inc                                               #
+#                                                                          #
+# 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.                                           #
+############################################################################
+
+
+import argparse
+import logging
+import os
+import subprocess
+import sys
+import time
+
+import yaml
+
+
+def start_traffic(yaml_cfg, logger):
+    '''Use curl and set admin status to enable on pong and ping vnfs'''
+
+    curl_fmt = 'curl -D /dev/stdout -H "Accept: application/vnd.yang.data' \
+                   '+xml" -H "Content-Type: application/vnd.yang.data+json" ' \
+                   '-X POST -d "{{ {data} }}" http://{mgmt_ip}:' \
+                   '{mgmt_port}/api/v1/{vnf_type}/{url}'
+
+    def setup_service(mgmt_ip, port, vnf_type, service_ip, service_port):
+        data = '\\"ip\\":\\"{}\\", \\"port\\":5555'.format(service_ip)
+        curl_cmd = curl_fmt.format(
+            mgmt_ip=mgmt_ip,
+            mgmt_port=port,
+            vnf_type=vnf_type,
+            data=data,
+            url='server'
+        )
+
+        logger.debug("Executing cmd: %s", curl_cmd)
+        proc = subprocess.run(curl_cmd, shell=True,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE)
+
+        logger.debug("Process: {}".format(proc))
+
+        return proc.returncode
+
+    def enable_service(mgmt_ip, port, vnf_type):
+        curl_cmd = curl_fmt.format(
+            mgmt_ip=mgmt_ip,
+            mgmt_port=port,
+            vnf_type=vnf_type,
+            data='\\"enable\\":true',
+            url='adminstatus/state'
+        )
+
+        logger.debug("Executing cmd: %s", curl_cmd)
+        proc = subprocess.run(curl_cmd, shell=True,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE)
+
+        logger.debug("Process: {}".format(proc))
+
+        return proc.returncode
+
+    # Get port from user parameter
+    service_port = yaml_cfg['parameter']['port']
+
+    service_ip = None
+    # Enable pong service first
+    for index, vnfr in yaml_cfg['vnfr'].items():
+        logger.debug("VNFR {}: {}".format(index, vnfr))
+
+        def get_cp_ip(cp_name):
+            for cp in vnfr['connection_point']:
+                if cp['name'].endswith(cp_name):
+                    return cp['ip_address']
+
+        # Check if it is pong vnf
+        if 'pong_vnf' in vnfr['name']:
+            vnf_type = 'pong'
+            mgmt_ip = vnfr['mgmt_ip_address']
+            port = vnfr['mgmt_port']
+            service_ip = get_cp_ip('cp1')
+
+            max_tries = 60
+            tries = 0
+            while tries < max_tries:
+                rc = setup_service(mgmt_ip, port, vnf_type, service_ip, service_port)
+                tries += 1
+                if rc != 0:
+                    logger.error("Setup service for pong failed ({}): {}".
+                                 format(tries, rc))
+                    if rc != 7:
+                        return rc
+                    else:
+                        time.sleep(1) # Sleep for 1 seconds
+
+            rc = enable_service(mgmt_ip, port, vnf_type)
+            if rc != 0:
+                logger.error("Enable service for pong failed: {}".
+                             format(rc))
+                return rc
+            break
+
+    # Add a delay to provide pong port to come up
+    time.sleep(1)
+
+    # Enable ping service next
+    for index, vnfr in yaml_cfg['vnfr'].items():
+        logger.debug("VNFR {}: {}".format(index, vnfr))
+
+        # Check if it is pong vnf
+        if 'ping_vnf' in vnfr['name']:
+            vnf_type = 'ping'
+            mgmt_ip = vnfr['mgmt_ip_address']
+            port = vnfr['mgmt_port']
+            if service_ip is None:
+                logger.error("Did not find pong ip!!")
+                return 1
+
+            max_tries = 30
+            tries = 0
+            while tries < max_tries:
+                rc = setup_service(mgmt_ip, port, vnf_type, service_ip, service_port)
+                tries += 1
+                if rc != 0:
+                    logger.error("Setup service for ping failed ({}): {}".
+                                 format(tries, rc))
+                    if rc != 7:
+                        return rc
+                    else:
+                        time.sleep(1) # Sleep for 1 seconds
+
+            rc = enable_service(mgmt_ip, port, vnf_type)
+            if rc != 0:
+                logger.error("Enable service for ping failed: {}".
+                             format(rc))
+            break
+
+    return rc
+
+
+def main(argv=sys.argv[1:]):
+    try:
+        parser = argparse.ArgumentParser()
+        parser.add_argument("yaml_cfg_file", type=argparse.FileType('r'))
+        parser.add_argument("-q", "--quiet", dest="verbose", action="store_false")
+        args = parser.parse_args()
+
+        run_dir = os.path.join(os.environ['RIFT_INSTALL'], "var/run/rift")
+        if not os.path.exists(run_dir):
+            os.makedirs(run_dir)
+        log_file = "{}/ping_pong_start_traffic-{}.log".format(run_dir, time.strftime("%Y%m%d%H%M%S"))
+
+        # logging.basicConfig(filename=log_file, level=logging.DEBUG)
+        logger = logging.getLogger('ping-pong-start-traffic')
+        logger.setLevel(logging.DEBUG)
+
+        fh = logging.FileHandler(log_file)
+        fh.setLevel(logging.DEBUG)
+
+        ch = logging.StreamHandler()
+        if args.verbose:
+            ch.setLevel(logging.DEBUG)
+        else:
+            ch.setLevel(logging.INFO)
+
+        # create formatter and add it to the handlers
+        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+        fh.setFormatter(formatter)
+        ch.setFormatter(formatter)
+        logger.addHandler(fh)
+        logger.addHandler(ch)
+
+    except Exception as e:
+        logger.exception("Exception in {}: {}".format(__file__, e))
+        sys.exit(1)
+
+    try:
+        logger.debug("Input file: {}".format(args.yaml_cfg_file.name))
+        yaml_str = args.yaml_cfg_file.read()
+        yaml_cfg = yaml.load(yaml_str)
+        logger.debug("Input YAML: {}".format(yaml_cfg))
+
+        rc = start_traffic(yaml_cfg, logger)
+        logger.info("Return code: {}".format(rc))
+        sys.exit(rc)
+
+    except Exception as e:
+        logger.exception("Exception in {}: {}".format(__file__, e))
+        sys.exit(1)
+
+if __name__ == "__main__":
+    main()
diff --git a/src/nsd/ref1_ns/ref1_nsd.yaml b/src/nsd/ref1_ns/ref1_nsd.yaml
new file mode 100644
index 0000000..465537c
--- /dev/null
+++ b/src/nsd/ref1_ns/ref1_nsd.yaml
@@ -0,0 +1,39 @@
+nsd:nsd-catalog:
+    nsd:
+    -   constituent-vnfd:
+        -   member-vnf-index: '1'
+            start-by-default: 'true'
+            vnfd-id-ref: Ref_Vnf_11
+        -   member-vnf-index: '2'
+            vnfd-id-ref: Ref_Vnf_21
+        description: Reference NS 1
+        id: Ref_NS_1
+        name: Ref_NS_1
+        vendor: ETSI
+        vld:
+        -   description: Mgmt VL
+            id: 54c04
+            name: VL1
+            short-name: VL1
+            type: ELAN
+            vendor: ETSI
+            vnfd-connection-point-ref:
+            -   member-vnf-index-ref: '1'
+                vnfd-id-ref: Ref_Vnf_11
+                vnfd-connection-point-ref: mgmt0
+            -   member-vnf-index-ref: '2'
+                vnfd-id-ref: Ref_Vnf_21
+                vnfd-connection-point-ref: mgmt
+        -   description: Data VL
+            id: 54c03
+            name: VL2
+            short-name: VL2
+            type: ELAN
+            vendor: ETSI
+            vnfd-connection-point-ref:
+            -   member-vnf-index-ref: '1'
+                vnfd-connection-point-ref: west
+                vnfd-id-ref: Ref_Vnf_11
+            -   member-vnf-index-ref: '2'
+                vnfd-connection-point-ref: data
+                vnfd-id-ref: Ref_Vnf_21
diff --git a/src/nsd/ref2_ns/ref2_nsd.yaml b/src/nsd/ref2_ns/ref2_nsd.yaml
new file mode 100644
index 0000000..281fdee
--- /dev/null
+++ b/src/nsd/ref2_ns/ref2_nsd.yaml
@@ -0,0 +1,40 @@
+nsd:nsd-catalog:
+    nsd:
+    -   constituent-vnfd:
+        -   member-vnf-index: '1'
+            vnfd-id-ref: Ref_Vnf_12
+        -   member-vnf-index: '2'
+            vnfd-id-ref: Ref_Vnf_22
+        description: Reference NS2
+        id: Ref_NS_2
+        name: Ref_NS_2
+        vendor: ETSI
+        vld:
+        -   id: '97465'
+            name: VL1
+            vnfd-connection-point-ref:
+            -   member-vnf-index-ref: '1'
+                vnfd-connection-point-ref: mgmt0
+                vnfd-id-ref: Ref_Vnf_12
+            -   member-vnf-index-ref: '2'
+                vnfd-connection-point-ref: mgmt
+                vnfd-id-ref: Ref_Vnf_22
+        -   id: f66e6
+            name: VL2
+            vnfd-connection-point-ref:
+            -   member-vnf-index-ref: '1'
+                vnfd-connection-point-ref: east
+                vnfd-id-ref: Ref_Vnf_12
+            -   member-vnf-index-ref: '2'
+                vnfd-connection-point-ref: east
+                vnfd-id-ref: Ref_Vnf_22
+        -   id: b72e9
+            name: VL3
+            vnfd-connection-point-ref:
+            -   member-vnf-index-ref: '1'
+                vnfd-connection-point-ref: west
+                vnfd-id-ref: Ref_Vnf_12
+            -   member-vnf-index-ref: '2'
+                vnfd-connection-point-ref: west
+                vnfd-id-ref: Ref_Vnf_22
+
diff --git a/src/vnfd/ping_vnf/ping_vnfd.yaml b/src/vnfd/ping_vnf/ping_vnfd.yaml
index 28796b4..44f09ab 100644
--- a/src/vnfd/ping_vnf/ping_vnfd.yaml
+++ b/src/vnfd/ping_vnf/ping_vnfd.yaml
@@ -16,58 +16,42 @@
 #
 
 vnfd:vnfd-catalog:
-    vnfd:   
-    -   connection-point:
+    vnfd:vnfd:
+     -  id: rift_ping_vnf
+        name: ping_vnf
+        short-name: ping_vnf
+        logo: rift_logo.png
+        vendor: RIFT.io
+        version: '1.0'
+        description: This is an example RIFT.ware VNF
+        connection-point:
         -   name: ping_vnfd/cp0
             type: VPORT
         -   name: ping_vnfd/cp1
             type: VPORT
-        description: This is an example RIFT.ware VNF
         http-endpoint:
         -   path: api/v1/ping/stats
             polling_interval_secs: '2'
             port: '18888'
-        id: 8759e766-8b99-11e6-9664-02b76030c497
-        logo: rift_logo.png
         mgmt-interface:
             dashboard-params:
                 path: api/v1/ping/stats
                 port: '18888'
             port: '18888'
             vdu-id: iovdu_0
-        monitoring-param:
-        -   description: no of ping requests
-            group-tag: Group1
-            http-endpoint-ref: api/v1/ping/stats
-            id: '1'
-            json-query-method: NAMEKEY
-            name: ping-request-tx-count
-            units: packets
-            value-type: INT
-            widget-type: COUNTER
-        -   description: no of ping responses
-            group-tag: Group1
-            http-endpoint-ref: api/v1/ping/stats
-            id: '2'
-            json-query-method: NAMEKEY
-            name: ping-response-rx-count
-            units: packets
-            value-type: INT
-            widget-type: COUNTER
-        name: ping_vnfd
         placement-groups:
         -   member-vdus:
             -   member-vdu-ref: iovdu_0
             name: Eris
             requirement: Place this VM on the Kuiper belt object Eris
             strategy: COLOCATION
-        short-name: ping_vnfd
         vdu:
-        -   count: '1'
+        -   cloud-init-file: ping_cloud_init.cfg
+            count: '1'
             external-interface:
             -   name: eth0
                 virtual-interface:
-                    type: OM-MGMT
+                    type: VIRTIO
                 vnfd-connection-point-ref: ping_vnfd/cp0
             -   name: eth1
                 virtual-interface:
@@ -81,30 +65,56 @@
                 memory-mb: '512'
                 storage-gb: '4'
                 vcpu-count: '1'
-        vendor: RIFT.io
-        version: '1.0'
         vnf-configuration:
             config-attributes:
-                config-delay: '0'
-                config-priority: '2'
-            config-template: "\n#!/bin/bash\n\n# Rest API config\nping_mgmt_ip='<rw_mgmt_ip>'\n\
-                ping_mgmt_port=18888\n\n# VNF specific configuration\npong_server_ip='<rw_connection_point_name\
-                \ pong_vnfd/cp0>'\nping_rate=5\nserver_port=5555\n\n# Make rest API\
-                \ calls to configure VNF\ncurl -D /dev/stdout \\\n    -H \"Accept:\
-                \ application/vnd.yang.data+xml\" \\\n    -H \"Content-Type: application/vnd.yang.data+json\"\
-                \ \\\n    -X POST \\\n    -d \"{\\\"ip\\\":\\\"$pong_server_ip\\\"\
-                , \\\"port\\\":$server_port}\" \\\n    http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/server\n\
-                rc=$?\nif [ $rc -ne 0 ]\nthen\n    echo \"Failed to set server info\
-                \ for ping!\"\n    exit $rc\nfi\n\ncurl -D /dev/stdout \\\n    -H\
-                \ \"Accept: application/vnd.yang.data+xml\" \\\n    -H \"Content-Type:\
-                \ application/vnd.yang.data+json\" \\\n    -X POST \\\n    -d \"{\\\
-                \"rate\\\":$ping_rate}\" \\\n    http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/rate\n\
-                rc=$?\nif [ $rc -ne 0 ]\nthen\n    echo \"Failed to set ping rate!\"\
-                \n    exit $rc\nfi\n\n\noutput=$(curl -D /dev/stdout \\\n    -H \"\
-                Accept: application/vnd.yang.data+xml\" \\\n    -H \"Content-Type:\
-                \ application/vnd.yang.data+json\" \\\n    -X POST \\\n    -d \"{\\\
-                \"enable\\\":true}\" \\\n    http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/adminstatus/state)\n\
-                if [[ $output == *\"Internal Server Error\"* ]]\nthen\n    echo $output\n\
-                \    exit 3\nelse\n    echo $output\nfi\n\nexit 0\n"
-            script:
-                script-type: bash
+                config-delay: 10
+            service-primitive:
+            -   name: start
+            -   name: stop
+            -   name: restart
+            -   name: config
+                parameter:
+                -   data-type: STRING
+                    default-value: <rw_mgmt_ip>
+                    name: ssh-hostname
+                -   data-type: STRING
+                    default-value: fedora
+                    name: ssh-username
+                -   data-type: STRING
+                    default-value: fedora
+                    name: ssh-password
+                -   data-type: STRING
+                    name: ssh-private-key
+                -   data-type: STRING
+                    default-value: ping
+                    name: mode
+                    read-only: 'true'
+            -   name: set-server
+                parameter:
+                -   data-type: STRING
+                    name: server-ip
+                -   data-type: INTEGER
+                    name: server-port
+            -   name: set-rate
+                parameter:
+                -   data-type: INTEGER
+                    default-value: '5'
+                    name: rate
+            -   name: start-traffic
+            -   name: stop-traffic
+            initial-config-primitive:
+            -   name: config
+                parameter:
+                -   name: ssh-hostname
+                    value: <rw_mgmt_ip>
+                -   name: ssh-username
+                    value: fedora
+                -   name: ssh-password
+                    value: fedora
+                -   name: mode
+                    value: ping
+                seq: '1'
+            -   name: start
+                seq: '2'
+            juju:
+                charm: pingpong
diff --git a/src/vnfd/pong_vnf/pong_vnfd.yaml b/src/vnfd/pong_vnf/pong_vnfd.yaml
index 9f9a8ff..fb7c53c 100644
--- a/src/vnfd/pong_vnf/pong_vnfd.yaml
+++ b/src/vnfd/pong_vnf/pong_vnfd.yaml
@@ -16,58 +16,42 @@
 #
 
 vnfd:vnfd-catalog:
-    vnfd:   
-    -   connection-point:
+    vnfd:
+     -  id: rift_pong_vnf
+        name: pong_vnf
+        short-name: pong_vnf
+        logo: rift_logo.png
+        vendor: RIFT.io
+        version: '1.0'
+        description: This is an example RIFT.ware VNF
+        connection-point:
         -   name: pong_vnfd/cp0
             type: VPORT
         -   name: pong_vnfd/cp1
             type: VPORT
-        description: This is an example RIFT.ware VNF
         http-endpoint:
         -   path: api/v1/pong/stats
             polling_interval_secs: '2'
             port: '18889'
-        id: 875b30d0-8b99-11e6-9664-02b76030c497
-        logo: rift_logo.png
         mgmt-interface:
             dashboard-params:
                 path: api/v1/pong/stats
                 port: '18889'
             port: '18889'
             vdu-id: iovdu_0
-        monitoring-param:
-        -   description: no of ping requests
-            group-tag: Group1
-            http-endpoint-ref: api/v1/pong/stats
-            id: '1'
-            json-query-method: NAMEKEY
-            name: ping-request-rx-count
-            units: packets
-            value-type: INT
-            widget-type: COUNTER
-        -   description: no of ping responses
-            group-tag: Group1
-            http-endpoint-ref: api/v1/pong/stats
-            id: '2'
-            json-query-method: NAMEKEY
-            name: ping-response-tx-count
-            units: packets
-            value-type: INT
-            widget-type: COUNTER
-        name: pong_vnfd
         placement-groups:
         -   member-vdus:
             -   member-vdu-ref: iovdu_0
             name: Weywot
             requirement: Place this VM on the Kuiper belt object Weywot
             strategy: COLOCATION
-        short-name: pong_vnfd
         vdu:
-        -   count: '1'
+        -   cloud-init-file: pong_cloud_init.cfg
+            count: '1'
             external-interface:
             -   name: eth0
                 virtual-interface:
-                    type: OM-MGMT
+                    type: VIRTIO
                 vnfd-connection-point-ref: pong_vnfd/cp0
             -   name: eth1
                 virtual-interface:
@@ -81,26 +65,51 @@
                 memory-mb: '512'
                 storage-gb: '4'
                 vcpu-count: '1'
-        vendor: RIFT.io
-        version: '1.0'
         vnf-configuration:
             config-attributes:
-                config-delay: '60'
-                config-priority: '1'
-            config-template: "\n#!/bin/bash\n\n# Rest API configuration\npong_mgmt_ip='<rw_mgmt_ip>'\n\
-                pong_mgmt_port=18889\n# username=<rw_username>\n# password=<rw_password>\n\
-                \n# VNF specific configuration\npong_server_ip='<rw_connection_point_name\
-                \ pong_vnfd/cp0>'\nserver_port=5555\n\n# Make Rest API calls to configure\
-                \ VNF\ncurl -D /dev/stdout \\\n    -H \"Accept: application/vnd.yang.data+xml\"\
-                \ \\\n    -H \"Content-Type: application/vnd.yang.data+json\" \\\n\
-                \    -X POST \\\n    -d \"{\\\"ip\\\":\\\"$pong_server_ip\\\", \\\"\
-                port\\\":$server_port}\" \\\n    http://${pong_mgmt_ip}:${pong_mgmt_port}/api/v1/pong/server\n\
-                rc=$?\nif [ $rc -ne 0 ]\nthen\n    echo \"Failed to set server(own)\
-                \ info for pong!\"\n    exit $rc\nfi\n\n\ncurl -D /dev/stdout \\\n\
-                \    -H \"Accept: application/vnd.yang.data+xml\" \\\n    -H \"Content-Type:\
-                \ application/vnd.yang.data+json\" \\\n    -X POST \\\n    -d \"{\\\
-                \"enable\\\":true}\" \\\n    http://${pong_mgmt_ip}:${pong_mgmt_port}/api/v1/pong/adminstatus/state\n\
-                rc=$?\nif [ $rc -ne 0 ]\nthen\n    echo \"Failed to enable pong service!\"\
-                \n    exit $rc\nfi\n\nexit 0\n"
-            script:
-                script-type: bash
+                config-delay: 10
+            service-primitive:
+            -   name: start
+            -   name: stop
+            -   name: restart
+            -   name: config
+                parameter:
+                -   data-type: STRING
+                    default-value: <rw_mgmt_ip>
+                    name: ssh-hostname
+                -   data-type: STRING
+                    default-value: fedora
+                    name: ssh-username
+                -   data-type: STRING
+                    default-value: fedora
+                    name: ssh-password
+                -   data-type: STRING
+                    name: ssh-private-key
+                -   data-type: STRING
+                    default-value: pong
+                    name: mode
+                    read-only: 'true'
+            -   name: set-server
+                parameter:
+                -   data-type: STRING
+                    name: server-ip
+                -   data-type: INTEGER
+                    name: server-port
+            -   name: start-traffic
+            -   name: stop-traffic
+            initial-config-primitive:
+            -   name: config
+                parameter:
+                -   name: ssh-hostname
+                    value: <rw_mgmt_ip>
+                -   name: ssh-username
+                    value: fedora
+                -   name: ssh-password
+                    value: fedora
+                -   name: mode
+                    value: pong
+                seq: '1'
+            -   name: start
+                seq: '2'
+            juju:
+                charm: pingpong
diff --git a/src/vnfd/ref11_vnf/ref11_vnfd.yaml b/src/vnfd/ref11_vnf/ref11_vnfd.yaml
new file mode 100644
index 0000000..f308282
--- /dev/null
+++ b/src/vnfd/ref11_vnf/ref11_vnfd.yaml
@@ -0,0 +1,66 @@
+vnfd:vnfd-catalog:
+    vnfd:
+    -   connection-point:
+        -   name: mgmt0
+            type: VPORT
+        -   name: west
+            type: VPORT
+        description: A simple VNF descriptor w/ VM1 and VM2
+        id: Ref_Vnf_11
+        name: Ref_VNF_11
+        short-name: Ref_VNF_11
+        internal-vld:
+        -   description: Internal VL
+            id: VL12
+            name: VL12
+            short-name: VL12
+            type: ELAN
+            vendor: ETSI
+            internal-connection-point:
+            -   id-ref: 'iface11'
+            -   id-ref: 'iface21'
+        vdu:
+        -   external-interface:
+            -   name: iface10
+                virtual-interface:
+                    type: OM-MGMT
+                vnfd-connection-point-ref: mgmt0
+            internal-interface:
+            -   name: iface11
+                virtual-interface:
+                    type: VIRTIO
+                vdu-internal-connection-point-ref: iface11
+            internal-connection-point:
+            -   name: iface11
+                id: iface11
+                type: VPORT
+            id: Ref_VM1
+            image: ref_vm1.qcow2
+            name: Ref_VM1
+            vm-flavor:
+                memory-mb: '2048'
+                storage-gb: '8'
+                vcpu-count: '2'
+        -   external-interface:
+            -   name: iface22
+                virtual-interface:
+                    type: VIRTIO
+                vnfd-connection-point-ref: west
+            internal-interface:
+            -   name: iface21
+                virtual-interface:
+                    type: VIRTIO
+                vdu-internal-connection-point-ref: iface21
+            internal-connection-point:
+            -   name: iface21
+                id: iface21
+                type: VPORT
+            id: Ref_VM2
+            image: ref_vm2.qcow2
+            name: Ref_VM2
+            vm-flavor:
+                memory-mb: '4096'
+                storage-gb: '16'
+                vcpu-count: '2'
+        vendor: ETSI
+        version: '1.0'
diff --git a/src/vnfd/ref12_vnf/ref12_vnfd.yaml b/src/vnfd/ref12_vnf/ref12_vnfd.yaml
new file mode 100644
index 0000000..2901c4a
--- /dev/null
+++ b/src/vnfd/ref12_vnf/ref12_vnfd.yaml
@@ -0,0 +1,73 @@
+vnfd:vnfd-catalog:
+    vnfd:
+    -   connection-point:
+        -   name: mgmt0
+            type: VPORT
+        -   name: west
+            type: VPORT
+        -   name: east
+            type: VPORT
+        description: A simple VNF descriptor w/ two VDU
+        id: Ref_Vnf_12
+        name: Ref_Vnf_12
+        short-name: Ref_Vnf_12
+        internal-vld:
+        -   description: Internal VL
+            id: VL34
+            name: VL34
+            short-name: VL34
+            type: ELAN
+            vendor: ETSI
+            internal-connection-point:
+            -   id-ref: 'iface31'
+            -   id-ref: 'iface41'
+        vdu:
+        -   description: Middlepoint
+            external-interface:
+            -   name: iface30
+                virtual-interface:
+                    type: OM-MGMT
+                vnfd-connection-point-ref: mgmt0
+            guest-epa:
+                cpu-pinning-policy: DEDICATED
+                mempage-size: "LARGE"
+            id: a3a2f
+            image: ref_vm3.qcow2
+            internal-connection-point:
+            -   id: iface31
+                name: iface31
+                type: VPORT
+            internal-interface:
+            -   name: iface31
+                vdu-internal-connection-point-ref: iface31
+                virtual-interface:
+                    type: VIRTIO
+            name: Ref_VM3
+            vm-flavor:
+                memory-mb: '2048'
+                storage-gb: '8'
+                vcpu-count: '2'
+        -   external-interface:
+            -   name: iface42
+                virtual-interface:
+                    type: PCI-PASSTHROUGH
+                vnfd-connection-point-ref: west
+            -   name: iface43
+                virtual-interface:
+                    type: SR-IOV
+                vnfd-connection-point-ref: east
+            guest-epa:
+                cpu-pinning-policy: DEDICATED
+            id: e526e
+            internal-connection-point:
+            -   id: iface41
+                name: iface41
+                type: VPORT
+            name: Ref_VM4
+            internal-interface:
+            -   name: iface41
+                vdu-internal-connection-point-ref: iface41
+                virtual-interface:
+                    type: VIRTIO
+        vendor: ETSI
+        version: '1.0'
diff --git a/src/vnfd/ref21_vnf/ref21_vnfd.yaml b/src/vnfd/ref21_vnf/ref21_vnfd.yaml
new file mode 100644
index 0000000..390ab9d
--- /dev/null
+++ b/src/vnfd/ref21_vnf/ref21_vnfd.yaml
@@ -0,0 +1,30 @@
+vnfd:vnfd-catalog:
+    vnfd:
+    -   connection-point:
+        -   name: mgmt
+            type: VPORT
+        -   name: data
+            type: VPORT
+        description: A simple VNF descriptor w/ one VDU
+        id: Ref_Vnf_21
+        name: Ref_Vnf_21
+        short-name: Ref_Vnf_21
+        vdu:
+        -   external-interface:
+            -   name: iface50
+                virtual-interface:
+                    type: OM-MGMT
+                vnfd-connection-point-ref: mgmt
+            -   name: iface51
+                virtual-interface:
+                    type: VIRTIO
+                vnfd-connection-point-ref: data
+            id: ref_vm21
+            image: ref_vm21.qcow2
+            name: Ref_VM_5
+            vm-flavor:
+                memory-mb: '1024'
+                storage-gb: '16'
+                vcpu-count: '1'
+        vendor: ETSI
+        version: '1.0'
diff --git a/src/vnfd/ref22_vnf/ref22_vnfd.yaml b/src/vnfd/ref22_vnf/ref22_vnfd.yaml
new file mode 100644
index 0000000..7dddc6f
--- /dev/null
+++ b/src/vnfd/ref22_vnf/ref22_vnfd.yaml
@@ -0,0 +1,39 @@
+vnfd:vnfd-catalog:
+    vnfd:
+    -   connection-point:
+        -   name: mgmt
+            type: VPORT
+        -   name: west
+            type: VPORT
+        -   name: east
+            type: VPORT
+        description: A simple VNF descriptor w/ one VDU
+        id: Ref_Vnf_22
+        name: Ref_VNF_22
+        short-name: Ref_VNF_22
+        vdu:
+        -   external-interface:
+            -   name: iface60
+                virtual-interface:
+                    type: OM-MGMT
+                vnfd-connection-point-ref: mgmt
+            -   name: iface61
+                virtual-interface:
+                    type: PCI-PASSTHROUGH
+                vnfd-connection-point-ref: west
+            -   name: iface62
+                virtual-interface:
+                    type: SR-IOV
+                vnfd-connection-point-ref: east
+            id: abd6831e-f811-4580-9aad-1de9c6424180
+            image: ref_vm22.qcow2
+            name: Ref_VM6
+            guest-epa:
+                cpu-pinning-policy: DEDICATED
+                mempage-size: "LARGE"
+            vm-flavor:
+                memory-mb: '1024'
+                storage-gb: '16'
+                vcpu-count: '1'
+        vendor: ETSI
+        version: '1.0'