treewide: Repository archived.

To signify move of the development to GitHub, tip of the default
branch is removed and README.md is left in place to point to the
new location.

Change-Id: I5a8ba8a740f8d7c455929a6f0eab77358bb13b99
Signed-off-by: Martin Kalcok <martin.kalcok@canonical.com>
This commit is contained in:
Martin Kalcok
2025-11-25 17:36:54 +01:00
parent e12f730112
commit 7f7cd2e8c2
40 changed files with 18 additions and 1390 deletions

View File

@@ -1,3 +0,0 @@
[DEFAULT]
test_path=./unit_tests
top_dir=./

View File

@@ -1,36 +0,0 @@
sudo: true
dist: xenial
language: python
install:
- pip install tox-travis
matrix:
include:
- name: "Python 3.6"
python: 3.6
env: ENV=pep8,py3
- name: "Python 3.7"
python: 3.7
env: ENV=pep8,py3
- name: "Functional test"
env: ENV=func-smoke
script:
- if [ $ENV = 'func-smoke' ]; then
sudo apt update;
sudo apt install -y distro-info;
sudo apt remove -y --purge lxd lxd-client;
sudo snap install lxd;
sudo snap install juju --classic;
sudo sh -c 'echo PATH=/snap/bin:$PATH >> /etc/environment';
sudo lxd waitready;
sudo lxd init --auto;
sudo usermod -a -G lxd travis;
sudo su travis -c 'juju bootstrap --no-gui localhost';
echo "export PATH=$PATH;cd $(pwd)" > $HOME/saved_path;
sudo su - travis -c "source $HOME/saved_path; tox -e build";
sudo su - travis -c "source $HOME/saved_path; tox -c build/builds/ovn-chassis/tox.ini -e $ENV -- --log DEBUG";
else
tox -c tox.ini -e $ENV;
fi
- if [ $ENV = 'func-smoke' ]; then
sudo su travis -c 'juju status -m $(juju models --format yaml|grep "^- name:.*zaza"|cut -f2 -d/)';
fi

View File

@@ -1,9 +1,3 @@
- project:
templates:
- openstack-python3-charm-jobs
- openstack-cover-jobs
check:
jobs:
- charmbuild
vars:
charm_build_name: ovn-chassis

View File

@@ -1 +0,0 @@
src/README.md

6
README.md Normal file
View File

@@ -0,0 +1,6 @@
# Repository archived
Development of the `ovn-chassis` charm has been moved to GitHub under
[canonical/charm-ovn-chassis](https://github.com/canonical/charm-ovn-chassis).
Content of stable branches will remain preserved here as well, but new development
is expected to happen on GitHub.

View File

@@ -1,4 +0,0 @@
libffi-dev [platform:dpkg]
libpq-dev [platform:dpkg]
libxml2-dev [platform:dpkg]
libxslt1-dev [platform:dpkg]

View File

@@ -1,44 +0,0 @@
type: charm
parts:
charm:
source: src/
plugin: reactive
reactive-charm-build-arguments:
- --binary-wheels-from-source
- -v
build-packages:
- git
- python3-dev
- libffi-dev
- libssl-dev
- rustc-1.78
- cargo-1.78
- pkg-config
override-build: |
# Note(mylesjp): Force build to use rustc-1.78
ln -s /usr/bin/rustc-1.78 /usr/bin/rustc
ln -s /usr/bin/cargo-1.78 /usr/bin/cargo
craftctl default
build-snaps:
- charm/latest/edge
build-environment:
- CHARM_INTERFACES_DIR: $CRAFT_PROJECT_DIR/interfaces/
- CHARM_LAYERS_DIR: $CRAFT_PROJECT_DIR/layers/
- MAKEFLAGS: -j$(nproc)
- CARGO_HTTP_MULTIPLEXING: 'false'
base: ubuntu@24.04
platforms:
amd64:
build-on: amd64
build-for: amd64
arm64:
build-on: arm64
build-for: arm64
ppc64el:
build-on: ppc64el
build-for: ppc64el
s390x:
build-on: s390x
build-for: s390x

View File

@@ -1 +0,0 @@
src/metadata.yaml

View File

@@ -1,9 +0,0 @@
- project:
templates:
- charm-unit-jobs-py310
- charm-functional-jobs
vars:
needs_charm_build: true
charm_build_name: ovn-chassis
build_type: charmcraft
charmcraft_channel: 3.x/beta

View File

@@ -1,5 +0,0 @@
# This file is used to trigger rebuilds
# when dependencies of the charm change,
# but nothing in the charm needs to.
# simply change the uuid to something new
03a68f9b-170c-497b-9f22-87a0e90a2d7b

View File

@@ -1,13 +0,0 @@
#!/bin/bash
charm=$(grep "charm_build_name" osci.yaml | awk '{print $2}')
echo "renaming ${charm}_*.charm to ${charm}.charm"
echo -n "pwd: "
pwd
ls -al
echo "Removing bad downloaded charm maybe?"
if [[ -e "${charm}.charm" ]];
then
rm "${charm}.charm"
fi
echo "Renaming charm here."
mv ${charm}_*.charm ${charm}.charm

View File

@@ -1,9 +0,0 @@
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of *requirements.txt files for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
#
git+https://github.com/juju/charm-tools.git
simplejson

View File

@@ -1,126 +0,0 @@
# Overview
The ovn-chassis charm provides the Open Virtual Network (OVN) local controller,
Open vSwitch Database and Switch. It is used in conjunction with the
[ovn-central][ovn-central-charm] charm.
Open vSwitch bridges for integration, external Layer2 and Layer3 connectivity
is managed by the charm.
On successful deployment the unit will be enlisted as a Chassis in the OVN
network.
The ovn-chassis charm is a subordinate charm. Alternatively, the principle
[ovn-dedicated-chassis][ovn-dedicated-chassis-charm] charm can be used,
resulting in a dedicated software gateway.
> **Note**: The OVN charms are supported starting with OpenStack Train.
# Usage
The [OpenStack Base bundle][openstack-base-bundle] gives an example of how you
can deploy OpenStack and OVN with [Vault][vault-charm] to automate certificate
lifecycle management.
OVN makes use of Public Key Infrastructure (PKI) to authenticate and authorize
control plane communication. The charm therefore requires a Certificate
Authority to be present in the model as represented by the `certificates`
relation.
Refer to [Open Virtual Network (OVN)][cdg-ovn] in the [OpenStack Charms
Deployment Guide][cdg] for details, including deployment steps.
## OpenStack support
When related to the [nova-compute][nova-compute-charm] charm the ovn-chassis
charm will enable services that provide [Nova metadata][nova-metadata] to
instances.
## DPDK, SR-IOV and hardware offload support
It is possible to configure chassis to prepare network interface cards (NICs)
for use with DPDK, SR-IOV and hardware offload support.
Please refer to the [OVN Configuration][cdg-ovn-cfg] in the [OpenStack Charms Deployment
Guide][cdg] for details.
## Network spaces
This charm supports the use of Juju network spaces.
By binding the `ovsdb` endpoint you can influence which interface will be used
for communication with the OVN Southbound DB as well as overlay traffic.
juju deploy ovn-chassis --bind "ovsdb=internal-space"
By binding the `data` extra-binding you can influence which interface will be
used for overlay traffic.
juju deploy ovn-chassis --bind "data=overlay-space"
## Port configuration
Chassis port configuration is composed of a mapping between physical network
names to bridge names (`ovn-bridge-mappings`) and individual interface to
bridge names (`bridge-interface-mappings`). There must be a match in both
configuration options before the charm will configure bridge and interfaces on
a unit.
The physical network name can be referenced when the administrator programs the
OVN logical flows, either by talking directly to the Northbound database, or by
interfacing with a Cloud Management System (CMS).
Networks for use with external Layer3 connectivity should have mappings on
chassis located in the vicinity of the datacenter border gateways. Having two
or more chassis with mappings for a Layer3 network will have OVN automatically
configure highly available routers with liveness detection provided by the
Bidirectional Forwarding Detection (BFD) protocol.
Chassis without direct external mapping to a external Layer3 network will
forward traffic through a tunnel to one of the chassis acting as a gateway for
that network.
> **Note**: It is not necessary, nor recommended, to add mapping for external
Layer3 networks to all chassis. Doing so will create a scaling problem at the
physical network layer that needs to be resolved with globally shared Layer2
(does not scale) or tunneling at the top-of-rack switch layer (adds
complexity) and is generally not a recommended configuration.
Networks for use with external Layer2 connectivity should have mappings present
on all chassis with potential to host the consuming payload.
## Deferred service events
Operational or maintenance procedures applied to a cloud often lead to the
restarting of various OpenStack services and/or the calling of certain charm
hooks. Although normal, such events can be undesirable due to the service
interruptions they can cause.
The deferred service events feature provides the operator the choice of
preventing these service restarts and hook calls from occurring, which can then
be resolved at a more opportune time.
See the [Deferred service events][cdg-deferred-service-events] page in the
[OpenStack Charms Deployment Guide][cdg] for an in-depth treatment of this
feature.
# Bugs
Please report bugs on [Launchpad][lp-ovn-chassis].
For general questions please refer to the [OpenStack Charm Guide][cg].
<!-- LINKS -->
[cg]: https://docs.openstack.org/charm-guide/latest/
[cdg]: https://docs.openstack.org/project-deploy-guide/charm-deployment-guide/latest/
[cdg-ovn]: https://docs.openstack.org/project-deploy-guide/charm-deployment-guide/latest/app-ovn.html
[cdg-ovn-cfg]: https://docs.openstack.org/project-deploy-guide/charm-deployment-guide/latest/app-ovn.html#configuration
[nova-compute-charm]: https://jaas.ai/nova-compute
[vault-charm]: https://jaas.ai/vault/
[ovn-central-charm]: https://jaas.ai/ovn-central
[ovn-dedicated-chassis-charm]: https://jaas.ai/ovn-dedicated-chassis
[lp-ovn-chassis]: https://bugs.launchpad.net/charm-ovn-chassis/+filebug
[openstack-base-bundle]: https://github.com/openstack-charmers/openstack-bundles/blob/master/development/openstack-base-focal-ussuri-ovn/bundle.yaml
[nova-metadata]: https://docs.openstack.org/nova/latest/user/metadata.html
[cdg-deferred-service-events]: https://docs.openstack.org/project-deploy-guide/charm-deployment-guide/latest/deferred-events.html

View File

@@ -1,27 +0,0 @@
restart-services:
description: |
Restarts services this charm manages.
params:
deferred-only:
type: boolean
default: false
description: |
Restart all deferred services.
services:
type: string
default: ""
description: |
List of services to restart.
run-hooks:
type: boolean
default: true
description: |
Run any hooks which have been deferred.
run-deferred-hooks:
description: |
Run deferable hooks and restart services.
.
NOTE: Service will be restarted as needed irrespective of enable-auto-restarts
show-deferred-events:
descrpition: |
Show the outstanding restarts

View File

@@ -1 +0,0 @@
restart_services.py

View File

@@ -1,76 +0,0 @@
#!/usr/bin/env python3
# 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 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 datetime
import sys
sys.path.append('actions')
sys.path.append('lib')
from charms.layer import basic
basic.bootstrap_charm_deps()
import charmhelpers.contrib.openstack.deferred_events as deferred_events
import charmhelpers.contrib.openstack.utils as os_utils
import charmhelpers.core.hookenv as hookenv
import charms_openstack.charm
import os_deferred_event_actions
charms_openstack.bus.discover()
def restart_services(args):
"""Restart services.
:param args: Unused
:type args: List[str]
"""
deferred_only = hookenv.action_get("deferred-only")
services = hookenv.action_get("services").split()
os_deferred_event_actions.restart_services(args)
# Clear deferred stops. If the services start time is after the
# requested stop time we can infer the stop has happened. This is
# to work around Bug #2012553
deferred_stops = [
e
for e in deferred_events.get_deferred_events()
if e.action == 'stop']
for event in deferred_stops:
start_time = deferred_events.get_service_start_time(event.service)
deferred_stop_time = datetime.datetime.fromtimestamp(
event.timestamp)
if start_time > deferred_stop_time:
deferred_events.clear_deferred_events([event.service], 'stop')
else:
if deferred_only or event.service in services:
os_utils.restart_services_action([event.service])
deferred_events.clear_deferred_events([event.service], 'stop')
with charms_openstack.charm.provide_charm_instance() as charm_instance:
charm_instance._assess_status()
def main(args):
hookenv._run_atstart()
try:
restart_services(args)
except Exception as e:
hookenv.action_fail(str(e))
hookenv._run_atexit()
if __name__ == "__main__":
sys.exit(main(sys.argv))

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env python3
# 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 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('actions')
import os_deferred_event_actions
if __name__ == "__main__":
sys.exit(os_deferred_event_actions.main(sys.argv))

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env python3
# 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 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('actions')
import os_deferred_event_actions
if __name__ == "__main__":
sys.exit(os_deferred_event_actions.main(sys.argv))

View File

@@ -1,23 +0,0 @@
options:
openstack-metadata-workers:
type: int
default: 2
description: |
When charm is related to OpenStack through the `nova-compute` relation
endpoint, the Neutron OVN Metadata service will be activated on the host.
.
Use this configuration option to control the number of workers the
Neutron OVN Metadata service should run.
.
Each of the workers will establish a connection to the OVN Southbound
database. Events the worker respond to is for example the first time
a hypervisor hosts an instance in a subnet, so the volume should be
relatively low. If you set this number too high you may put an
unnecessary toll on the OVN Southbound database server.
enable-auto-restarts:
type: boolean
default: True
description: |
Allow the charm and packages to restart services automatically when
required.

View File

View File

@@ -1,49 +0,0 @@
#!/usr/bin/env python3
# Copyright (C) 2023 Canonical
#
# 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 json
import os
import sys
from datetime import datetime, timedelta
NAGIOS_PLUGIN_DATA = '/usr/local/lib/nagios/juju_charm_plugin_data'
WARN = 1
SUCCESS = 0
if __name__ == "__main__":
output_path = os.path.join(NAGIOS_PLUGIN_DATA, 'ovn_cert_status.json')
if os.path.exists(output_path):
with open(output_path) as fd:
try:
status = json.loads(fd.read())
ts = datetime.strptime(status['last_updated'],
"%Y-%m-%d %H:%M:%S")
if datetime.now() - ts > timedelta(days=1):
print("ovn cert check status is more than 24 hours old "
"(last_updated={})".format(status['last_updated']))
sys.exit(WARN)
print(status['message'])
sys.exit(status['exit_code'])
except ValueError:
print("invalid check output")
sys.exit(WARN)
else:
print("no info available")
sys.exit(WARN)
sys.exit(SUCCESS)

View File

@@ -1,106 +0,0 @@
#!/usr/bin/env python3
# Copyright (C) 2023 Canonical
#
# 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 os
import json
from datetime import datetime
from cryptography.hazmat.backends import default_backend
from cryptography import x509
NAGIOS_PLUGIN_DATA = '/usr/local/lib/nagios/juju_charm_plugin_data'
UNKNOWN = 3
CRITICAL = 2
WARN = 1
SUCCESS = 0
CERT_EXPIRY_CRITICAL_LIMIT = 30
CERT_EXPIRY_WARN_LIMIT = 60
class SSLCertificate(object):
def __init__(self, path):
self.path = path
@property
def cert(self):
with open(self.path, "rb") as fd:
return fd.read()
@property
def expiry_date(self):
cert = x509.load_pem_x509_certificate(self.cert, default_backend())
return cert.not_valid_after
@property
def days_remaining(self):
return int((self.expiry_date - datetime.now()).days)
def check_ovn_certs():
output_path = os.path.join(NAGIOS_PLUGIN_DATA, 'ovn_cert_status.json')
if not os.path.isdir(NAGIOS_PLUGIN_DATA):
os.makedirs(NAGIOS_PLUGIN_DATA)
exit_code = SUCCESS
for cert in ['/etc/ovn/cert_host', '/etc/ovn/ovn-chassis.crt']:
if not os.path.exists(cert):
message = "cert '{}' does not exist.".format(cert)
exit_code = CRITICAL
break
if not os.access(cert, os.R_OK):
message = "cert '{}' is not readable.".format(cert)
exit_code = CRITICAL
break
try:
remaining_days = SSLCertificate(cert).days_remaining
if remaining_days <= 0:
message = "{}: cert has expired.".format(cert)
exit_code = CRITICAL
break
if remaining_days < CERT_EXPIRY_CRITICAL_LIMIT:
message = ("{}: cert will expire in {} days".
format(cert, remaining_days))
exit_code = CRITICAL
break
if remaining_days < CERT_EXPIRY_WARN_LIMIT:
message = ("{}: cert will expire in {} days".
format(cert, remaining_days))
exit_code = WARN
break
except Exception as exc:
message = "failed to check cert '{}': {}".format(cert, str(exc))
exit_code = UNKNOWN
else:
message = "all certs healthy"
exit_code = SUCCESS
ts = datetime.now()
with open(output_path, 'w') as fd:
fd.write(json.dumps({'message': message,
'exit_code': exit_code,
'last_updated':
ts.strftime("%Y-%m-%d %H:%M:%S")}))
os.chmod(output_path, 644)
if __name__ == "__main__":
check_ovn_certs()

View File

@@ -1,191 +0,0 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="266.66666"
height="266.66666"
viewBox="0 0 70.555554 70.555555"
version="1.1"
id="svg3931"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="icon.svg">
<defs
id="defs3925">
<inkscape:path-effect
is_visible="true"
id="path-effect3028"
effect="spiro" />
<inkscape:path-effect
is_visible="true"
id="path-effect4724"
effect="spiro" />
<inkscape:path-effect
is_visible="true"
id="path-effect4720"
effect="spiro" />
<marker
style="overflow:visible"
id="Arrow1Lend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
inkscape:connector-curvature="0"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
id="path3917" />
</marker>
<inkscape:path-effect
is_visible="true"
id="path-effect3908"
effect="spiro" />
<inkscape:path-effect
is_visible="true"
id="path-effect4724-8"
effect="spiro" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="887.07689"
inkscape:cy="18.723436"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="3770"
inkscape:window-height="2096"
inkscape:window-x="70"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata3928">
<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="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-226.44443)">
<g
id="g4132"
transform="matrix(0.13712291,0,0,0.13712291,6.9978915,233.42295)">
<g
transform="translate(-116.86196,-400.24359)"
style="display:inline"
id="layer1-6"
inkscape:label="Base">
<rect
ry="19.369202"
rx="19.369202"
y="410.75735"
x="129.53154"
height="382.54175"
width="382.54175"
id="rect2987"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<rect
ry="17.49905"
rx="23.46236"
y="492.37717"
x="173.8145"
height="219.83182"
width="294.74588"
id="rect2989"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<flowRoot
transform="translate(488.47522,401.2293)"
style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none"
id="flowRoot3004"
xml:space="preserve"><flowRegion
id="flowRegion3006"><rect
style="fill:#ffffff"
y="314.19586"
x="-229.67079"
height="123.70679"
width="149.3353"
id="rect3008" /></flowRegion><flowPara
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:60px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:Sans;text-align:start;writing-mode:lr-tb;text-anchor:start"
id="flowPara3010">OVN</flowPara></flowRoot> </g>
<g
transform="translate(-116.86196,-400.24359)"
style="display:inline"
inkscape:label="Knobs &amp; Text"
id="layer2">
<circle
transform="translate(-11.541922,-28.674478)"
id="path3808"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
cx="190.08102"
cy="482.84048"
r="19.116308" />
<circle
transform="translate(44.364264,-28.674478)"
id="path3808-7"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
cx="190.08102"
cy="482.84048"
r="19.116308" />
<circle
transform="translate(130.72139,-28.674478)"
id="path3808-7-3"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
cx="190.08102"
cy="482.84048"
r="19.116308" />
<circle
transform="translate(220.55891,-28.674478)"
id="path3808-4"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
cx="190.08102"
cy="482.84048"
r="19.116308" />
<circle
transform="translate(276.46511,-28.674478)"
id="path3808-7-36"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
cx="190.08102"
cy="482.84048"
r="19.116308" />
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
inkscape:original-d="m 275.17737,567.87881 86.37835,0.73292 v -22.7212 l 41.01417,33.71537 -41.01417,32.98241 v -20.5224 h -86.99979 z"
inkscape:path-effect="#path-effect4724"
id="path4722"
d="m 275.17737,567.87881 86.37835,0.73292 v -22.7212 l 41.01417,33.71537 -41.01417,32.98241 v -20.5224 h -86.99979 z"
style="display:inline;fill:#008000;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
inkscape:original-d="m 361.10949,622.65312 -86.37833,0.73294 v -22.72122 l -41.01417,33.71537 41.01417,32.98243 v -20.52241 h 86.99976 z"
inkscape:path-effect="#path-effect4724-8"
id="path4722-1"
d="m 361.10949,622.65312 -86.37833,0.73294 v -22.72122 l -41.01417,33.71537 41.01417,32.98243 v -20.52241 h 86.99976 z"
style="display:inline;fill:#008000;fill-opacity:1;stroke:none" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -1,21 +0,0 @@
includes:
- layer:ovn
- interface:nrpe-external-master
- interface:ovsdb
- interface:ovsdb-subordinate
- interface:neutron-plugin
- interface:juju-info
options:
basic:
use_venv: True
include_system_packages: False
repo: https://opendev.org/x/charm-ovn-chassis
config:
deletes:
- source
- ssl_ca
- ssl_cert
- ssl_key
- use-internal-endpoints
- use-syslog
- verbose

View File

@@ -1,13 +0,0 @@
# Copyright 2019 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 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.

View File

@@ -1,13 +0,0 @@
# Copyright 2019 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 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.

View File

@@ -1,13 +0,0 @@
# Copyright 2019 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 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.

View File

@@ -1,80 +0,0 @@
# Copyright 2019 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 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 os
from charmhelpers.core.host import rsync, write_file
from charmhelpers.contrib.charmsupport import nrpe
import charmhelpers.fetch as ch_fetch
import charms_openstack.charm as charm
import charms.ovn_charm
NAGIOS_PLUGINS = '/usr/local/lib/nagios/plugins'
SCRIPTS_DIR = '/usr/local/bin'
CERTCHECK_CRONFILE = '/etc/cron.d/ovn-chassis-cert-checks'
CRONJOB_CMD = "{schedule} root {command} 2>&1 | logger -p local0.notice\n"
charm.use_defaults('charm.default-select-release')
class OVNChassisCharm(charms.ovn_charm.DeferredEventMixin,
charms.ovn_charm.BaseOVNChassisCharm):
# OpenvSwitch and OVN is distributed as part of the Ubuntu Cloud Archive
# Pockets get their name from OpenStack releases.
#
# This defines the earliest version this charm can support, actually
# installed version is selected by the principle charm.
release = 'ussuri'
name = 'ovn-chassis'
# packages needed by nrpe checks
nrpe_packages = ['python3-cryptography']
# Setting an empty source_config_key activates special handling of release
# selection suitable for subordinate charms
source_config_key = ''
@property
def packages(self):
return super().packages + self.nrpe_packages
def render_nrpe(self):
hostname = nrpe.get_nagios_hostname()
self.add_nrpe_certs_check(nrpe.NRPE(hostname=hostname))
super().render_nrpe()
def add_nrpe_certs_check(self, charm_nrpe):
script = 'nrpe_check_ovn_certs.py'
src = os.path.join(os.getenv('CHARM_DIR'), 'files', 'nagios', script)
dst = os.path.join(NAGIOS_PLUGINS, script)
rsync(src, dst)
charm_nrpe.add_check(
shortname='check_ovn_certs',
description='Check that ovn certs are valid.',
check_cmd=script
)
# Need to install this as a system package since it is needed by the
# cron script that runs outside of the charm.
ch_fetch.apt_install(['python3-cryptography'])
script = 'check_ovn_certs.py'
src = os.path.join(os.getenv('CHARM_DIR'), 'files', 'scripts', script)
dst = os.path.join(SCRIPTS_DIR, script)
rsync(src, dst)
cronjob = CRONJOB_CMD.format(
schedule='*/15 * * * *',
command=dst)
write_file(CERTCHECK_CRONFILE, cronjob)

View File

@@ -1,2 +0,0 @@
config:
linux.kernel_modules: openvswitch

View File

@@ -1,31 +0,0 @@
name: ovn-chassis
summary: Open Virtual Network for Open vSwitch - Chassis
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
description: |
Subordinate charm that deploys the OVN local controller and Open vSwitch
Database and Switch.
docs: https://discourse.charmhub.io/t/ovn-chassis-docs-index/11011
tags:
- networking
series:
- jammy
- mantic
subordinate: true
extra-bindings:
data:
provides:
nova-compute:
interface: neutron-plugin
scope: container
ovsdb-subordinate:
interface: ovsdb-subordinate
scope: container
nrpe-external-master:
interface: nrpe-external-master
scope: container
requires:
juju-info:
interface: juju-info
scope: container
ovsdb:
interface: ovsdb

View File

@@ -1,41 +0,0 @@
# Copyright 2019 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 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 charms.reactive as reactive
import charms_openstack.charm as charm
from . import ovn_chassis_charm_handlers
@reactive.when_not(ovn_chassis_charm_handlers.OVN_CHASSIS_ENABLE_HANDLERS_FLAG)
def enable_ovn_chassis_handlers():
reactive.set_flag(
ovn_chassis_charm_handlers.OVN_CHASSIS_ENABLE_HANDLERS_FLAG)
@reactive.when_not('is-update-status-hook')
def configure_deferred_restarts():
with charm.provide_charm_instance() as instance:
instance.configure_deferred_restarts()
@reactive.when_none('charm.paused', 'is-update-status-hook')
@reactive.when('config.rendered')
@reactive.when_any('config.changed.nagios_context',
'config.changed.nagios_servicegroups',
'endpoint.nrpe-external-master.changed',
'nrpe-external-master.available')
def configure_nrpe():
"""Handle config-changed for NRPE options."""
with charm.provide_charm_instance() as charm_instance:
charm_instance.render_nrpe()

View File

@@ -1,9 +0,0 @@
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of *requirements.txt files for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
#
# Functional Test Requirements (let Zaza's dependencies solve all dependencies here!)
git+https://github.com/openstack-charmers/zaza.git#egg=zaza
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack

View File

@@ -1,52 +0,0 @@
variables:
openstack-origin: &openstack-origin caracal
local_overlay_enabled: False
series: noble
applications:
vault:
charm: ch:vault
num_units: 1
series: noble
channel: latest/edge
ovn-central:
charm: ch:ovn-central
num_units: 3
options:
source: *openstack-origin
channel: latest/edge
magpie:
# By default, when instance NUMA placement is not specified,
# a topology of N sockets, each with one core and one thread,
# is used for an instance, where N corresponds to the number of
# instance vCPUs requested.
#
# Let's use a 8 VCPU 2 socket flavor for low level tests
constraints: "instance-type=twosocketm1.xlarge"
charm: ch:magpie
num_units: 2
options:
source: *openstack-origin
channel: latest/edge
ovn-chassis:
charm: ../../../ovn-chassis_amd64.charm
relations:
- - 'ovn-central:certificates'
- 'vault:certificates'
- - 'magpie:juju-info'
- 'ovn-chassis:juju-info'
- - 'ovn-chassis:ovsdb'
- 'ovn-central:ovsdb'
- - 'ovn-chassis:certificates'
- 'vault:certificates'

View File

@@ -1,41 +0,0 @@
charm_name: ovn-chassis
gate_bundles:
- noble-caracal
smoke_bundles:
- noble-caracal
dev_bundles:
- noble-caracal
target_deploy_status:
magpie:
workload-status-message: icmp ok
ovn-central:
workload-status: waiting
workload-status-message-prefix: "'ovsdb-peer' incomplete, 'certificates' awaiting server certificate data"
ovn-chassis:
workload-status: waiting
workload-status-message-prefix: "'certificates' awaiting server certificate data"
vault:
workload-status: blocked
workload-status-message-prefix: Vault needs to be initialized
# Note that full end to end tests are performed with OVN in the
# neutron-api-plugin-ovn and octavia charm gates
configure:
- zaza.openstack.charm_tests.vault.setup.auto_initialize_no_validation
- zaza.openstack.charm_tests.neutron.setup.undercloud_and_charm_setup
configure_options:
# magpie is obviously not a hypervisor, but for the purpose of this charm
# gate it is the principal charm for ovn-chassis and as such is the target
# unit for preparing hugepages and VFIO configuration.
hypervisor_application: 'magpie'
tests:
- zaza.openstack.charm_tests.ovn.tests.OVNChassisDeferredRestartTest
- zaza.openstack.charm_tests.ovn.tests.ChassisCharmOperationTest
- zaza.openstack.charm_tests.ovn.tests.DPDKTest

View File

@@ -1,55 +0,0 @@
# Source charm (with zaza): ./src/tox.ini
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of tox.ini for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
[tox]
envlist = pep8
# NOTE: Avoid build/test env pollution by not enabling sitepackages.
sitepackages = False
# NOTE: Avoid false positives by not skipping missing interpreters.
skip_missing_interpreters = False
[testenv]
# We use tox mainly for virtual environment management for test requirements
# and do not install the charm code as a Python package into that environment.
# Ref: https://tox.wiki/en/latest/config.html#skip_install
skip_install = True
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
allowlist_externals = juju
passenv =
HOME
TERM
CS_*
OS_*
TEST_*
deps = -r{toxinidir}/test-requirements.txt
[testenv:pep8]
basepython = python3
commands = charm-proof
[testenv:func-noop]
basepython = python3
commands =
functest-run-suite --help
[testenv:func]
basepython = python3
commands =
functest-run-suite --keep-model
[testenv:func-smoke]
basepython = python3
commands =
functest-run-suite --keep-model --smoke
[testenv:func-target]
basepython = python3
commands =
functest-run-suite --keep-model --bundle {posargs}
[testenv:venv]
commands = {posargs}

View File

@@ -1,6 +0,0 @@
git+https://github.com/wolsen/charms.reactive.git@fix-entry-points#egg=charms.reactive
git+https://github.com/openstack/charms.openstack.git#egg=charms.openstack
git+https://github.com/juju/charm-helpers.git#egg=charmhelpers

View File

@@ -1,23 +0,0 @@
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of *requirements.txt files for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
#
pyparsing<3.0.0 # aodhclient is pinned in zaza and needs pyparsing < 3.0.0, but cffi also needs it, so pin here.
stestr>=2.2.0
# Dependency of stestr. Workaround for
# https://github.com/mtreinish/stestr/issues/145
cliff<3.0.0
requests>=2.18.4
charms.reactive
mock>=1.2
nose>=1.3.7
coverage>=3.6
git+https://github.com/openstack/charms.openstack.git#egg=charms.openstack
netifaces

96
tox.ini
View File

@@ -1,107 +1,35 @@
# Source charm: ./tox.ini
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of tox.ini for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
# Placeholder tox.ini to satisfy CI on final push that
# archives the repository.
[tox]
envlist = pep8,py3
envlist = pep8,pylint,py3
# NOTE: Avoid build/test env pollution by not enabling sitepackages.
sitepackages = False
# NOTE: Avoid false positives by not skipping missing interpreters.
skip_missing_interpreters = False
[testenv]
# We use tox mainly for virtual environment management for test requirements
# and do not install the charm code as a Python package into that environment.
# Ref: https://tox.wiki/en/latest/config.html#skip_install
skip_install = True
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
TERM=linux
CHARM_LAYERS_DIR={toxinidir}/layers
CHARM_INTERFACES_DIR={toxinidir}/interfaces
JUJU_REPOSITORY={toxinidir}/build
passenv =
no_proxy
http_proxy
https_proxy
CHARM_INTERFACES_DIR
CHARM_LAYERS_DIR
JUJU_REPOSITORY
allowlist_externals =
charmcraft
bash
tox
deps =
-r{toxinidir}/requirements.txt
[testenv:build]
basepython = python3
commands =
charmcraft clean
charmcraft -v pack
[testenv:add-build-lock-file]
basepython = python3
commands =
charm-build --log-level DEBUG --write-lock-file -o {toxinidir}/build/builds src {posargs}
allowlist_externals=true
[testenv:py3]
basepython = python3
deps = -r{toxinidir}/test-requirements.txt
commands = stestr run --slowest {posargs}
commands = true
[testenv:py310]
basepython = python3.10
deps = -r{toxinidir}/test-requirements.txt
commands = stestr run --slowest {posargs}
[testenv:py312]
basepython = python3.12
deps = -r{toxinidir}/test-requirements.txt
commands = stestr run --slowest {posargs}
commands = true
[testenv:pep8]
basepython = python3
deps = flake8==7.1.1
git+https://github.com/juju/charm-tools.git
commands = flake8 {posargs} src unit_tests \
{toxinidir}/src/files/nagios/nrpe_check_ovn_certs.py \
{toxinidir}/src/files/scripts/check_ovn_certs.py
commands = true
[testenv:pylint]
basepython = python3
commands = true
[testenv:cover]
# Technique based heavily upon
# https://github.com/openstack/nova/blob/master/tox.ini
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
setenv =
{[testenv]setenv}
PYTHON=coverage run
commands =
coverage erase
stestr run --slowest {posargs}
coverage combine
coverage html -d cover
coverage xml -o cover/coverage.xml
coverage report
[coverage:run]
branch = True
concurrency = multiprocessing
parallel = True
source =
.
omit =
.tox/*
*/charmhelpers/*
unit_tests/*
commands = true
[testenv:venv]
basepython = python3
commands = {posargs}
[flake8]
# E402 ignore necessary for path append before sys module import in actions
ignore = E402,W503,W504

View File

@@ -1 +0,0 @@
This is not the unit tests you are looking for, take a look at `layer-ovn`.

View File

@@ -1,69 +0,0 @@
# Copyright 2018 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 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('src')
sys.path.append('src/lib')
# Mock out charmhelpers so that we can test without it.
import charms_openstack.test_mocks # noqa
charms_openstack.test_mocks.mock_charmhelpers()
import mock
class _fake_decorator(object):
def __init__(self, *args):
pass
def __call__(self, f):
return f
charms = mock.MagicMock()
sys.modules['charms'] = charms
charms.leadership = mock.MagicMock()
sys.modules['charms.leadership'] = charms.leadership
charms.reactive = mock.MagicMock()
charms.reactive.when = _fake_decorator
charms.reactive.when_all = _fake_decorator
charms.reactive.when_any = _fake_decorator
charms.reactive.when_not = _fake_decorator
charms.reactive.when_none = _fake_decorator
charms.reactive.when_not_all = _fake_decorator
charms.reactive.not_unless = _fake_decorator
charms.reactive.when_file_changed = _fake_decorator
charms.reactive.collect_metrics = _fake_decorator
charms.reactive.meter_status_changed = _fake_decorator
charms.reactive.only_once = _fake_decorator
charms.reactive.hook = _fake_decorator
charms.reactive.bus = mock.MagicMock()
charms.reactive.flags = mock.MagicMock()
charms.reactive.relations = mock.MagicMock()
sys.modules['charms.reactive'] = charms.reactive
sys.modules['charms.reactive.bus'] = charms.reactive.bus
sys.modules['charms.reactive.bus'] = charms.reactive.decorators
sys.modules['charms.reactive.flags'] = charms.reactive.flags
sys.modules['charms.reactive.relations'] = charms.reactive.relations
sys.modules['charms.leadership'] = charms.leadership
netaddr = mock.MagicMock()
sys.modules['netaddr'] = netaddr
import reactive
reactive.ovn_chassis_charm_handlers = mock.MagicMock()
reactive.ovn_chassis_charm_handlers.OVN_CHASSIS_ENABLE_HANDLERS_FLAG = \
'MOCKED_FLAG'
sys.modules['reactive.ovn_chassis_charm_handlers'] = \
reactive.ovn_chassis_charm_handlers

View File

@@ -1,54 +0,0 @@
# Copyright 2019 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 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 reactive.ovn_chassis_handlers as handlers
import charms_openstack.test_utils as test_utils
class TestRegisteredHooks(test_utils.TestRegisteredHooks):
def setUp(self):
super().setUp()
def test_hooks(self):
hook_set = {
'when_none': {
'configure_nrpe': ('charm.paused', 'is-update-status-hook',),
},
'when_not': {
'enable_ovn_chassis_handlers': ('MOCKED_FLAG',),
'configure_deferred_restarts': ('is-update-status-hook',),
},
'when': {
'configure_nrpe': ('config.rendered',),
},
'when_any': {
'configure_nrpe': ('config.changed.nagios_context',
'config.changed.nagios_servicegroups',
'endpoint.nrpe-external-master.changed',
'nrpe-external-master.available',),
},
}
# test that the hooks were registered via the
# reactive.ovn_handlers
self.registered_hooks_test_helper(handlers, hook_set, {})
class TestOvnHandlers(test_utils.PatchHelper):
def test_enable_ovn_chassis_handlers(self):
self.patch_object(handlers.reactive, 'set_flag')
handlers.enable_ovn_chassis_handlers()
self.set_flag.assert_called_once_with('MOCKED_FLAG')