Tutorial VNF/NSD implementation

VNF/NSD implementation tutorial based on experience of an Open Call participant

VNF/NSD implementation tutorial based on experience of an Open Call participant

This is a tutorial for creation of a Virtual Network Function instance and the use it in an NSD. It is based on experience of an Open Call 1 participant, Netictech, performing an experiment RobotView5G. Its purpose is to provide additional support to future open call participants in order for them to ease the development and deployment of their VNF machines within 5GinFIRE infrastructure.

Terminology

The actors in 5GinFIRE have been classified into the following roles

● Experimenter: This role represents the user that will utilize 5GinFIRE’s services and tools to deploy an experiment.
● VxF/VNF developer: This role is responsible for:
○ developing a VNF machine,
○ creating a VNFD and uploading it to the 5GinFIRE portal,
○ creating a NSD and uploading it to the 5GinFIRE portal.
● Mentor: a member of the 5GinFIRE consortium acting as a representant and a contact person of the consortium, providing technical assistance for the VNF developer.
● Testbed provider: This role represents users that are responsible for testbed administration, configuration, integration, adaptation, support, etc.
● Services administrator: This role represents the user that are responsible for maintenance of the 5GinFIRE services.

VNF machine

VNF (Virtual Network Function) machine is a virtual machine that is intended to be run as a Virtual Network Function.

Obtaining a scratch machine

The first step of the process of preparation of a VNF machine is to obtain a scratch machine. A scratch machine is a machine acting as a VNF too, but performing another function. It is easier to adjust this machine to the purpose of the experiment the OC participant is willing to perform than to build the machine from a clean OS cloud image. For the purpose of our experiment, we used OpenCV Transcoder VNF, prepared and provided by the 5GinFIRE consortium.

Deployment of the scratch machine

The scratch machine is available as a file to be deployed. However, deployment of it requires a cloud infrastructure and some know-how. It is easier to have the machine deployed by the 5GinFIRE consortium. In order to be able to do that, an experiment Mentor is to be contacted and asked for deployment of the OpenCV Transcoder VNF machine in one of the 5GinFIRE’s federated infrastructure centers. A VNF developer is then provided with credentials to the machine and credentials with configuration file enabling access to VPN, from where the machine can be reached.

Development

Having gained access to the machine, a VNF developer is able to deploy their software. In our case this involved heavy redesign of our application, as now it was to run headless, without a GUI. The application needs to be adjusted to running from scripts, where important options are exposed as parameters, for an experimenter to provide values of. Furthermore, a way has to be developed for results generated by the VNF to be provided to the experimenter. In our case, there was a script generated that performed upload of generated files using SFTP. What’s more, optional but highly useful was a status channel, providing up-to-date information about the current status of processing on the VNF. For that, we used echo calls piped to netcat

VNFD

After the VNF machine is ready and necessary script parameters are known, a VxF developer is ready to start creation of a VNF Descriptor (VNFD). The easiest course of action is not to start clean, bo to work on files from an example provided by the
5GinFIRE consortium. In our case, we used OpenCV Transcoder VNF.

Obtaining files to work on

The first step is to clone the GitHub repository containing the OpenCV Transcoder VNF. Execute the following command in the shell:

$ git clone https://github.com/5GinFIRE/opencv_transcoder_vnf.git 5ginfire-transcoder-vnf-original-image 

In order to make the process less prone to errors, it is best to edit the .yaml files using a diff editor. In order to be able to do that, it best first to copy the contents of the cloned directory to another location:

$ cp -R 5ginfire-transcoder-vnf-original-image my-vnf-image 

After the directory is duplicated, let’s delete the obsolete git files from the new directory:

$ rm -r my-vnf-image/.git 

Now we are ready to edit the files.

Editing files

There is a number of diff editors available.. In our case, meld was used. The meaning of fields in the files and further info can be checked in the 5GinFIRE OpenCV Transcoder VNF Tutorial.

Cloud init config

Let’s rename the cloud init config file and edit it:

$ mv my-vnf-image/vnf/cloud_init/transcoder_cloud_init.cfg my-vnf-image/vnf/cloud_init/my_vnf_cloud_init.cfg 
$ meld 5ginfire-transcoder-vnf-original-image/vnf/cloud_init/transcoder_cloud_init.cfg my-vnf-image/vnf/cloud_init/my_vnf_cloud_init.cfg  

in our case, no change of the file content was required. Our file is named qoe_cloud_init.cfg and its content is as follows:

#cloud-config 
password: 5ginfire 
chpasswd: { expire: False } 
ssh_pwauth: True

Main VNFD file

Let’s rename the main VNFD file and edit it:

$ mv my-vnf-image/vnf/opencv_transcoder_vnfd.yaml my-vnf-image/vnf/my_vnfd.yaml 
$ meld 5ginfire-transcoder-vnf-original-image/vnf/opencv_transcoder_vnfd.yaml my-vnf-image/vnf/my_vnfd.yaml 

In our case, the file is called qoe-vnfd.yaml and its content is as follows:

vnfd:vnfd-catalog: 
  vnfd:vnfd: 
   -  id: robotview5g_qoe_vnf 
      name: robotview5g_qoe_vnf 
      short-name: qoe_vnf 
      logo: 5GinFIRE.png 
      vendor: Netictech 
      version: '1.1' 
      description: QoE NR estimation tool VNF created in RobotView5G project within 5GinFIRE 
      connection-point: 
      -   name: qoe_vnfd/cp_charm 
          type: VPORT 
      -   name: qoe_vnfd/cp_net 
          type: VPORT 
      vdu: 
      -   cloud-init-file: qoe_cloud_init.cfg 
          count: '1' 
          external-interface: 
          -   name: eth0 
              virtual-interface: 
                 type: VIRTIO 
              vnfd-connection-point-ref: qoe_vnfd/cp_charm 
          -   name: eth1 
              virtual-interface: 
                 type: VIRTIO 
              vnfd-connection-point-ref: qoe_vnfd/cp_net 
          id: robotview5g_qoe_vdu 
          image: robotview5g_qoe_image 
          name: robotview5g_qoe_vdu 
          vm-flavor: 
              memory-mb: '4096' 
              storage-gb: '20' 
              vcpu-count: '16' 
      vnf-configuration: 
          config-attributes: 
              config-delay: 10 
          service-primitive: 
          -   name: config 
              parameter: 
              -   data-type: STRING 
                 default-value: <rw_mgmt_ip> 
                 name: ssh-hostname 
              -   data-type: STRING 
                 default-value: ubuntu 
                 name: ssh-username 
              -   data-type: STRING 
                 default-value: 5ginfire 
                 name: ssh-password 
              -   data-type: STRING 
                 name: ssh-private-key 
          -   name: start-qoe 
              parameter: 
              -   data-type: STRING 
                 name: rtsp-url 
              -   data-type: INTEGER 
                 name: video-width 
              -   data-type: INTEGER 
                 name: video-height 
              -   data-type: STRING 
                 name: status-report-ip 
              -   data-type: INTEGER 
                 name: status-report-port 
              -   data-type: STRING 
                 name: experiment-name 
              -   data-type: INTEGER 
                 name: extra-initial-delay 
          initial-config-primitive: 
          -   name: config 
              parameter: 
              -   name: ssh-hostname 
                 value: <rw_mgmt_ip> 
              -   name: ssh-username 
                 value: ubuntu 
              -   name: ssh-password 
                 value: 5ginfire 
              seq: '1' 
          juju: 
              charm: 5ginfire-robotview5g-qoe 

JUJU charm

Let’s modify the example in order to create our own charm:

$ mv my-vnf-image/charms/transcoder my-vnf-image/charms/layers/my-charm 

In our case, the directory name was changed to layers/5ginfire-robotview5g-qoe. An extra folder called layers/ will be useful when building the charm. Now we can proceed to edit the files.

The layer file

Let’s modify the layer.yaml file:

$ meld my-vnf-image/charms/layers/my-charm/layer.yaml 5ginfire-transcoder-vnf-original-image/charms/transcoder/layer.yaml 

In our case, the file content is as follows:

"includes": 
- "layer:options" 
- "layer:basic" 
- "layer:sshproxy" 
- "layer:vnfproxy" 
"options": 
  "basic": 
  "use_venv": !!bool "false" 
  "packages": [] 
  "include_system_packages": !!bool "false" 
  "python_packages": [] 
  "sshproxy": {} 
  "vnfproxy": {} 
  "5ginfire-robotview5g-qoe": {} 
"is": "5ginfire-robotview5g-qoe" 

The metadata file

Let’s modify the metadata.yaml file:

$ meld my-vnf-image/charms/layers/my-charm/metadata.yaml 5ginfire-transcoder-vnf-original-image/charms/transcoder/metadata.yaml 

In our case, the file content is as follows:

"name": "5ginfire-robotview5g-qoe" 
"summary": "5GinFIRE RobotView5G QoE NR tool charm" 
"maintainer": "Piotr Pawa\u0142owski 
<piotr.pawalowski@netictech.com>" 
"description": | 
  The 5ginfire-robotview5g-qoe charm initializes the qoe VNF. 
"tags": 
  # Replace "misc" with one or more whitelisted tags from this list: # https://jujucharms.com/docs/stable/authors-charm-metadata 
  - "misc" 
  - "osm" 
  - "vnf" 
  - "streaming" 
  - "monitoring" 
  - "nfv" 
"series": 
D2  RobotView5G / 5GINFIRE 
Page 17 of (26) 
- "xenial" 
- "trusty" 
"subordinate": !!bool "false"

The actions file

Let’s modify the actions.yaml file:

$ meld my-vnf-image/charms/layers/my-charm/actions.yaml 5ginfire-transcoder-vnf-original-image/charms/transcoder/actions.yaml 

In our case, the file content is as follows:

## 
# Copyright 2016 Canonical Ltd. 
# 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. 
## 
 
"run": 
  "description": "Run an arbitrary command" 
  "params": 
  "command": 
   "description": "The command to execute." 
   "type": "string" 
   "default": "" 
  "required": 
  - "command" 
"generate-ssh-key": 
  "description": "Generate a new SSH keypair for this unit. 
This will replace any\ 
  \ existing previously generated keypair." 
"verify-ssh-credentials": 
  "description": "Verify that this unit can authenticate with 
server specified by\ 
  \ ssh-hostname and ssh-username." 
"get-ssh-public-key": 
  "description": "Get the public SSH key for this unit." 
"start": 
  "description": "Start the service on the VNF." 
"stop": 
  "description": "Stop the service on the VNF." 
"restart": 
  "description": "Restart the service on the VNF." 
 
"reboot": 
  "description": "Reboot the VNF virtual machine." 
"upgrade": 
  "description": "Upgrade the software on the VNF." 
"start-qoe": 
  "description": "Start QoE and QoS measurments" 
  "params": 
  "rtsp-url": 
   "description": "RTSP URL to fetch the stream from." 
   "type": "string" 
  "video-width": 
   "description": "Width of video in pixels." 
   "type": "integer" 
  "video-height": 
   "description": "Height of video in pixels." 
   "type": "integer" 
  "status-report-ip": 
   "description": "IP address to report current status to." 
   "type": "string" 
  "status-report-port": 
   "description": "Network port to report current status to." 
   "type": "integer" 
  "experiment-name": 
   "description": "Experiment name, suffixed to results file names." 
   "type": "string" 
  "extra-initial-delay": 
   "description": "Extra initial delay in seconds." 
   "type": "integer" 
  "required": 
  - "rtsp-url" 
  - "video-width" 
  - "video-height" 
  - "status-report-ip" 
  - "status-report-port" 
  - "experiment-name" 
  - "extra-initial-delay" 

Looking at the content of the file above, a single new action, start-qoe, has been introduced, replacing the start-transcoder action from an exemplary charm.

The actions

Under actions/ subdirectory there are several files representing actions to invoke the reactive framework with. In our case, a single action, start-qoe, has been added, replacing the start-transcoder action:

$ mv my-vnf-image/charms/layers/my-charm/actions/start-transcoder my-vnf-image/charms/layers/my-charm/actions/start-qoe 
$ meld 5ginfire-transcoder-vnf-original-image/charms/transcoder/actions/start-transcoder my-vnf-image/charms/layers/my-charm/actions/start-qoe 

In our case, the file is called start-qoe and its content is as follows:

#!/usr/bin/env python3 
import sys 
sys.path.append('lib') 
 
from charms.reactive import main 
from charms.reactive import set_state 
from charmhelpers.core.hookenv import action_fail 

""" 
`set_state` only works here because it's flushed to disk inside 
the `main()` 
loop. remove_state will need to be called inside the action 
method. 
""" 
set_state('actions.start-qoe') 
 
try: 
  main() 
except Exception as e: 
  action_fail(repr(e)) 

Implementation of called actions under reactive/

Under reactive/ subdirectory there are several files with an implementation of actions to be performed. In our case, a single action, 5ginfire_robotview5g_qoe, has been added, replacing the transcoder action:

$ mv my-vnf-image/charms/layers/my-charm/reactive/transcoder.py my-vnf-image/charms/layers/my-charm/reactive/5ginfire_robotview5g_qoe.py 
$ meld 5ginfire-transcoder-vnf-original-image/charms/transcoder/reactive/transcoder.py my-vnf-image/charms/layers/my-charm/reactive/5ginfire_robotview5g_qoe.py 

So in our case, the file is called 5ginfire_robotview5g_qoe.py and its content is as follows:

from charmhelpers.core.hookenv import ( 
  action_fail, 
  action_get, 
  action_set, 
RobotView5G / 5GINFIRE  D2 
Page 22 of (26) 
  config, 
  status_set, 
) 
from charms.reactive import when, set_state, remove_state 
import charms.sshproxy 
 
cfg = config() 
 
@when('config.changed') 
def config_changed(): 
  set_state('5ginfire_robotview5g_qoe.configured') 
  status_set('active', 'ready!') 
 
@when('5ginfire_robotview5g_qoe.configured') 
@when('actions.start-qoe') 
def start_qoe(): 
  rtsp_url = action_get('rtsp-url') 
  video_width = action_get('video-width') 
  video_height = action_get('video-height') 
  status_report_ip = action_get('status-report-ip') 
  status_report_port = action_get('status-report-port') 
  experiment_name = action_get('experiment-name') 
  extra_initial_delay = action_get('extra-initial-delay') 
 
  err = '' 
  try: 
      cmd = "cd /home/ubuntu/qoe-tool/application/scripts" 
      cmd += " && ./run-vnf.sh" 
      cmd += " {0}".format(rtsp_url) 
      cmd += " {0}".format(video_width) 
      cmd += " {0}".format(video_height) 
      cmd += " {0}".format(status_report_ip) 
      cmd += " {0}".format(status_report_port) 
      cmd += " {0}".format(experiment_name) 
      cmd += " {0}".format(extra_initial_delay) 
      result, err = charms.sshproxy._run(cmd) 
  except: 
      action_fail('command failed: ' + err) 
  else: 
      action_set({'output': result, 'errors': err}) 
  finally: 
      remove_state('actions.start-qoe') 

Building the charm

After the files have been edited, the charm is ready to be built. First, let’s install the necessary
software:

sudo add-apt-repository ppa:juju/stable 
sudo apt update 
sudo apt install juju 

Then, set some environmental variables:

cd my-vnf-image/charms/ export JUJU_REPOSITORY=pwdexport LAYER_PATH=$JUJU_REPOSITORY/layers cd $LAYER_PATH

Finally, we are ready to build the charm:

charm build

Building a package

The next step is to build the VNFD package, as described in the 5GinFIRE OpenCV Transcoder VNF Tutorial

Uploading to a portal

After the package has been built, the VNFD is ready to be uploaded to a portal in order for it to be onboarded. The necessary steps are described in the portal manual

NSD

After the VNFD is created, a VxF developer is ready to start creation of a Network Service Descriptor (NSD, or, Experiment Descriptor). Like in the case of VNFD, the easiest course of action is not to start clean, bo to work on files from an example provided by the 5GinFIRE consortium. In our case, we used OpenCV Transcoder VNF.

Editing the file

The meaning of fields in the file and further info can be checked in the 5GinFIRE OpenCV Transcoder NSD Tutorial
Let’s modify the main NSD file:

$ mv my-vnf-image/ns/opencv_transcoder_nsd.yaml my-vnf-image/ns/my-nsd.yaml 
$ meld 5ginfire-transcoder-vnf-original-image/ns/opencv_transcoder_nsd.yaml my-vnf-image/ns/my-nsd.yaml 

In our case, the file is called qoe-nsd.yaml and its content is as follows:

nsd:nsd-catalog: 
  nsd: 
  -   id: "robotview5g_qoe_ns" 
     name: "robotview5g_qoe_ns" 
     short-name: "robotview5g_qoe_ns" 
     description: "NSD for QoS and NR QoE estimation tool created in RobotView5G project within 5GinFIRE" 
     vendor: "Netictech" 
     logo: "RobotView5G-QoE-NSD.png" 
     version: "1.0" 
     constituent-vnfd: 
     -   member-vnf-index: 1 
         vnfd-id-ref: "robotview5g_qoe_vnf" 
         start-by-default: "true" 
     vld: 
     -   id: "robotview5g_qoe_mgmt_vl" 
         name: "robotview5g_qoe_mgmt_vl" 
         short-name: "robotview5g_qoe_mgmt_vl" 
         vendor: "Netictech" 
         description: "Management Network for QoS and NR QoE estimation tool created in RobotView5G" 
         version: "1.0" 
         type: "ELAN" 
         mgmt-network: "true" 
         vnfd-connection-point-ref: 
         - member-vnf-index-ref: 1 
            vnfd-id-ref: "robotview5g_qoe_vnf" 
            vnfd-connection-point-ref: "qoe_vnfd/cp_charm" 
     -   id: "robotview5g_qoe_data_vl" 
         name: "robotview5g_qoe_data_vl" 
         short-name: "robotview5g_qoe_data_vl" 
         vendor: "Netictech" 
         description: "Data Network for QoS and NR QoE estimation tool created in RobotView5G" 
         version: "1.0" 
         type: "ELAN" 
         mgmt-network: "false" 
         vnfd-connection-point-ref: 
         - member-vnf-index-ref: 1 
            vnfd-id-ref: "robotview5g_qoe_vnf" 
            vnfd-connection-point-ref: "qoe_vnfd/cp_net" 

Building a package

The next step is to build the NSD package, as described in the 5GinFIRE OpenCV Transcoder NSD Tutorial

Uploading to a portal

After the package has been built, the NSD (Experiment Descriptor) is ready to be uploaded to a portal in order for it to be onboarded. The necessary steps are described in the portal manual

Deployment

After the VNF is ready, VNFD and NSD/Experiment Descriptor are onboarded, an experimenter is ready to schedule an experiment. The process is described in the portal user guide