# JUnit xml
utils/ci/junit-xml/*.xml
+
+# charm builds
+examples/charms/builds/
+examples/vnfs/**/charms/
+
+# performance measurement results
+examples/performance_measurements/*.csv
+examples/autogenerated/
+!**/.gitkeep
\ No newline at end of file
echo "flake8 version:"
flake8 --version
echo "Doing flake8 style check ..."
-flake8 --exclude=.eggs,devops --ignore=E501,W605,W504 .
+flake8 --exclude=.eggs,devops,examples/charms --ignore=E501,W605,W504 .
echo "done."
# trigger the tests
echo "Running unit tests ..."
--- /dev/null
+Example from https://osm.etsi.org/gitweb/?p=osm/devops.git;a=tree;f=charms/layers/simple;h=bdf2957b5a5f6342bf24e3a675c21634d6064e3a;hb=HEAD
+
+# Overview
+
+This is an example charm as demonstrated in the OSM [Hackfest](https://osm.etsi.org/wikipub/index.php/OSM_workshops_and_events) series.
+
+This is intended to provide a well-documented example of the proxy charm written by Hackfest participants.
+
+# Prerequisites
+
+There are two ways that you can exercise this charm: install the latest stable release of OSM or use Juju directly.
+
+The workshop materials and tutorials cover using charms as part of OSM. You can follow that approach, but this README will focus on using Juju directly. We highly recommend that vendors and charm developers use this approach for the initial development of the charm.
+
+## Ubuntu 16.04 or higher
+
+We recommend using Ubuntu 16.04 or higher for the development and testing of charms. It is assumed that you have installed Ubuntu either on physical hardware or in a Virtual Machine.
+
+## Install LXD and Juju
+
+We will be installing the required software via snap. Snaps are containerised software packages, preferred because they are easy to create and install, will automatically update to the latest stable version, and contain bundled dependencies.
+
+```
+snap install lxd
+snap install juju
+snap install charm
+```
+
+# Usage
+
+
+## Known Limitations and Issues
+
+This not only helps users but gives people a place to start if they want to help
+you add features to your charm.
+
+# Configuration
+
+The configuration options will be listed on the charm store, however If you're
+making assumptions or opinionated decisions in the charm (like setting a default
+administrator password), you should detail that here so the user knows how to
+change it immediately, etc.
+
+# Contact Information
+
+## Upstream Project Name
+
+ - Upstream website
+ - Upstream bug tracker
+ - Upstream mailing list or contact information
+ - Feel free to add things if it's useful for users
+
+
+[service]: http://example.com
+[icon guidelines]: https://jujucharms.com/docs/stable/authors-charm-icon
--- /dev/null
+touch:
+ description: "Touch a file on the VNF."
+ params:
+ filename:
+ description: "The name of the file to touch."
+ type: string
+ default: ""
+ required:
+ - filename
--- /dev/null
+#!/usr/bin/env python3
+##
+# 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.
+##
+import sys
+sys.path.append('lib')
+
+from charms.reactive import main, set_flag
+from charmhelpers.core.hookenv import action_fail, action_name
+
+"""
+`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_flag('actions.{}'.format(action_name()))
+
+try:
+ main()
+except Exception as e:
+ action_fail(repr(e))
--- /dev/null
+options:
+ string-option:
+ type: string
+ default: "Default Value"
+ description: "A short description of the configuration option"
+ boolean-option:
+ type: boolean
+ default: False
+ description: "A short description of the configuration option"
+ int-option:
+ type: int
+ default: 9001
+ description: "A short description of the configuration option"
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="96"
+ height="96"
+ id="svg6517"
+ version="1.1"
+ inkscape:version="0.48+devel r12274"
+ sodipodi:docname="Juju_charm_icon_template.svg">
+ <defs
+ id="defs6519">
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#Background"
+ id="linearGradient6461"
+ gradientUnits="userSpaceOnUse"
+ x1="0"
+ y1="970.29498"
+ x2="144"
+ y2="970.29498"
+ gradientTransform="matrix(0,-0.66666669,0.6660448,0,-866.25992,731.29077)" />
+ <linearGradient
+ id="Background">
+ <stop
+ id="stop4178"
+ offset="0"
+ style="stop-color:#b8b8b8;stop-opacity:1" />
+ <stop
+ id="stop4180"
+ offset="1"
+ style="stop-color:#c9c9c9;stop-opacity:1" />
+ </linearGradient>
+ <filter
+ style="color-interpolation-filters:sRGB;"
+ inkscape:label="Inner Shadow"
+ id="filter1121">
+ <feFlood
+ flood-opacity="0.59999999999999998"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood1123" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="out"
+ result="composite1"
+ id="feComposite1125" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="1"
+ result="blur"
+ id="feGaussianBlur1127" />
+ <feOffset
+ dx="0"
+ dy="2"
+ result="offset"
+ id="feOffset1129" />
+ <feComposite
+ in="offset"
+ in2="SourceGraphic"
+ operator="atop"
+ result="composite2"
+ id="feComposite1131" />
+ </filter>
+ <filter
+ style="color-interpolation-filters:sRGB;"
+ inkscape:label="Drop Shadow"
+ id="filter950">
+ <feFlood
+ flood-opacity="0.25"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood952" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="in"
+ result="composite1"
+ id="feComposite954" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="1"
+ result="blur"
+ id="feGaussianBlur956" />
+ <feOffset
+ dx="0"
+ dy="1"
+ result="offset"
+ id="feOffset958" />
+ <feComposite
+ in="SourceGraphic"
+ in2="offset"
+ operator="over"
+ result="composite2"
+ id="feComposite960" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath873">
+ <g
+ transform="matrix(0,-0.66666667,0.66604479,0,-258.25992,677.00001)"
+ id="g875"
+ inkscape:label="Layer 1"
+ style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline">
+ <path
+ style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline"
+ d="m 46.702703,898.22775 50.594594,0 C 138.16216,898.22775 144,904.06497 144,944.92583 l 0,50.73846 c 0,40.86071 -5.83784,46.69791 -46.702703,46.69791 l -50.594594,0 C 5.8378378,1042.3622 0,1036.525 0,995.66429 L 0,944.92583 C 0,904.06497 5.8378378,898.22775 46.702703,898.22775 Z"
+ id="path877"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssss" />
+ </g>
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ id="filter891"
+ inkscape:label="Badge Shadow">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.71999962"
+ id="feGaussianBlur893" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4.0745362"
+ inkscape:cx="18.514671"
+ inkscape:cy="49.018169"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1029"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ showborder="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:showpageshadow="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid821" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="16,48"
+ id="guide823" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="64,80"
+ id="guide825" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="80,40"
+ id="guide827" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="64,16"
+ id="guide829" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata6522">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="BACKGROUND"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(268,-635.29076)"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient6461);fill-opacity:1;stroke:none;display:inline;filter:url(#filter1121)"
+ d="m -268,700.15563 0,-33.72973 c 0,-27.24324 3.88785,-31.13513 31.10302,-31.13513 l 33.79408,0 c 27.21507,0 31.1029,3.89189 31.1029,31.13513 l 0,33.72973 c 0,27.24325 -3.88783,31.13514 -31.1029,31.13514 l -33.79408,0 C -264.11215,731.29077 -268,727.39888 -268,700.15563 Z"
+ id="path6455"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssss" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="PLACE YOUR PICTOGRAM HERE"
+ style="display:inline" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="BADGE"
+ style="display:none"
+ sodipodi:insensitive="true">
+ <g
+ style="display:inline"
+ transform="translate(-340.00001,-581)"
+ id="g4394"
+ clip-path="none">
+ <g
+ id="g855">
+ <g
+ inkscape:groupmode="maskhelper"
+ id="g870"
+ clip-path="url(#clipPath873)"
+ style="opacity:0.6;filter:url(#filter891)">
+ <path
+ transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-237.54282)"
+ d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"
+ sodipodi:ry="12"
+ sodipodi:rx="12"
+ sodipodi:cy="552.36218"
+ sodipodi:cx="252"
+ id="path844"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ id="g862">
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path4398"
+ sodipodi:cx="252"
+ sodipodi:cy="552.36218"
+ sodipodi:rx="12"
+ sodipodi:ry="12"
+ d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"
+ transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-238.54282)" />
+ <path
+ transform="matrix(1.25,0,0,1.25,33,-100.45273)"
+ d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"
+ sodipodi:ry="12"
+ sodipodi:rx="12"
+ sodipodi:cy="552.36218"
+ sodipodi:cx="252"
+ id="path4400"
+ style="color:#000000;fill:#dd4814;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="star"
+ style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path4459"
+ sodipodi:sides="5"
+ sodipodi:cx="666.19574"
+ sodipodi:cy="589.50385"
+ sodipodi:r1="7.2431178"
+ sodipodi:r2="4.3458705"
+ sodipodi:arg1="1.0471976"
+ sodipodi:arg2="1.6755161"
+ inkscape:flatsided="false"
+ inkscape:rounded="0.1"
+ inkscape:randomized="0"
+ d="m 669.8173,595.77657 c -0.39132,0.22593 -3.62645,-1.90343 -4.07583,-1.95066 -0.44938,-0.0472 -4.05653,1.36297 -4.39232,1.06062 -0.3358,-0.30235 0.68963,-4.03715 0.59569,-4.47913 -0.0939,-0.44198 -2.5498,-3.43681 -2.36602,-3.8496 0.18379,-0.41279 4.05267,-0.59166 4.44398,-0.81759 0.39132,-0.22593 2.48067,-3.48704 2.93005,-3.4398 0.44938,0.0472 1.81505,3.67147 2.15084,3.97382 0.3358,0.30236 4.08294,1.2817 4.17689,1.72369 0.0939,0.44198 -2.9309,2.86076 -3.11469,3.27355 C 669.9821,591.68426 670.20862,595.55064 669.8173,595.77657 Z"
+ transform="matrix(1.511423,-0.16366377,0.16366377,1.511423,-755.37346,-191.93651)" />
+ </g>
+ </g>
+ </g>
+ </g>
+</svg>
--- /dev/null
+includes: ['layer:basic', 'layer:vnfproxy']
+options:
+ basic:
+ use_venv: false
--- /dev/null
+name: simple
+summary: A simple VNF proxy charm
+maintainer: Adam Israel <adam.israel@canonical.com>
+subordinate: false
+series: ['xenial']
--- /dev/null
+metrics:
+ uptime:
+ type: gauge
+ description: "Uptime of the VNF"
+ command: awk '{print $1}' /proc/uptime
--- /dev/null
+from charmhelpers.core.hookenv import (
+ action_get,
+ action_fail,
+ action_set,
+ status_set,
+)
+from charms.reactive import (
+ clear_flag,
+ set_flag,
+ when,
+ when_not,
+)
+import charms.sshproxy
+
+
+@when('sshproxy.configured')
+@when_not('simple.installed')
+def install_simple_proxy_charm():
+ """Post-install actions.
+
+ This function will run when two conditions are met:
+ 1. The 'sshproxy.configured' state is set
+ 2. The 'simple.installed' state is not set
+
+ This ensures that the workload status is set to active only when the SSH
+ proxy is properly configured.
+ """
+ set_flag('simple.installed')
+ status_set('active', 'Ready!')
+
+
+@when('actions.touch')
+def touch():
+ err = ''
+ try:
+ filename = action_get('filename')
+ cmd = ['touch {}'.format(filename)]
+ result, err = charms.sshproxy._run(cmd)
+ except:
+ action_fail('command failed:' + err)
+ else:
+ action_set({'output': result})
+ finally:
+ clear_flag('actions.touch')
--- /dev/null
+# Copyright (c) 2019 Erik Schilling
+# 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.
+
+# based on https://docs.docker.com/engine/examples/running_ssh_service/
+FROM ubuntu:16.04
+
+RUN apt update && apt install -y net-tools iproute
+RUN apt install -y openssh-server
+RUN mkdir /var/run/sshd
+RUN echo 'root:test' | chpasswd
+RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
+
+# SSH login fix. Otherwise user is kicked off after login
+RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
+
+ENV NOTVISIBLE "in users profile"
+RUN echo "export VISIBLE=now" >> /etc/profile
+
+EXPOSE 22
+
+CMD ["/usr/sbin/sshd", "-D"]
--- /dev/null
+#!/usr/bin/env python2
+# Copyright (c) 2019 Erik Schilling
+# 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.
+
+import csv
+import logging
+import os
+import subprocess
+
+import shutil
+import time
+
+from emuvim.api.osm.pre_configured_osm import PreConfiguredOSM
+from emuvim.api.util.docker_utils import build_dockerfile_dir
+from mininet.log import setLogLevel
+
+logging.basicConfig(level=logging.DEBUG)
+setLogLevel('debug') # set Mininet loglevel
+logging.getLogger('werkzeug').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.base').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.compute').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.keystone').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.nova').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.neutron').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.heat').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.heat.parser').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.glance').setLevel(logging.DEBUG)
+logging.getLogger('api.openstack.helper').setLevel(logging.DEBUG)
+
+prefix = os.path.dirname(os.path.abspath(__file__))
+
+build_dockerfile_dir('../images/sshcontainer/', 'sshcontainer')
+
+layers_folder = os.path.join(prefix, '../charms/layers')
+simple_charm_folder = os.path.join(layers_folder, 'simple')
+charm_target_dir = os.path.join(prefix, '../vnfs/simple_charmed_vnfd/charms/')
+shutil.rmtree(charm_target_dir, ignore_errors=True)
+if not subprocess.call(['/snap/bin/charm', 'build'], cwd=simple_charm_folder, env={
+ 'CHARM_BUILD_DIR': charm_target_dir,
+ 'CHARM_LAYERS_DIR': layers_folder
+}) in [0, 100]: # 100 means tests skipped
+ raise RuntimeError('charm build failed')
+
+
+def get_detailed_configuration_status(osm):
+ status = osm.ns_get(ns_id)['_admin']['deployed']['VCA'][0]['detailed-status']
+ print('current status: %s' % status)
+ return status
+
+
+def wait_for_detailed_configuration_status(osm, status):
+ while get_detailed_configuration_status(osm) != status:
+ time.sleep(1)
+
+
+with open('charmed-%d.csv' % time.time(), 'w') as csvfile:
+ fieldnames = ['ns_create', 'charm_deployment_start', 'waiting_for_machine', 'installing_charm_software',
+ 'ns_action', 'ns_delete']
+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
+ writer.writeheader()
+
+ for n in range(1, 10 + 1):
+ with PreConfiguredOSM() as osm:
+ osm.onboard_vnfd('../vnfs/simple_charmed_vnfd')
+ nsd_id = osm.onboard_nsd('../services/simple_charmed_nsd')
+ ns_create = time.time()
+ ns_id = osm.ns_create('charmed-ns-%d' % n, nsd_id)
+ osm.ns_wait_until_all_in_status('running')
+ ns_created = time.time()
+
+ wait_for_detailed_configuration_status(osm, 'waiting for machine')
+ waiting_for_machine_start = time.time()
+
+ wait_for_detailed_configuration_status(osm, 'installing charm software')
+ installing_charm_start = time.time()
+
+ wait_for_detailed_configuration_status(osm, 'Ready!')
+ ready = time.time()
+
+ instance = osm.api.compute.find_server_by_name_or_id('dc1_charmed-ns-%d-1--1' % n).emulator_compute
+ osm.ns_action(ns_id, 1, 'touch')
+ while instance.cmd('cat /testmanual') != '':
+ time.sleep(0.1)
+ ns_action_done = time.time()
+
+ osm.ns_delete(ns_id)
+ osm.ns_wait_until_all_in_status('terminated')
+ ns_deleted = time.time()
+
+ writer.writerow({
+ 'ns_create': ns_created - ns_create,
+ 'charm_deployment_start': waiting_for_machine_start - ns_created,
+ 'waiting_for_machine': installing_charm_start - waiting_for_machine_start,
+ 'installing_charm_software': ready - installing_charm_start,
+ 'ns_action': ns_action_done - ready,
+ 'ns_delete': ns_deleted - ns_action_done,
+ })
+ csvfile.flush()
--- /dev/null
+# Copyright (c) 2019 Erik Schilling
+# 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.
+
+nsd:nsd-catalog:
+ nsd:
+ - id: charmed
+ name: charmed
+ short-name: charmed
+ constituent-vnfd:
+ - vnfd-id-ref: charmed-vnf
+ member-vnf-index: '1'
+ vld:
+ - id: mgmt
+ type: ELAN
+ mgmt-network: 'true'
+ vim-network-name: default
+ vnfd-connection-point-ref:
+ - vnfd-id-ref: charmed-vnf
+ member-vnf-index-ref: '1'
+ vnfd-connection-point-ref: eth0
--- /dev/null
+# Copyright (c) 2019 Erik Schilling
+# 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.
+
+vnfd:vnfd-catalog:
+ vnfd:
+ - id: charmed-vnf
+ short-name: charmed-vnf
+ name: charmed-vnf
+ vdu:
+ - id: charmed-vnf-vdu
+ vm-flavor:
+ vcpu-count: 1
+ memory-mb: 256
+ storage-gb: 6
+ image: sshcontainer
+ interface:
+ - name: eth0
+ type: EXTERNAL
+ position: 0
+ external-connection-point-ref: eth0
+ mgmt-interface:
+ vdu-id: charmed-vnf-vdu
+ connection-point:
+ - name: eth0
+ type: VPORT
+ vnf-configuration:
+ juju:
+ charm: simple
+ initial-config-primitive:
+ - seq: '1'
+ name: config
+ parameter:
+ - name: ssh-hostname
+ value: <rw_mgmt_ip>
+ - name: ssh-username
+ value: root
+ - name: ssh-password
+ value: test
+ - seq: '2'
+ name: touch
+ parameter:
+ - name: filename
+ value: /test
+ config-primitive:
+ - name: touch
+ parameter:
+ - name: filename
+ data-type: STRING
+ default-value: '/testmanual'