Skip to content
Snippets Groups Projects
Commit d433b37c authored by garciadav's avatar garciadav
Browse files

Fix bug 1987

parent 11b10ead
No related branches found
No related tags found
1 merge request!190Fix bug 1987
Pipeline #5488 passed with stage
in 1 minute and 40 seconds
Showing
with 893 additions and 456 deletions
# Overview
This is an example of an Open Source Mano (OSM) charm used with the Network Service (ns) example.
# Usage
## Known Limitations and Issues
Network Service charms are an **experimental** feature, expected to be released with OSM R6 in the spring of 2019.
# Configuration
None
# Contact Information
## Open Source Mano (OSM)
- [OSM website](https://osm.etsi.org/)
- [OSM bug tracker](https://osm.etsi.org/bugzilla/)
- [OSM_TECH](mailto:OSM_TECH@list.etsi.org) mailing list
- [Slack](https://join.slack.com/t/opensourcemano/shared_invite/enQtMzQ3MzYzNTQ0NDIyLWJkMzRjNDM0MjFjODYzMGQ3ODIzMzJlNTg2ZGI5OTdiZjFiNDMyMzYxMjRjNDU4N2FmNjRjNzY5NTE1MjgzOTQ)
<?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>
includes:
- 'layer:basic'
- 'layer:vnfproxy'
- 'layer:sshproxy'
options:
basic:
use_venv: false
name: vnf-policy
summary: <Fill in summary here>
maintainer: Adam Israel <Adam.Israel@maidalchini>
description: |
<Multi-line description here>
tags:
# Replace "misc" with one or more whitelisted tags from this list:
# https://jujucharms.com/docs/stable/authors-charm-metadata
- misc
series:
- xenial
- bionic
subordinate: false
from charmhelpers.core.hookenv import (
action_get,
action_fail,
action_set,
status_set,
log,
)
from charms.reactive import (
clear_flag,
set_flag,
when,
when_not,
)
@when('sshproxy.configured')
@when_not('vnf-policy.installed')
def install_vnf_b():
set_flag('vnf-policy.installed')
status_set('active', 'Ready!')
@when('actions.set-policy')
def action_set_policy():
"""Set the policy for a given user.
Sets the policy (bw and qos) for the specified user_id
"""
err = ''
updated = False
try:
user_id = action_get('user_id')
bw = action_get('bw')
qos = action_get('qos')
# If this were a functional vnf, you would perform your operation here
# and may return a value to indicate success or failure.
updated = True
except Exception as err:
action_fail(str(err))
else:
action_set({'updated': updated})
finally:
clear_flag('actions.set-policy')
#!/bin/bash
sudo add-apt-repository ppa:juju/stable -y
sudo apt-get update
sudo apt-get install amulet python-requests -y
#!/usr/bin/python3
import amulet
import requests
import unittest
class TestCharm(unittest.TestCase):
def setUp(self):
self.d = amulet.Deployment()
self.d.add('vnf-b')
self.d.expose('vnf-b')
self.d.setup(timeout=900)
self.d.sentry.wait()
self.unit = self.d.sentry['vnf-b'][0]
def test_service(self):
# test we can access over http
page = requests.get('http://{}'.format(self.unit.info['public-address']))
self.assertEqual(page.status_code, 200)
# Now you can use self.d.sentry[SERVICE][UNIT] to address each of the units and perform
# more in-depth steps. Each self.d.sentry[SERVICE][UNIT] has the following methods:
# - .info - An array of the information of that unit from Juju
# - .file(PATH) - Get the details of a file on that unit
# - .file_contents(PATH) - Get plain text output of PATH file from that unit
# - .directory(PATH) - Get details of directory
# - .directory_contents(PATH) - List files and folders in PATH on that unit
# - .relation(relation, service:rel) - Get relation data from return service
if __name__ == '__main__':
unittest.main()
# Copyright 2020 David Garcia
# See LICENSE file for licensing details.
__pycache__
*.pyc
.vscode
venv
.charm
build
__pycache__
\ No newline at end of file
/venv
*.py[cod]
*.charm
This diff is collapsed.
# sshproxy
## Description
SSHProxy Charm example for Open Source MANO.
The purpose of this charm is to operate a VNF via SSH. For this, the charm should know the hostname of the VNF (ip address), and the username. The charm will be in a blocked state until it has the hostname, username, and the credentials for SSH-ing to the VNF. Both hostname and username are set via config, with `ssh-hostname` and `ssh-username` respectively.
There are two ways of specifying the credentials: password, keys. (See next section)
## Usage
This charm works for both LXD and K8s. By default, it will work on LXD. To make it work in K8s, just change the following in the `metadata.yaml`
```yaml
series:
# - focal
# - bionic
# - xenial
- kubernetes
deployment:
mode: operator
```
### Prepare the environment:
- LXD:
```bash
sudo snap install juju --classic
juju bootstrap lxd
juju add-model test
```
- K8s:
```bash
sudo snap install juju --classic
sudo snap install microk8s --classic
sudo microk8s.status --wait-ready
sudo microk8s.enable storage dns
juju bootstrap microk8s
juju add-model test
```
### Deploying charm:
```bash
charmcraft build
juju deploy ./sshproxy.charm
```
### Configuring the charm:
First of all, set the username and hostname of the VNF:
```bash
juju config sshproxy ssh-hostname=<hostname> \
ssh-username=<username>
```
#### Mirrors
To workaround this [bug](https://bugs.launchpad.net/juju/+bug/1929399), use the following configurations of the charm to specify the urls of apt and security mirrors.
```bash
juju config sshproxy apt-mirror=<apt-mirror> \
security-apt-mirror=<security-apt-mirror>
```
### Credentials
There are two ways to set up the credentials for the charm to be able to SSH the VNF.
With password:
```bash
juju config sshproxy ssh-password=<password>
```
With public keys:
1. First get the public key from the charm
```bash
$ juju run-action sshproxy/0 get-ssh-public-key --wait
unit-sshproxy-0:
UnitId: sshproxy/0
id: "12"
results:
pubkey: |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC0IgSXMsu/5tY9QjsQfiAqcs6MBMO/7BDJB1ohbJFfvFrPiGg3+5FohKOsgu3SPiZbBhTITmI1YdaiZK7Dye2tHUfQKXhPFVFFVRtyWG6U/QJqEn+6OvAhjladcBlah4cb//r8V2Lvk/PshBJPzgvYSNJOhMhpfAMc7SMMpS8VxGBDIuTE0JFlHcRALJy3YBg70DPea2xrLsxqfA2pTA33KcjK2GyLgfOcZavmkqudEA/WaFb0xCY16TB/hDQBSwZm3l2kJ2aHyAWyWMmLNGL0TT14HUQKR1a8NS/kAnKY/yQf04dKoicmCvl4B3ndIYFT5Pq9b07mVfZvEH5Blle/x48iUF6JHWH2383SXwZfGy3XcX+lRx3u+IIkzS/Pmgt175JVdpu8bktk1c3Ekc0aL9v1gJ8rmZo+C6cilBoaziPfbqIatGPeGxnTDdw0JSfpxUGIQF4H98VOdWf3cHGC1hJZubZt0MGYeK4bk7GfsVPMlGaBWDyTaBQ5d9dHGxJpJX5OMBCDD4MfBYvg9IlgsVr1vDbpB4OFoAmQqFgnUWxRg2w0Iv3HBeMCvvOMM7DBOjwgjgbwa693Oyt/Rxd3GOwvy6vRQkFTgVS6f69SyIMCj9aIl1zxkIcOsfM5aU6vgio1BVWt9Xrj1TA3dTYJ7fkC5LJetqJ1knO67u67ww== root@juju-73fac6-2
status: completed
timing:
completed: 2020-11-18 15:42:03 +0000 UTC
enqueued: 2020-11-18 15:42:00 +0000 UTC
started: 2020-11-18 15:42:03 +0000 UTC
```
2. Inject that key in `~/.ssh/authorized_keys` at the VNF
3. Verify the ssh credentials
```bash
$ juju run-action sshproxy/0 verify-ssh-credentials --wait
unit-sshproxy-0:
UnitId: sshproxy/0
id: "14"
results:
verified: "True"
status: completed
timing:
completed: 2020-11-18 15:39:30 +0000 UTC
enqueued: 2020-11-18 15:39:29 +0000 UTC
started: 2020-11-18 15:39:29 +0000 UTC
```
## Developing
Create and activate a virtualenv with the development requirements:
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements-dev.txt
## Testing
The Python operator framework includes a very nice harness for testing
operator behaviour without full deployment. Just `run_tests`:
./run_tests
#!/usr/bin/env python3
##
# Copyright 2016 Canonical Ltd.
# All rights reserved.
# Copyright 2021 Canonical Ltd.
#
# 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
......@@ -14,20 +11,22 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact: legal@canonical.com
#
# To get in touch with the maintainers, please contact:
# osm-charmers@lists.launchpad.net
##
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))
type: charm
bases:
- build-on:
- name: ubuntu
channel: "20.04"
architectures: ["amd64"]
run-on:
- name: ubuntu
channel: "20.04"
architectures:
- amd64
# Copyright 2022 David Garcia
# See LICENSE file for licensing details.
options:
ssh-hostname:
type: string
default: ""
description: "Mock config"
ssh-username:
type: string
default: ""
description: "Mock config"
ssh-password:
type: string
default: ""
description: "Mock config"
# Copyright 2020 David Garcia
# See LICENSE file for licensing details.
name: vnf-policy
description: |
This is a basic example of charm that emulates a Proxy Charm
creating a policy for a user in a remote VNF. The action
`set-policy` implemented by the charm just returns a True,
doesn't really do anything.
summary: VNF policy operator
series:
- focal
- bionic
- xenial
ops
#!/usr/bin/env python3
# Copyright 2020 David Garcia
# See LICENSE file for licensing details.
from ops.main import main
from ops.charm import CharmBase
from ops.model import ActiveStatus
class VnfPolicyCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
# Charm events
self.framework.observe(self.on.install, self._on_install)
self.framework.observe(self.on.set_policy_action, self._on_set_policy_action)
def _on_install(self, _):
self.unit.status = ActiveStatus()
def _on_set_policy_action(self, event):
"""Set policy action."""
event.set_results({"updated": True})
if __name__ == "__main__":
main(VnfPolicyCharm)
File added
......@@ -17,7 +17,7 @@ vnfd:
execution-environment-list:
- id: vnf-policy-ee
juju:
charm: vnf-policy
charm: vnf-policy_ubuntu-20.04-amd64.charm
proxy: true
initial-config-primitive:
- name: config
......
# Overview
This is an example of an Open Source Mano (OSM) charm used with the Network Service (ns) example.
Network Service charms are an **experimental** feature, expected to be released with OSM R6 in the spring of 2019.
# 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
None
# Contact Information
## Open Source Mano (OSM)
- [OSM website](https://osm.etsi.org/)
- [OSM bug tracker](https://osm.etsi.org/bugzilla/)
- [OSM_TECH](mailto:OSM_TECH@list.etsi.org) mailing list
- [Slack](https://join.slack.com/t/opensourcemano/shared_invite/enQtMzQ3MzYzNTQ0NDIyLWJkMzRjNDM0MjFjODYzMGQ3ODIzMzJlNTg2ZGI5OTdiZjFiNDMyMzYxMjRjNDU4N2FmNjRjNzY5NTE1MjgzOTQ)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment