This is a combination of all the commits.
=======================================================================
Enable Robot Tests
Enabling robot tests in CI/CD pipeline
Propagate the parameter DO_ROBOT to stage_3-merge
Setting OSM_HOSTNAME for robot test execution
Adding prometheus_hostname env variable for ci/cd tests
Archive containers logs in robot test execution
Signed-off-by: beierlm <mark.beierl@canonical.com>
Author: Felipe Vicens <felipe.vicens@atos.net>
8716 - K8s Proxy Charms
This commit contains the following changes:
- Changes to LCM Charm to configure vca k8s cloud
- K8s installation:
- Add storageclass to K8s
- Add k8s to VCA
- Configure lcm.env to pass k8s cloud name
- Pass k8s cloud name to LCM Charm in charmed
installation
- Pin juju version tu 2.8/stable
- Instal juju after Microk8s in charmed
installation
Signed-off-by: Dominik Fleischmann <dominik.fleischmann@canonical.com>
Add PLA charm
Signed-off-by: David Garcia <david.garcia@canonical.com>
Add NG-UI Charm
Signed-off-by: David Garcia <david.garcia@canonical.com>
Fix bugs in NG-UI charm
Signed-off-by: David Garcia <david.garcia@canonical.com>
Updated Dockerfiles to use ReleaseEIGHT-daily repo by default
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Fix bug 1124: K8s added to juju after k8s has been initialized
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Helm and k8s storage initialization for k8s-based installation
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Fix bug 1125: iptables must be installed and configured if not present
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Fix bug 1129: juju_addk8s requires the storage class
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Fix issue in UI charm
Scale policy is only available in stateful pods
Signed-off-by: David Garcia <david.garcia@canonical.com>
Adds image overlay to bundle
When installing using a bundle, the image overlay was not being
generated, resulting in the --tag option being ignored.
Bug 1130
Signed-off-by: beierlm <mark.beierl@canonical.com>
Fix uninstall process, will fix issues is daily-stage4
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Fix PLA relations, add missing ENVs, and include it in the bundle
Signed-off-by: David Garcia <david.garcia@canonical.com>
Fix 1127 bug: Use config instead of resources for SSL certificates
Signed-off-by: David Garcia <david.garcia@canonical.com>
Remove unused config from PLA overlayx
Signed-off-by: David Garcia <david.garcia@canonical.com>
Installer: refactor file generation, improved ng-ui and light-ui separation, fixes in PLA
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
Pin libjuju version to 2.8.2
This fixes bug 1144
Signed-off-by: David Garcia <david.garcia@canonical.com>
Pin libjuju version to 2.8.2
Fixes bug 1144
Signed-off-by: Mark Beierl <mark.beierl@canonical.com>
Remove api_proxy variable in charmed installer
- Fixes bug 1154
Signed-off-by: David Garcia <david.garcia@canonical.com>
Add waiting period to Storage Class creation
This commit adds a waiting period until the
storage class is available.
It also fixes a minor bug in the juju add-k8s
command.
This fixes Bug 1155
Signed-off-by: Dominik Fleischmann <dominik.fleischmann@canonical.com>
Remove api_proxy from osm bundles
Signed-off-by: David Garcia <david.garcia@canonical.com>
Make Charmed Installer Idempotent
By default, the charmed installer will create a controller called
'controller', unless an external VCA is specified using the --vca
option. Upon uninstall, it is not known or safe to remove this
Juju controller as there might be other applications using it.
This change shows that message on uninstall, giving the user the
opportunity to remove it with a command.
Also, as part of the installation, this change checks for the
controller and if it exists, presents the user with options for
how to resolve the situation.
Fixes bug 1126
Signed-off-by: beierlm <mark.beierl@canonical.com>
Remove unneeded mysql interface in PLA, fix osm-ha bundle, and add README.md to bundles
Signed-off-by: David Garcia <david.garcia@canonical.com>
Expose NBI and NG-UI
Adds ingress rules for K8s installation to expose the NBI, the
NG-UI and allow for unlimited content size.
Fixes bug 1171
Signed-off-by: beierlm <mark.beierl@canonical.com>
Installer Quits Too Soon
Increases the timeout and provides more feedback on progress.
Signed-off-by: beierlm <mark.beierl@canonical.com>
Change in returned storage status format from microk8s
Signed-off-by: calvinosanc1 <guillermo.calvino@canonical.com>
========================================================================================
Change-Id: I9223675bb9ad25a0da1f20215e79ef392e544eb5
Signed-off-by: beierlm <mark.beierl@canonical.com>
--- /dev/null
+# Copyright 2020 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.
+[submodule "installers/charm/pla/mod/operator"]
+ path = installers/charm/pla/mod/operator
+ url = https://github.com/canonical/operator
+[submodule "installers/charm/ng-ui/mod/operator"]
+ path = installers/charm/ng-ui/mod/operator
+ url = https://github.com/canonical/operator
&& mv juju /usr/local/bin/juju
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
'paramiko' 'dogpile.cache==0.9.2'
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
&& mkdir -p /app/storage/kafka && mkdir -p /app/log
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
&& apt-get install -y nginx
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
ARG NGUI_VERSION
&& python3 -m pip install pymzn==0.18.3
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
&& pip3 install pip==9.0.3
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
&& python3 -m pip install --upgrade pip && python3 -m pip install pyangbind networking-l2gw
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseFOUR-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
ARG LWUI_VERSION
TAG ?= 6
REPOSITORY_BASE ?= http://osm-download.etsi.org/repository/osm/debian
-RELEASE ?= ReleaseFOUR-daily
+RELEASE ?= ReleaseEIGHT-daily
REPOSITORY_KEY ?= OSM%20ETSI%20Release%20Key.gpg
REPOSITORY ?= testing
NO_CACHE ?= --no-cache
#!/bin/sh
+#
+# Copyright 2020 ETSI
+#
+# 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.
+#
-RELEASE="ReleaseFOUR-daily"
+RELEASE="ReleaseEIGHT-daily"
REPOSITORY_KEY="OSM%20ETSI%20Release%20Key.gpg"
REPOSITORY="testing"
REPOSITORY_BASE="http://osm-download.etsi.org/repository/osm/debian"
RUN python3 -m pip install -U pip && python3 -m pip install pyyaml python-magic pyangbind pytest==4.6.3 verboselogs
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
git+https://osm.etsi.org/gerrit/osm/IM.git git+https://osm.etsi.org/gerrit/osm/osmclient.git
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
-ARG RELEASE=ReleaseSEVEN-daily
+ARG RELEASE=ReleaseEIGHT-daily
ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
ARG REPOSITORY=testing
ARG TESTS_VERSION
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
-ENTRYPOINT [ "/robot-systest/run_test.sh"]
\ No newline at end of file
+ENTRYPOINT [ "/robot-systest/run_test.sh"]
├── nbi-k8s
├── pol-k8s
├── ro-k8s
-└── ui-k8s
+├── ui-k8s
+└── ng-ui --> new operator framework
```
--- /dev/null
+<!--
+ Copyright 2020 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.
+-->
+# Charmed OSM
+
+
+Charmed OSM is an OSM distribution, developed and maintained by Canonical, which uses Juju charms to simplify its deployments and operations. Charmed OSM enables TSPs to easily deploy pure upstream OSM in highly available, production-grade and scalable clusters.
+
+- Industry‐aligned and fully compliant with upstream
+- Predictable release cadence and upgrade path
+- Simplified deployments and operations
+- Stable and secure
+- Highly Available and resilient against failures
+- Supported with [Ubuntu Advantage](https://ubuntu.com/advantage)
+- Availability of managed services
+
+
+## Quick start
+
+Go to the [OSM User Guide](https://osm.etsi.org/docs/user-guide/03-installing-osm.html#charmed-installation)
zookeeper-units: 3
annotations:
gui-x: 0
- gui-y: 1100
+ gui-y: 550
mariadb-k8s:
charm: "cs:~charmed-osm/mariadb-k8s"
channel: "stable"
query-cache-size: 0
ha-mode: true
annotations:
- gui-x: -500
- gui-y: -400
+ gui-x: -250
+ gui-y: -200
kafka-k8s:
charm: "cs:~charmed-osm/kafka-k8s"
channel: "stable"
zookeeper-service-name: zookeeper-k8s-endpoints
annotations:
gui-x: 0
- gui-y: 600
+ gui-y: 300
mongodb-k8s:
charm: "cs:~charmed-osm/mongodb-k8s"
channel: "stable"
enable-sidecar: true
annotations:
gui-x: 0
- gui-y: 100
+ gui-y: 50
nbi-k8s:
charm: "cs:~charmed-osm/nbi-k8s"
channel: "%(channel)s"
DATABASE_COMMONKEY: osm
annotations:
gui-x: 0
- gui-y: -400
+ gui-y: -200
ro-k8s:
charm: "cs:~charmed-osm/ro-k8s"
channel: "%(channel)s"
ro_database: "mano_db"
OPENMANO_TENANT: "osm"
annotations:
- gui-x: -500
- gui-y: 600
+ gui-x: -250
+ gui-y: 300
ui-k8s:
charm: "cs:~charmed-osm/ui-k8s"
channel: "%(channel)s"
series: kubernetes
options:
mysql_database: lwui
+ annotations:
+ gui-x: 250
+ gui-y: -200
+ ng-ui:
+ charm: "%(prefix)s/ng-ui%(suffix)s"
+ channel: "%(channel)s"
+ scale: 3
+ series: kubernetes
+ options:
+ port: 80
+ https_port: 443
+ server_name: localhost
+ client_max_body_size: 15M
annotations:
gui-x: 500
- gui-y: -400
+ gui-y: 100
lcm-k8s:
charm: "cs:~charmed-osm/lcm-k8s"
channel: "%(channel)s"
vca_password: secret
vca_pubkey: pubkey
vca_cacert: cacert
- vca_apiproxy: apiproxy
use_external_vca: true
DATABASE_COMMONKEY: osm
annotations:
- gui-x: -500
- gui-y: 100
+ gui-x: -250
+ gui-y: 50
mon-k8s:
charm: "cs:~charmed-osm/mon-k8s"
channel: "%(channel)s"
vca_cacert: cacert
use_external_vca: true
annotations:
- gui-x: 500
- gui-y: 100
+ gui-x: 250
+ gui-y: 50
pol-k8s:
charm: "cs:~charmed-osm/pol-k8s"
channel: "%(channel)s"
options:
log_level: INFO
annotations:
- gui-x: -500
- gui-y: 1100
+ gui-x: -250
+ gui-y: 550
+ pla:
+ charm: "%(prefix)s/pla%(suffix)s"
+ channel: "%(channel)s"
+ scale: 3
+ series: kubernetes
+ annotations:
+ gui-x: 500
+ gui-y: -200
prometheus-k8s:
charm: "cs:~charmed-osm/prometheus-k8s"
channel: "stable"
web-subpath: /
default-target: "mon-k8s:8000"
annotations:
- gui-x: 500
- gui-y: 600
+ gui-x: 250
+ gui-y: 300
grafana-k8s:
charm: "cs:~charmed-osm/grafana-k8s"
channel: "stable"
scale: 3
series: kubernetes
annotations:
- gui-x: 500
- gui-y: 1100
+ gui-x: 250
+ gui-y: 550
relations:
- - "kafka-k8s:zookeeper"
- "nbi-k8s:nbi"
- - "prometheus-k8s:prometheus"
- "nbi-k8s:prometheus"
+ - - "pla:kafka"
+ - "kafka-k8s:kafka"
+ - - "pla:mongo"
+ - "mongodb-k8s:mongo"
+ - - 'ng-ui:nbi'
+ - 'nbi-k8s:nbi'
--- /dev/null
+<!--
+ Copyright 2020 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.
+-->
+# Charmed OSM
+
+
+Charmed OSM is an OSM distribution, developed and maintained by Canonical, which uses Juju charms to simplify its deployments and operations. Charmed OSM enables TSPs to easily deploy pure upstream OSM in highly available, production-grade and scalable clusters.
+
+- Industry‐aligned and fully compliant with upstream
+- Predictable release cadence and upgrade path
+- Simplified deployments and operations
+- Stable and secure
+- Highly Available and resilient against failures
+- Supported with [Ubuntu Advantage](https://ubuntu.com/advantage)
+- Availability of managed services
+
+
+## Quick start
+
+Go to the [OSM User Guide](https://osm.etsi.org/docs/user-guide/03-installing-osm.html#charmed-installation)
bundle: kubernetes
applications:
zookeeper-k8s:
- charm: 'cs:~charmed-osm/zookeeper-k8s'
- channel: 'stable'
+ charm: "cs:~charmed-osm/zookeeper-k8s"
+ channel: "stable"
scale: 1
series: kubernetes
storage:
zookeeper-units: 1
annotations:
gui-x: 0
- gui-y: 1100
+ gui-y: 550
mariadb-k8s:
- charm: 'cs:~charmed-osm/mariadb-k8s'
- channel: 'stable'
+ charm: "cs:~charmed-osm/mariadb-k8s"
+ channel: "stable"
scale: 1
series: kubernetes
storage:
query-cache-size: 0
ha-mode: false
annotations:
- gui-x: -500
- gui-y: -400
+ gui-x: -250
+ gui-y: -200
kafka-k8s:
- charm: 'cs:~charmed-osm/kafka-k8s'
- channel: 'stable'
+ charm: "cs:~charmed-osm/kafka-k8s"
+ channel: "stable"
scale: 1
series: kubernetes
storage:
zookeeper-service-name: zookeeper-k8s-endpoints
annotations:
gui-x: 0
- gui-y: 600
+ gui-y: 300
mongodb-k8s:
- charm: 'cs:~charmed-osm/mongodb-k8s'
- channel: 'stable'
+ charm: "cs:~charmed-osm/mongodb-k8s"
+ channel: "stable"
scale: 1
series: kubernetes
storage:
enable-sidecar: false
annotations:
gui-x: 0
- gui-y: 100
+ gui-y: 50
nbi-k8s:
- charm: '%(prefix)s/nbi-k8s%(suffix)s'
- channel: '%(channel)s'
+ charm: "%(prefix)s/nbi-k8s%(suffix)s"
+ channel: "%(channel)s"
scale: 1
series: kubernetes
storage:
DATABASE_COMMONKEY: osm
annotations:
gui-x: 0
- gui-y: -400
+ gui-y: -200
ro-k8s:
- charm: '%(prefix)s/ro-k8s%(suffix)s'
- channel: '%(channel)s'
+ charm: "%(prefix)s/ro-k8s%(suffix)s"
+ channel: "%(channel)s"
scale: 1
series: kubernetes
storage:
log: 50M
options:
- vim_database: 'mano_vim_db'
- ro_database: 'mano_db'
- OPENMANO_TENANT: 'osm'
+ vim_database: "mano_vim_db"
+ ro_database: "mano_db"
+ OPENMANO_TENANT: "osm"
annotations:
- gui-x: -500
- gui-y: 600
+ gui-x: -250
+ gui-y: 300
ui-k8s:
- charm: '%(prefix)s/ui-k8s%(suffix)s'
- channel: '%(channel)s'
+ charm: "%(prefix)s/ui-k8s%(suffix)s"
+ channel: "%(channel)s"
scale: 1
series: kubernetes
options:
mysql_database: lwui
+ annotations:
+ gui-x: 250
+ gui-y: -200
+ ng-ui:
+ charm: "%(prefix)s/ng-ui%(suffix)s"
+ channel: "%(channel)s"
+ scale: 1
+ series: kubernetes
+ options:
+ port: 80
+ https_port: 443
+ server_name: localhost
+ client_max_body_size: 15M
annotations:
gui-x: 500
- gui-y: -400
+ gui-y: 100
lcm-k8s:
- charm: '%(prefix)s/lcm-k8s%(suffix)s'
- channel: '%(channel)s'
+ charm: "%(prefix)s/lcm-k8s%(suffix)s"
+ channel: "%(channel)s"
scale: 1
series: kubernetes
storage:
vca_password: secret
vca_pubkey: pubkey
vca_cacert: cacert
- vca_apiproxy: apiproxy
use_external_vca: false
DATABASE_COMMONKEY: osm
annotations:
- gui-x: -500
- gui-y: 100
+ gui-x: -250
+ gui-y: 50
mon-k8s:
- charm: '%(prefix)s/mon-k8s%(suffix)s'
- channel: '%(channel)s'
+ charm: "%(prefix)s/mon-k8s%(suffix)s"
+ channel: "%(channel)s"
scale: 1
series: kubernetes
storage:
vca_cacert: cacert
use_external_vca: false
annotations:
- gui-x: 500
- gui-y: 100
+ gui-x: 250
+ gui-y: 50
pol-k8s:
- charm: '%(prefix)s/pol-k8s%(suffix)s'
- channel: '%(channel)s'
+ charm: "%(prefix)s/pol-k8s%(suffix)s"
+ channel: "%(channel)s"
scale: 1
series: kubernetes
storage:
options:
log_level: INFO
annotations:
- gui-x: -500
- gui-y: 1100
+ gui-x: -250
+ gui-y: 550
+ pla:
+ charm: "%(prefix)s/pla%(suffix)s"
+ channel: "%(channel)s"
+ scale: 1
+ series: kubernetes
+ annotations:
+ gui-x: 500
+ gui-y: -200
prometheus-k8s:
- charm: 'cs:~charmed-osm/prometheus-k8s'
- channel: 'stable'
+ charm: "cs:~charmed-osm/prometheus-k8s"
+ channel: "stable"
scale: 1
series: kubernetes
storage:
web-subpath: /
default-target: "mon-k8s:8000"
annotations:
- gui-x: 500
- gui-y: 600
+ gui-x: 250
+ gui-y: 300
grafana-k8s:
- charm: 'cs:~charmed-osm/grafana-k8s'
- channel: 'stable'
+ charm: "cs:~charmed-osm/grafana-k8s"
+ channel: "stable"
scale: 1
series: kubernetes
annotations:
- gui-x: 500
- gui-y: 1100
+ gui-x: 250
+ gui-y: 550
relations:
- - - 'kafka-k8s:zookeeper'
- - 'zookeeper-k8s:zookeeper'
- - - 'ro-k8s:mysql'
- - 'mariadb-k8s:mysql'
- - - 'nbi-k8s:mongo'
- - 'mongodb-k8s:mongo'
- - - 'nbi-k8s:kafka'
- - 'kafka-k8s:kafka'
- - - 'lcm-k8s:kafka'
- - 'kafka-k8s:kafka'
- - - 'lcm-k8s:mongo'
- - 'mongodb-k8s:mongo'
- - - 'mon-k8s:kafka'
- - 'kafka-k8s:kafka'
- - - 'mon-k8s:mongo'
- - 'mongodb-k8s:mongo'
- - - 'pol-k8s:kafka'
- - 'kafka-k8s:kafka'
- - - 'pol-k8s:mongo'
- - 'mongodb-k8s:mongo'
- - - 'lcm-k8s:ro'
- - 'ro-k8s:ro'
- - - 'prometheus-k8s:prometheus'
- - 'mon-k8s:prometheus'
- - - 'grafana-k8s:prometheus'
- - 'prometheus-k8s:prometheus'
- - - 'ui-k8s:mysql'
- - 'mariadb-k8s:mysql'
- - - 'ui-k8s:nbi'
+ - - "kafka-k8s:zookeeper"
+ - "zookeeper-k8s:zookeeper"
+ - - "ro-k8s:mysql"
+ - "mariadb-k8s:mysql"
+ - - "nbi-k8s:mongo"
+ - "mongodb-k8s:mongo"
+ - - "nbi-k8s:kafka"
+ - "kafka-k8s:kafka"
+ - - "lcm-k8s:kafka"
+ - "kafka-k8s:kafka"
+ - - "lcm-k8s:mongo"
+ - "mongodb-k8s:mongo"
+ - - "mon-k8s:kafka"
+ - "kafka-k8s:kafka"
+ - - "mon-k8s:mongo"
+ - "mongodb-k8s:mongo"
+ - - "pol-k8s:kafka"
+ - "kafka-k8s:kafka"
+ - - "pol-k8s:mongo"
+ - "mongodb-k8s:mongo"
+ - - "lcm-k8s:ro"
+ - "ro-k8s:ro"
+ - - "prometheus-k8s:prometheus"
+ - "mon-k8s:prometheus"
+ - - "grafana-k8s:prometheus"
+ - "prometheus-k8s:prometheus"
+ - - "ui-k8s:mysql"
+ - "mariadb-k8s:mysql"
+ - - "ui-k8s:nbi"
+ - "nbi-k8s:nbi"
+ - - "prometheus-k8s:prometheus"
+ - "nbi-k8s:prometheus"
+ - - "pla:kafka"
+ - "kafka-k8s:kafka"
+ - - "pla:mongo"
+ - "mongodb-k8s:mongo"
+ - - 'ng-ui:nbi'
- 'nbi-k8s:nbi'
- - - 'prometheus-k8s:prometheus'
- - 'nbi-k8s:prometheus'
type: string
description: "The VCA lxd cloud name"
default: "localhost"
+ vca_k8s_cloud:
+ type: string
+ description: "The VCA K8s cloud name"
+ default: "k8scloud"
advertised-hostname:
description: LCM Hostname
type: string
config,
)
from charms import layer
-
+import yaml
@hook("upgrade-charm")
@when("leadership.is_leader")
}
data.update(cfg)
- return pod_spec_template % data
+ spec = yaml.safe_dump(pod_spec_template % data)
+ if "vca_apiproxy" in cfg and cfg["vca_apiproxy"] != "":
+ spec["containers"][0]["config"]["OSMLCM_VCA_APIPROXY"] = cfg["vca_apiproxy"]
+ return spec
\ No newline at end of file
OSMLCM_VCA_PUBKEY: %(vca_pubkey)s
OSMLCM_VCA_SECRET: %(vca_password)s
OSMLCM_VCA_CACERT: %(vca_cacert)s
- OSMLCM_VCA_APIPROXY: %(vca_apiproxy)s
OSMLCM_VCA_CLOUD: %(vca_cloud)s
+ OSMLCM_VCA_K8S_CLOUD: %(vca_k8s_cloud)s
OSMNBI_DATABASE_DRIVER: mongo
OSMNBI_DATABASE_URI: %(mongo_uri)s
OSMNBI_DATABASE_COMMONKEY: %(DATABASE_COMMONKEY)s
-
+
OSMNBI_STORAGE_DRIVER: mongo
OSMNBI_STORAGE_PATH: /app/storage
OSMNBI_STORAGE_COLLECTION: files
OSMNBI_STORAGE_URI: %(mongo_uri)s
OSMNBI_STATIC_DIR: /app/osm_nbi/html_public
-
+
OSMNBI_PROMETHEUS_HOST: %(prometheus_host)s
OSMNBI_PROMETHEUS_PORT: %(prometheus_port)s
- OSMNBI_LOG_LEVEL: %(log_level)s
\ No newline at end of file
+ OSMNBI_LOG_LEVEL: %(log_level)s
--- /dev/null
+# Copyright 2020 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.
+---
+extends: default
+
+yaml-files:
+ - "*.yaml"
+ - "*.yml"
+ - ".yamllint"
+ignore: |
+ .tox
+ mod
--- /dev/null
+<!-- # Copyright 2020 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. -->
+
+# NG-UI Charm
+
+## How to deploy
+
+```bash
+juju deploy . # cs:~charmed-osm/ng-ui --channel edge
+juju relate ng-ui nbi-k8s
+```
+
+## How to expose the NG-UI through ingress
+
+```bash
+juju config ng-ui juju-external-hostname=ng.<k8s_worker_ip>.xip.io
+juju expose ng-ui
+```
+
+> Note: The <k8s_worker_ip> is the IP of the K8s worker node. With microk8s, you can see the IP with `microk8s.config`. It is usually the IP of your host machine.
+
+## How to scale
+
+```bash
+ juju scale-application ng-ui 3
+```
+
+## How to use certificates
+
+Generate your own certificate if you don't have one already:
+
+```bash
+sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ssl_certificate.key -out ssl_certificate.crt
+sudo chown $USER:$USER ssl_certificate.key
+juju config ng-ui ssl_certificate=`cat ssl_certificate.crt | base64 -w 0`
+juju config ng-ui ssl_certificate_key=`cat ssl_certificate.key | base64 -w 0`
+```
+
+## Config Examples
+
+```bash
+juju config ng-ui image=opensourcemano/ng-ui:<tag>
+juju config ng-ui port=80
+juju config server_name=<name>
+juju config client_max_body_size=25M
+```
--- /dev/null
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Arctos Labs Scandinavia AB
+#
+# 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.
+
+options:
+ image:
+ description: Docker image name
+ type: string
+ default: opensourcemano/ng-ui:8
+ port:
+ description: Port number
+ type: int
+ default: 80
+ https_port:
+ description: Port number
+ type: int
+ default: 443
+ server_name:
+ description: Server name
+ type: string
+ default: localhost
+ client_max_body_size:
+ description: Client maximum body size
+ type: string
+ default: 15M
+ ssl_certificate:
+ description: Base64 encoded ssl certificate
+ type: string
+ ssl_certificate_key:
+ description: Base64 encoded ssl certificate key
+ type: string
--- /dev/null
+# Copyright 2020 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.
+
+
+
+server {
+ listen $http_port;
+ listen $https_port default ssl;
+ server_name $server_name;
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ client_max_body_size $client_max_body_size;
+ $ssl_crt
+ $ssl_crt_key
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
+ location /osm {
+ proxy_pass https://$nbi_host:$nbi_port;
+ proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
+ proxy_set_header Accept-Encoding "";
+ }
+
+ location / {
+ try_files $$uri $$uri/ /index.html;
+ }
+}
--- /dev/null
+../src/charm.py
\ No newline at end of file
--- /dev/null
+../mod/operator/ops
\ No newline at end of file
--- /dev/null
+# Copyright 2020 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.
+
+name: ng-ui
+summary: A Next Generation UI charm for Opensource MANO
+description: |
+ New UI for OSM
+series:
+ - kubernetes
+min-juju-version: 2.7.0
+deployment:
+ type: stateless
+ service: cluster
+requires:
+ nbi:
+ interface: osm-nbi
--- /dev/null
+Subproject commit a84ce8776b368a8b2bccdb173716e342db9a6b36
--- /dev/null
+#!/usr/bin/env python3
+# Copyright 2020 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
+import logging
+import base64
+
+sys.path.append("lib")
+
+from ops.charm import CharmBase
+from ops.framework import StoredState, Object
+from ops.main import main
+from ops.model import (
+ ActiveStatus,
+ MaintenanceStatus,
+ BlockedStatus,
+ ModelError,
+ WaitingStatus,
+)
+
+from glob import glob
+from pathlib import Path
+from string import Template
+
+logger = logging.getLogger(__name__)
+
+
+class NGUICharm(CharmBase):
+ state = StoredState()
+
+ def __init__(self, framework, key):
+ super().__init__(framework, key)
+ self.state.set_default(spec=None)
+ self.state.set_default(nbi_host=None)
+ self.state.set_default(nbi_port=None)
+
+ # Observe Charm related events
+ self.framework.observe(self.on.config_changed, self.on_config_changed)
+ self.framework.observe(self.on.start, self.on_start)
+ self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
+ self.framework.observe(
+ self.on.nbi_relation_changed, self.on_nbi_relation_changed
+ )
+
+ # SSL Certificate path
+ self.ssl_folder = "/certs"
+ self.ssl_crt_name = "ssl_certificate.crt"
+ self.ssl_key_name = "ssl_certificate.key"
+
+ def _apply_spec(self):
+ # Only apply the spec if this unit is a leader.
+ unit = self.model.unit
+ if not unit.is_leader():
+ unit.status = ActiveStatus("ready")
+ return
+ if not self.state.nbi_host or not self.state.nbi_port:
+ unit.status = WaitingStatus("Waiting for NBI")
+ return
+ unit.status = MaintenanceStatus("Applying new pod spec")
+
+ new_spec = self.make_pod_spec()
+ if new_spec == self.state.spec:
+ unit.status = ActiveStatus("ready")
+ return
+ self.framework.model.pod.set_spec(new_spec)
+ self.state.spec = new_spec
+ unit.status = ActiveStatus("ready")
+
+ def make_pod_spec(self):
+ config = self.framework.model.config
+
+ config_spec = {
+ "http_port": config["port"],
+ "https_port": config["https_port"],
+ "server_name": config["server_name"],
+ "client_max_body_size": config["client_max_body_size"],
+ "nbi_host": self.state.nbi_host or config["nbi_host"],
+ "nbi_port": self.state.nbi_port or config["nbi_port"],
+ "ssl_crt": "",
+ "ssl_crt_key": "",
+ }
+
+ ssl_certificate = None
+ ssl_certificate_key = None
+ ssl_enabled = False
+
+ if "ssl_certificate" in config and "ssl_certificate_key" in config:
+ # Get bytes of cert and key
+ cert_b = base64.b64decode(config["ssl_certificate"])
+ key_b = base64.b64decode(config["ssl_certificate_key"])
+ # Decode key and cert
+ ssl_certificate = cert_b.decode("utf-8")
+ ssl_certificate_key = key_b.decode("utf-8")
+ # Get paths
+ cert_path = "{}/{}".format(self.ssl_folder, self.ssl_crt_name)
+ key_path = "{}/{}".format(self.ssl_folder, self.ssl_key_name)
+
+ config_spec["port"] = "{} ssl".format(config["https_port"])
+ config_spec["ssl_crt"] = "ssl_certificate {};".format(cert_path)
+ config_spec["ssl_crt_key"] = "ssl_certificate_key {};".format(key_path)
+ ssl_enabled = True
+ else:
+ config_spec["ssl_crt"] = ""
+ config_spec["ssl_crt_key"] = ""
+
+ files = [
+ {
+ "name": "configuration",
+ "mountPath": "/etc/nginx/sites-available/",
+ "files": {
+ Path(filename)
+ .name: Template(Path(filename).read_text())
+ .substitute(config_spec)
+ for filename in glob("files/*")
+ },
+ }
+ ]
+ port = config["https_port"] if ssl_enabled else config["port"]
+ ports = [
+ {"name": "port", "containerPort": port, "protocol": "TCP", },
+ ]
+
+ kubernetes = {
+ "readinessProbe": {
+ "tcpSocket": {"port": port},
+ "timeoutSeconds": 5,
+ "periodSeconds": 5,
+ "initialDelaySeconds": 10,
+ },
+ "livenessProbe": {
+ "tcpSocket": {"port": port},
+ "timeoutSeconds": 5,
+ "initialDelaySeconds": 45,
+ },
+ }
+
+ if ssl_certificate and ssl_certificate_key:
+ files.append(
+ {
+ "name": "ssl",
+ "mountPath": self.ssl_folder,
+ "files": {
+ self.ssl_crt_name: ssl_certificate,
+ self.ssl_key_name: ssl_certificate_key,
+ },
+ }
+ )
+ logger.debug(files)
+ spec = {
+ "version": 2,
+ "containers": [
+ {
+ "name": self.framework.model.app.name,
+ "image": "{}".format(config["image"]),
+ "ports": ports,
+ "kubernetes": kubernetes,
+ "files": files,
+ }
+ ],
+ }
+
+ return spec
+
+ def on_config_changed(self, event):
+ """Handle changes in configuration"""
+ self._apply_spec()
+
+ def on_start(self, event):
+ """Called when the charm is being installed"""
+ self._apply_spec()
+
+ def on_upgrade_charm(self, event):
+ """Upgrade the charm."""
+ unit = self.model.unit
+ unit.status = MaintenanceStatus("Upgrading charm")
+ self.on_start(event)
+
+ def on_nbi_relation_changed(self, event):
+ unit = self.model.unit
+ if not unit.is_leader():
+ return
+ self.state.nbi_host = event.relation.data[event.unit].get("host")
+ self.state.nbi_port = event.relation.data[event.unit].get("port")
+ self._apply_spec()
+
+
+if __name__ == "__main__":
+ main(NGUICharm)
--- /dev/null
+# Copyright 2020 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.
+[tox]
+envlist = pep8
+skipsdist = True
+
+[testenv]
+setenv = VIRTUAL_ENV={envdir}
+ PYTHONHASHSEED=0
+whitelist_externals = juju
+passenv = HOME TERM CS_API_* OS_* AMULET_*
+deps = -r{toxinidir}/test-requirements.txt
+install_command =
+ pip install {opts} {packages}
+
+[testenv:black]
+basepython = python3
+deps =
+ black
+ yamllint
+commands =
+ black --check --diff src
+ yamllint .
+
+[testenv:pep8]
+basepython = python3
+deps=charm-tools
+commands = charm-proof
+
+[testenv:func-noop]
+basepython = python3
+commands =
+ true
+
+[testenv:func]
+basepython = python3
+commands = functest-run-suite
+
+[testenv:func-smoke]
+basepython = python3
+commands = functest-run-suite --keep-model --smoke
+
+[testenv:venv]
+commands = {posargs}
--- /dev/null
+# Copyright 2020 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.
+---
+extends: default
+
+yaml-files:
+ - "*.yaml"
+ - "*.yml"
+ - ".yamllint"
+ignore: |
+ .tox
+ mod
--- /dev/null
+<!-- # Copyright 2020 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. -->
+# PLA Charm
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Arctos Labs Scandinavia AB
+#
+# 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.
+
+options:
+ image:
+ description: Docker image name
+ type: string
+ default: opensourcemano/pla:8
+ port:
+ description: Port number
+ type: int
+ default: 8080 # Fake port
+ log_level:
+ description: Log level
+ type: string
+ default: INFO
+ database:
+ description: Database name
+ type: string
+ default: pla
+ database_common_key:
+ description: Common Key for Mongo database
+ type: string
+ default: osm
--- /dev/null
+../src/charm.py
\ No newline at end of file
--- /dev/null
+../src/charm.py
\ No newline at end of file
--- /dev/null
+../src/charm.py
\ No newline at end of file
--- /dev/null
+../mod/operator/ops
\ No newline at end of file
--- /dev/null
+# Copyright 2020 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.
+
+name: pla
+summary: A Placement charm for Opensource MANO
+description: |
+ Placement module for OSM
+series:
+ - kubernetes
+min-juju-version: 2.7.0
+deployment:
+ type: stateless
+ service: cluster
+requires:
+ kafka:
+ interface: kafka
+ mongo:
+ interface: mongodb
--- /dev/null
+Subproject commit a84ce8776b368a8b2bccdb173716e342db9a6b36
--- /dev/null
+#!/usr/bin/env python3
+# Copyright 2020 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
+import logging
+
+sys.path.append("lib")
+
+from ops.charm import CharmBase
+from ops.framework import StoredState, Object
+from ops.main import main
+from ops.model import (
+ ActiveStatus,
+ MaintenanceStatus,
+ WaitingStatus,
+)
+
+from glob import glob
+from pathlib import Path
+from string import Template
+
+logger = logging.getLogger(__name__)
+
+
+class PLACharm(CharmBase):
+ state = StoredState()
+
+ def __init__(self, framework, key):
+ super().__init__(framework, key)
+ self.state.set_default(spec=None)
+ self.state.set_default(kafka_host=None)
+ self.state.set_default(kafka_port=None)
+ self.state.set_default(mongodb_uri=None)
+
+ # Observe Charm related events
+ self.framework.observe(self.on.config_changed, self.on_config_changed)
+ self.framework.observe(self.on.start, self.on_start)
+ self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
+
+ # Relations
+ self.framework.observe(
+ self.on.kafka_relation_changed, self.on_kafka_relation_changed
+ )
+ self.framework.observe(
+ self.on.mongo_relation_changed, self.on_mongo_relation_changed
+ )
+
+ def _apply_spec(self):
+ # Only apply the spec if this unit is a leader.
+ unit = self.model.unit
+ if not unit.is_leader():
+ unit.status = ActiveStatus("ready")
+ return
+ if not self.state.kafka_host or not self.state.kafka_port:
+ unit.status = WaitingStatus("Waiting for Kafka")
+ return
+ if not self.state.mongodb_uri:
+ unit.status = WaitingStatus("Waiting for MongoDB")
+ return
+
+ unit.status = MaintenanceStatus("Applying new pod spec")
+
+ new_spec = self.make_pod_spec()
+ if new_spec == self.state.spec:
+ unit.status = ActiveStatus("ready")
+ return
+ self.framework.model.pod.set_spec(new_spec)
+ self.state.spec = new_spec
+ unit.status = ActiveStatus("ready")
+
+ def make_pod_spec(self):
+ config = self.framework.model.config
+
+ ports = [
+ {"name": "port", "containerPort": config["port"], "protocol": "TCP", },
+ ]
+
+ config_spec = {
+ "OSMPLA_MESSAGE_DRIVER": "kafka",
+ "OSMPLA_MESSAGE_HOST": self.state.kafka_host,
+ "OSMPLA_MESSAGE_PORT": self.state.kafka_port,
+ "OSMPLA_DATABASE_DRIVER": "mongo",
+ "OSMPLA_DATABASE_URI": self.state.mongodb_uri,
+ "OSMPLA_GLOBAL_LOG_LEVEL": config["log_level"],
+ "OSMPLA_DATABASE_COMMONKEY": config["database_common_key"],
+ }
+
+ spec = {
+ "version": 2,
+ "containers": [
+ {
+ "name": self.framework.model.app.name,
+ "image": config["image"],
+ "ports": ports,
+ "config": config_spec,
+ }
+ ],
+ }
+
+ return spec
+
+ def on_config_changed(self, event):
+ """Handle changes in configuration"""
+ self._apply_spec()
+
+ def on_start(self, event):
+ """Called when the charm is being installed"""
+ self._apply_spec()
+
+ def on_upgrade_charm(self, event):
+ """Upgrade the charm."""
+ unit = self.model.unit
+ unit.status = MaintenanceStatus("Upgrading charm")
+ self.on_start(event)
+
+ def on_kafka_relation_changed(self, event):
+ unit = self.model.unit
+ if not unit.is_leader():
+ return
+ self.state.kafka_host = event.relation.data[event.unit].get("host")
+ self.state.kafka_port = event.relation.data[event.unit].get("port")
+ self._apply_spec()
+
+ def on_mongo_relation_changed(self, event):
+ unit = self.model.unit
+ if not unit.is_leader():
+ return
+ self.state.mongodb_uri = event.relation.data[event.unit].get(
+ "connection_string"
+ )
+ self._apply_spec()
+
+
+if __name__ == "__main__":
+ main(PLACharm)
--- /dev/null
+# Copyright 2020 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.
+
+[tox]
+envlist = pep8
+skipsdist = True
+
+[testenv]
+setenv = VIRTUAL_ENV={envdir}
+ PYTHONHASHSEED=0
+whitelist_externals = juju
+passenv = HOME TERM CS_API_* OS_* AMULET_*
+deps = -r{toxinidir}/test-requirements.txt
+install_command =
+ pip install {opts} {packages}
+
+[testenv:black]
+basepython = python3
+deps =
+ black
+ yamllint
+commands =
+ black --check --diff src
+ yamllint .
+
+[testenv:pep8]
+basepython = python3
+deps=charm-tools
+commands = charm-proof
+
+[testenv:func-noop]
+basepython = python3
+commands =
+ true
+
+[testenv:func]
+basepython = python3
+commands = functest-run-suite
+
+[testenv:func-smoke]
+basepython = python3
+commands = functest-run-suite --keep-model --smoke
+
+[testenv:venv]
+commands = {posargs}
# See the License for the specific language governing permissions and
# limitations under the License.
version: 2
-service:
- scalePolicy: serial
containers:
- name: %(name)s
image: %(docker_image)s
# echo $BUNDLE $KUBECONFIG $LXDENDPOINT
}
+
function install_snaps(){
- sudo snap install juju --classic --channel=2.7/stable
- [ ! -v KUBECFG ] && sudo snap install microk8s --classic && sudo usermod -a -G microk8s `whoami` && mkdir -p ~/.kube && sudo chown -f -R `whoami` ~/.kube
+ if [ ! -v KUBECFG ]; then
+ sudo snap install microk8s --classic
+ sudo usermod -a -G microk8s `whoami`
+ mkdir -p ~/.kube
+ sudo chown -f -R `whoami` ~/.kube
+ KUBEGRP="microk8s"
+ else
+ KUBECTL="kubectl"
+ sudo snap install kubectl --classic
+ export KUBECONFIG=${KUBECFG}
+ KUBEGRP=$(id -g -n)
+ fi
+ sudo snap install juju --classic --channel=2.8/stable
}
function bootstrap_k8s_lxd(){
[ -v CONTROLLER ] && ADD_K8S_OPTS="--controller ${CONTROLLER}" && CONTROLLER_NAME=$CONTROLLER
- [ ! -v CONTROLLER ] && ADD_K8S_OPTS="--client" && BOOTSTRAP_NEEDED="yes" && CONTROLLER_NAME="controller"
+ [ ! -v CONTROLLER ] && ADD_K8S_OPTS="--client" && BOOTSTRAP_NEEDED="yes" && CONTROLLER_NAME="osm-vca"
+
+ if [ -v BOOTSTRAP_NEEDED ]; then
+ CONTROLLER_PRESENT=$(juju controllers 2>/dev/null| grep ${CONTROLLER_NAME} | wc -l)
+ if [ $CONTROLLER_PRESENT -ge 1 ]; then
+ cat << EOF
+Threre is already a VCA present with the installer reserved name of "${CONTROLLER_NAME}".
+You may either explicitly use this VCA with the "--vca ${CONTROLLER_NAME}" option, or remove it
+using this command:
+
+ juju destroy-controller --release-storage --destroy-all-models -y ${CONTROLLER_NAME}
+
+Please retry the installation once this conflict has been resolved.
+EOF
+ exit 1
+ fi
+ fi
if [ -v KUBECFG ]; then
cat $KUBECFG | juju add-k8s $K8S_CLOUD_NAME $ADD_K8S_OPTS
[ -v BOOTSTRAP_NEEDED ] && juju bootstrap $K8S_CLOUD_NAME $CONTROLLER_NAME --config controller-service-type=loadbalancer
else
- sg microk8s -c "echo ${DEFAULT_IP}-${DEFAULT_IP} | microk8s.enable metallb"
- sg microk8s -c "microk8s.enable storage dns"
+ sg ${KUBEGRP} -c "echo ${DEFAULT_IP}-${DEFAULT_IP} | microk8s.enable metallb"
+ sg ${KUBEGRP} -c "microk8s.enable storage dns"
+ TIME_TO_WAIT=30
+ start_time="$(date -u +%s)"
while true
do
- sg microk8s -c "microk8s.status" | grep 'storage: enabled'
- if [ $? -eq 0 ]; then
+ now="$(date -u +%s)"
+ if [[ $(( now - start_time )) -gt $TIME_TO_WAIT ]];then
+ echo "Microk8s storage failed to enable"
+ sg ${KUBEGRP} -c "microk8s.status"
+ exit 1
+ fi
+ storage_status=`sg ${KUBEGRP} -c "microk8s.status -a storage"`
+ if [[ $storage_status == "enabled" ]]; then
break
fi
sleep 1
done
- [ ! -v BOOTSTRAP_NEEDED ] && sg microk8s -c "microk8s.config" | juju add-k8s $K8S_CLOUD_NAME $ADD_K8S_OPTS
- [ -v BOOTSTRAP_NEEDED ] && sg microk8s -c "juju bootstrap microk8s $CONTROLLER_NAME --config controller-service-type=loadbalancer" && K8S_CLOUD_NAME=microk8s
+ [ ! -v BOOTSTRAP_NEEDED ] && sg ${KUBEGRP} -c "microk8s.config" | juju add-k8s $K8S_CLOUD_NAME $ADD_K8S_OPTS
+ [ -v BOOTSTRAP_NEEDED ] && sg ${KUBEGRP} -c "juju bootstrap microk8s $CONTROLLER_NAME --config controller-service-type=loadbalancer" && K8S_CLOUD_NAME=microk8s
fi
if [ -v LXD_CLOUD ]; then
juju add-cloud -c $CONTROLLER_NAME lxd-cloud $LXD_CLOUD --force
juju add-credential -c $CONTROLLER_NAME lxd-cloud -f $LXD_CREDENTIALS
sg lxd -c "lxd waitready"
- juju add-model test lxd-cloud || true
+ #juju add-model test lxd-cloud || true
+ juju controller-config features=[k8s-operators]
+}
+
+function wait_for_port(){
+ SERVICE=$1
+ INDEX=$2
+ TIME_TO_WAIT=30
+ start_time="$(date -u +%s)"
+ while true
+ do
+ now="$(date -u +%s)"
+ if [[ $(( now - start_time )) -gt $TIME_TO_WAIT ]];then
+ echo "Failed to expose external ${SERVICE} interface port"
+ exit 1
+ fi
+
+ if [ $(sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq -r '.items[$INDEX].metadata.name'") == ${SERVICE} ] ; then
+ break
+ fi
+ sleep 1
+ done
}
function deploy_charmed_osm(){
if [ -v KUBECFG ]; then
juju add-model osm $K8S_CLOUD_NAME
else
- sg microk8s -c "juju add-model osm $K8S_CLOUD_NAME"
+ sg ${KUBEGRP} -c "juju add-model osm $K8S_CLOUD_NAME"
fi
echo "Deploying OSM with charms"
- # echo $BUNDLE
+ images_overlay=""
+ [ -v TAG ] && generate_images_overlay && images_overlay="--overlay $IMAGES_OVERLAY_FILE"
if [ -v BUNDLE ]; then
- juju deploy $BUNDLE --overlay ~/.osm/vca-overlay.yaml
+ juju deploy $BUNDLE --overlay ~/.osm/vca-overlay.yaml $images_overlay
else
- images_overlay=""
- [ -v TAG ] && generate_images_overlay && images_overlay="--overlay $IMAGES_OVERLAY_FILE"
juju deploy cs:osm --overlay ~/.osm/vca-overlay.yaml $images_overlay
fi
+
echo "Waiting for deployment to finish..."
- check_osm_deployed &> /dev/null
+ check_osm_deployed
echo "OSM with charms deployed"
- sg microk8s -c "microk8s.enable ingress"
- juju config ui-k8s juju-external-hostname=osm.$DEFAULT_IP.xip.io
+ if [ ! -v KUBECFG ]; then
+ sg ${KUBEGRP} -c "microk8s.enable ingress"
+ API_SERVER=${DEFAULT_IP}
+ else
+ API_SERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
+ proto="$(echo $API_SERVER | grep :// | sed -e's,^\(.*://\).*,\1,g')"
+ url="$(echo ${API_SERVER/$proto/})"
+ user="$(echo $url | grep @ | cut -d@ -f1)"
+ hostport="$(echo ${url/$user@/} | cut -d/ -f1)"
+ API_SERVER="$(echo $hostport | sed -e 's,:.*,,g')"
+ fi
+
+ juju config nbi-k8s juju-external-hostname=nbi.${API_SERVER}.xip.io
+ juju expose nbi-k8s
+
+ wait_for_port nbi-k8s 0
+ sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[0].metadata.annotations += {\"nginx.ingress.kubernetes.io/backend-protocol\": \"HTTPS\"}' | ${KUBECTL} --validate=false replace -f -"
+ sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[0].metadata.annotations += {\"nginx.ingress.kubernetes.io/proxy-body-size\": \"0\"}' | ${KUBECTL} replace -f -"
+
+ juju config ng-ui juju-external-hostname=ui.${API_SERVER}.xip.io
+ juju expose ng-ui
+
+ wait_for_port ng-ui 1
+ sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[2].metadata.annotations += {\"nginx.ingress.kubernetes.io/proxy-body-size\": \"0\"}' | ${KUBECTL} --validate=false replace -f -"
+
+ juju config ui-k8s juju-external-hostname=osm.${API_SERVER}.xip.io
juju expose ui-k8s
+
+ wait_for_port ui-k8s 2
+ sg ${KUBEGRP} -c "${KUBECTL} get ingress -n osm -o json | jq '.items[1].metadata.annotations += {\"nginx.ingress.kubernetes.io/proxy-body-size\": \"0\"}' | ${KUBECTL} --validate=false replace -f -"
}
function check_osm_deployed() {
+ TIME_TO_WAIT=600
+ start_time="$(date -u +%s)"
+ total_service_count=14
while true
do
- pod_name=`sg microk8s -c "microk8s.kubectl -n osm get pods | grep ui-k8s | grep -v operator" | awk '{print $1; exit}'`
-
- if [[ `sg microk8s -c "microk8s.kubectl -n osm wait pod $pod_name --for condition=Ready"` ]]; then
- if [[ `sg microk8s -c "microk8s.kubectl -n osm wait pod lcm-k8s-0 --for condition=Ready"` ]]; then
- break
- fi
+ service_count=$(juju status | grep kubernetes | grep active | wc -l)
+ echo "$service_count / $total_service_count services active"
+ if [ $service_count -eq $total_service_count ]; then
+ break
+ fi
+ now="$(date -u +%s)"
+ if [[ $(( now - start_time )) -gt $TIME_TO_WAIT ]];then
+ echo "Timed out waiting for OSM services to become ready"
+ exit 1
fi
sleep 10
done
# Calculate the default route of this machine
local DEFAULT_IF=`ip route list match 0.0.0.0 | awk '{print $5}'`
- local vca_apiproxy=`ip -o -4 a |grep ${DEFAULT_IF}|awk '{split($4,a,"/"); print a[1]}'`
# Generate a new overlay.yaml, overriding any existing one
cat << EOF > /tmp/vca-overlay.yaml
vca_port: $vca_port
vca_pubkey: $vca_pubkey
vca_cacert: $vca_cacert
- vca_apiproxy: $vca_apiproxy
vca_cloud: $vca_cloud
+ vca_k8s_cloud: $K8S_CLOUD_NAME
mon-k8s:
options:
vca_user: $vca_user
ui-k8s:
options:
image: opensourcemano/light-ui:$TAG
+ pla:
+ options:
+ image: opensourcemano/pla:$TAG
+ ng-ui:
+ options:
+ image: opensourcemano/ng-ui:$TAG
EOF
mv /tmp/images-overlay.yaml $IMAGES_OVERLAY_FILE
check_arguments $@
mkdir -p ~/.osm
install_snaps
-sleep 5
bootstrap_k8s_lxd
deploy_charmed_osm
install_osmclient
if [ -v MICROSTACK ]; then
install_microstack
fi
+
+echo "Your installation is now complete, follow these steps for configuring the osmclient:"
+echo
+echo "1. Create the OSM_HOSTNAME environment variable with the NBI IP"
+echo
+echo "export OSM_HOSTNAME=nbi.$API_SERVER.xip.io:443"
+echo
+echo "2. Add the previous command to your .bashrc for other Shell sessions"
+echo
+echo "echo \"export OSM_HOSTNAME=nbi.$API_SERVER.xip.io:443\" >> ~/.bashrc"
+echo
+echo "DONE"
#
-juju destroy-model osm --destroy-storage -y
-juju destroy-model test --destroy-storage -y
+juju destroy-model osm --destroy-storage -y --force --no-wait
sudo snap unalias osm
sudo snap remove osmclient
+CONTROLLER_NAME="osm-vca"
+CONTROLLER_PRESENT=$(juju controllers 2>/dev/null| grep ${CONTROLLER_NAME} | wc -l)
+if [[ $CONTROLLER_PRESENT -ge 1 ]]; then
+ cat << EOF
+The VCA with the name "${CONTROLLER_NAME}" has been left in place to ensure that no other
+applications are using it. If you are sure you wish to remove this controller,
+please execute the following command:
+
+ juju destroy-controller --release-storage --destroy-all-models -y ${CONTROLLER_NAME}
+
+EOF
+fi
--- /dev/null
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+########################################################################
+
+version: '3'
+networks:
+ netOSM:
+ external:
+ name: ${OSM_NETWORK:-netosm}
+ #driver: overlay
+ #driver_opts:
+ # com.docker.network.driver.mtu: "1446"
+services:
+ light-ui:
+ image: ${DOCKER_USER:-opensourcemano}/light-ui:${TAG:-8}
+ networks:
+ - netOSM
+ environment:
+ OSM_SERVER: nbi
+ #depends_on:
+ # - nbi
+ env_file:
+ - ./lwui.env
+ ports:
+ - "${OSM_UI_PORTS:-80:80}"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
+
##
-# Copyright 2019 ETSI
+# Copyright 2019-2020 ETSI
#
# 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
########################################################################
version: '3'
-volumes:
- ro:
- ro_db:
- mongo_db:
- mon_db:
- pol_db:
- osm_packages:
- prom_db:
networks:
netOSM:
external:
#driver_opts:
# com.docker.network.driver.mtu: "1446"
services:
- zookeeper:
- image: wurstmeister/zookeeper:${ZOOKEEPER_TAG:-latest}
-# ports:
-# - "2181:2181"
- networks:
- - netOSM
- healthcheck:
- test: echo stat | nc localhost 2181
- interval: 10s
- timeout: 10s
- retries: 3
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- kafka:
- image: wurstmeister/kafka:${KAFKA_TAG:-latest}
- ports:
- - "9092"
- networks:
- - netOSM
- environment:
- KAFKA_ADVERTISED_HOST_NAME: kafka
- KAFKA_ADVERTISED_PORT: 9092
- KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
- KAFKA_LOG_RETENTION_HOURS: 24
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock
- healthcheck:
- test: zookeeper-shell.sh zookeeper:2181 ls /brokers/ids 2>&1 | grep "Node does not exist" && exit 1 || exit 0
- interval: 20s
- timeout: 10s
- retries: 5
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- #depends_on:
- # - zookeeper
- mongo:
- image: mongo
-# ports:
-# - "27017:27017"
- networks:
- - netOSM
- volumes:
- - mongo_db:/data/db
- prometheus:
- image: prom/prometheus:${PROMETHEUS_TAG:-latest}
- hostname: prometheus
- ports:
- - "${OSM_PROM_PORTS:-9091:9090}"
- volumes:
- - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- - prom_db:/prometheus
- networks:
- - netOSM
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- prometheus-cadvisor:
- image: google/cadvisor:${PROMETHEUS_CADVISOR_TAG:-latest}
- ports:
- - "${OSM_PROM_CADVISOR_PORTS:-8080:8080}"
- volumes:
- - /:/rootfs:ro
- - /var/run:/var/run:ro
- - /sys:/sys:ro
- - /var/lib/docker/:/var/lib/docker:ro
- - /dev/disk/:/dev/disk:ro
- networks:
- - netOSM
- keystone:
- image: ${DOCKER_USER:-opensourcemano}/keystone:${TAG:-8}
- networks:
- - netOSM
- environment:
- DB_HOST: mysql
- env_file:
- - ./keystone.env
- ports:
- - "${OSM_KEYSTONE_PORTS:-5000:5000}"
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- nbi:
- image: ${DOCKER_USER:-opensourcemano}/nbi:${TAG:-8}
- networks:
- - netOSM
- volumes:
- - osm_packages:/app/storage
- environment:
- OSMNBI_DATABASE_HOST: mongo
- OSMNBI_MESSAGE_HOST: kafka
- env_file:
- - ./nbi.env
- ports:
- - "${OSM_NBI_PORTS:-9999:9999}"
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- #depends_on:
- # - kafka
- # - mongo
- lcm:
- image: ${DOCKER_USER:-opensourcemano}/lcm:${TAG:-8}
- networks:
- - netOSM
- volumes:
- - osm_packages:/app/storage
- environment:
- OSMLCM_RO_HOST: ro
- OSMLCM_DATABASE_HOST: mongo
- OSMLCM_MESSAGE_HOST: kafka
- env_file:
- - ./lcm.env
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- #depends_on:
- # - kafka
- # - mongo
- # - ro
- mysql:
- image: mysql:5
- networks:
- netOSM:
- aliases:
- - ro-db
- volumes:
- - ro_db:/var/lib/mysql
- env_file:
- - ./ro-db.env
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
-# ports:
-# - "3306:3306"
- ro:
- image: ${DOCKER_USER:-opensourcemano}/ro:${TAG:-8}
- networks:
- - netOSM
- environment:
- RO_DB_HOST: mysql
- env_file:
- - ./ro.env
- #depends_on:
- # - mysql
- volumes:
- - ro:/var/log/osm
- ports:
- - "${OSM_RO_PORTS:-9090:9090}"
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
- mon:
- image: ${DOCKER_USER:-opensourcemano}/mon:${TAG:-8}
- networks:
- - netOSM
- volumes:
- - mon_db:/app/database
- environment:
- OSMMON_MESSAGE_HOST: kafka
- OSMMON_MESSAGE_PORT: 9092
- env_file:
- - ./mon.env
- ports:
- - "${OSM_MON_PORTS:-8662:8662}"
- #depends_on:
- # - kafka
- logging:
- driver: "json-file"
- options:
- max-file: 5
- max-size: 10m
- pol:
- image: ${DOCKER_USER:-opensourcemano}/pol:${TAG:-8}
- networks:
- - netOSM
- volumes:
- - pol_db:/app/database
- environment:
- OSMPOL_MESSAGE_HOST: kafka
- OSMPOL_MESSAGE_PORT: 9092
- env_file:
- - ./pol.env
- #depends_on:
- # - kafka
- # - mon
- logging:
- driver: "json-file"
- options:
- max-file: 5
- max-size: 10m
ng-ui:
image: ${DOCKER_USER:-opensourcemano}/ng-ui:${TAG:-8}
networks:
- netOSM
- #depends_on:
- # - nbi
ports:
- "${OSM_UI_PORTS:-80:80}"
logging:
options:
max-size: "100m"
max-file: "2"
- grafana:
- image: grafana/grafana
- volumes:
- - ./files/dashboards-osm.yml:/etc/grafana/provisioning/dashboards/dashboards-osm.yml
- - ./files/osm-sample-dashboard.json:/etc/grafana/provisioning/dashboards/osm-sample-dashboard.json
- - ./files/osm-system-dashboard.json:/etc/grafana/provisioning/dashboards/osm-system-dashboard.json
- - ./files/datasource-prometheus.yml:/etc/grafana/provisioning/datasources/datasource-prometheus.yml
- hostname: grafana
- ports:
- - "${OSM_GRAFANA_PORTS:-3000:3000}"
- networks:
- - netOSM
- logging:
- driver: "json-file"
- options:
- max-size: "100m"
- max-file: "2"
########################################################################
version: '3'
+networks:
+ netOSM:
+ external:
+ name: ${OSM_NETWORK:-netosm}
+ #driver: overlay
+ #driver_opts:
+ # com.docker.network.driver.mtu: "1446"
services:
pla:
- image: ${DOCKER_USER:-opensourcemano}/pla:${TAG:-7}
+ image: ${DOCKER_USER:-opensourcemano}/pla:${TAG:-8}
networks:
- netOSM
logging:
fi
remove_k8s_namespace $OSM_STACK_NAME
else
-
remove_stack $OSM_STACK_NAME
remove_stack osm_elk
fi
newgrp docker << EONG
docker image rm ${DOCKER_USER}/ro:${OSM_DOCKER_TAG}
docker image rm ${DOCKER_USER}/lcm:${OSM_DOCKER_TAG}
- docker image rm ${DOCKER_USER}/light-ui:${OSM_DOCKER_TAG}
docker image rm ${DOCKER_USER}/keystone:${OSM_DOCKER_TAG}
docker image rm ${DOCKER_USER}/nbi:${OSM_DOCKER_TAG}
docker image rm ${DOCKER_USER}/mon:${OSM_DOCKER_TAG}
EONG
if [ -n "$NGUI" ]; then
- newgrp docker << EONG
- docker image rm ${DOCKER_USER}/ng-ui:${OSM_DOCKER_TAG}
-EONG
+ sg docker -c "docker image rm ${DOCKER_USER}/ng-ui:${OSM_DOCKER_TAG}"
else
- newgrp docker << EONG
- docker image rm ${DOCKER_USER}/light-ui:${OSM_DOCKER_TAG}
-EONG
- fi
+ sg docker -c "docker image rm ${DOCKER_USER}/light-ui:${OSM_DOCKER_TAG}"
+ fi
if [ -n "$KUBERNETES" ]; then
OSM_NAMESPACE_VOL="${OSM_HOST_VOL}/${OSM_STACK_NAME}"
[ -z "$CONTROLLER_NAME" ] && sg lxd -c "juju destroy-controller --destroy-all-models --yes $OSM_STACK_NAME"
fi
remove_crontab_job
- uninstall_osmclient
+ [ -z "$INSTALL_NOHOSTCLIENT" ] && uninstall_osmclient
echo "Some docker images will be kept in case they are used by other docker stacks"
echo "To remove them, just run 'docker image prune' in a terminal"
return 0
#Safe unattended install of iptables-persistent
function check_install_iptables_persistent(){
echo -e "\nChecking required packages: iptables-persistent"
- if dpkg -l iptables-persistent &>/dev/null; then
+ if ! dpkg -l iptables-persistent &>/dev/null; then
echo -e " Not installed.\nInstalling iptables-persistent requires root privileges"
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
function install_juju() {
echo "Installing juju"
- sudo snap install juju --classic --channel=2.7/stable
+ sudo snap install juju --classic --channel=2.8/stable
[[ ":$PATH": != *":/snap/bin:"* ]] && PATH="/snap/bin:${PATH}"
update_juju_images
echo "Finished installation of juju"
sg lxd -c "juju bootstrap --bootstrap-series=xenial $OSM_VCA_CLOUDNAME $OSM_STACK_NAME"
fi
[ $(juju controllers | awk "/^${OSM_STACK_NAME}[\*| ]/{print $1}"|wc -l) -eq 1 ] || FATAL "Juju installation failed"
+ juju controller-config features=[k8s-operators]
+}
+
+function juju_addk8s() {
+ cat $HOME/.kube/config | juju add-k8s $OSM_VCA_K8S_CLOUDNAME --controller $OSM_STACK_NAME --storage openebs-hostpath
}
function juju_createproxy() {
fi
}
+function generate_docker_compose_files() {
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
+ if [ -n "$NGUI" ]; then
+ # For NG-UI
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose-ngui.yaml $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml
+ else
+ # Docker-compose
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose-lightui.yaml $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml
+ fi
+ if [ -n "$INSTALL_PLA" ]; then
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_pla/docker-compose.yaml $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml
+ fi
+}
+
+function generate_k8s_manifest_files() {
+ #Kubernetes resources
+ $WORKDIR_SUDO cp -bR ${OSM_DEVOPS}/installers/docker/osm_pods $OSM_DOCKER_WORK_DIR
+ if [ -n "$NGUI" ]; then
+ $WORKDIR_SUDO rm -f $OSM_K8S_WORK_DIR/light-ui.yaml
+ else
+ $WORKDIR_SUDO rm -f $OSM_K8S_WORK_DIR/ng-ui.yaml
+ fi
+}
+
+function generate_prometheus_grafana_files() {
+ [ -n "$KUBERNETES" ] && return
+ # Prometheus files
+ $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus/prometheus.yml $OSM_DOCKER_WORK_DIR/prometheus/prometheus.yml
+
+ # Grafana files
+ $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/grafana
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/dashboards-osm.yml $OSM_DOCKER_WORK_DIR/grafana/dashboards-osm.yml
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/datasource-prometheus.yml $OSM_DOCKER_WORK_DIR/grafana/datasource-prometheus.yml
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-sample-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-sample-dashboard.json
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-system-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-system-dashboard.json
+
+ # Prometheus Exporters files
+ $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus_exporters
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus_exporters/node_exporter.service $OSM_DOCKER_WORK_DIR/prometheus_exporters/node_exporter.service
+}
+
function generate_docker_env_files() {
echo "Doing a backup of existing env files"
$WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/keystone-db.env{,~}
$WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/ro.env{,~}
echo "Generating docker env files"
- if [ -n "$KUBERNETES" ]; then
- #Kubernetes resources
- $WORKDIR_SUDO cp -bR ${OSM_DEVOPS}/installers/docker/osm_pods $OSM_DOCKER_WORK_DIR
- [ -n "$NGUI" ] && $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_pods/ng-ui.yaml $OSM_K8S_WORK_DIR/ng-ui.yaml && $WORKDIR_SUDO rm $OSM_K8S_WORK_DIR/light-ui.yaml
- else
- if [ -n "$NGUI" ]; then
- # For NG-UI
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose-ngui.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
- else
- # Docker-compose
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
- fi
- if [ -n "$INSTALL_PLA" ]; then
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_pla/docker-compose.yaml $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml
- fi
-
- # Prometheus files
- $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus/prometheus.yml $OSM_DOCKER_WORK_DIR/prometheus/prometheus.yml
-
- # Grafana files
- $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/grafana
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/dashboards-osm.yml $OSM_DOCKER_WORK_DIR/grafana/dashboards-osm.yml
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/datasource-prometheus.yml $OSM_DOCKER_WORK_DIR/grafana/datasource-prometheus.yml
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-sample-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-sample-dashboard.json
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/grafana/osm-system-dashboard.json $OSM_DOCKER_WORK_DIR/grafana/osm-system-dashboard.json
-
- # Prometheus Exporters files
- $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/prometheus_exporters
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus_exporters/node_exporter.service $OSM_DOCKER_WORK_DIR/prometheus_exporters/node_exporter.service
- fi
-
# LCM
if [ ! -f $OSM_DOCKER_WORK_DIR/lcm.env ]; then
echo "OSMLCM_DATABASE_COMMONKEY=${OSM_DATABASE_COMMONKEY}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
$WORKDIR_SUDO sed -i "s|OSMLCM_VCA_CLOUD.*|OSMLCM_VCA_CLOUD=${OSM_VCA_CLOUDNAME}|g" $OSM_DOCKER_WORK_DIR/lcm.env
fi
+ if ! grep -Fq "OSMLCM_VCA_K8S_CLOUD" $OSM_DOCKER_WORK_DIR/lcm.env; then
+ echo "OSMLCM_VCA_K8S_CLOUD=${OSM_VCA_K8S_CLOUDNAME}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
+ else
+ $WORKDIR_SUDO sed -i "s|OSMLCM_VCA_K8S_CLOUD.*|OSMLCM_VCA_K8S_CLOUD=${OSM_VCA_K8S_CLOUDNAME}|g" $OSM_DOCKER_WORK_DIR/lcm.env
+ fi
+
# RO
MYSQL_ROOT_PASSWORD=$(generate_secret)
if [ ! -f $OSM_DOCKER_WORK_DIR/ro-db.env ]; then
sudo chown $(id -u):$(id -g) $HOME/.kube/config
}
+function install_k8s_storageclass() {
+ kubectl apply -f https://openebs.github.io/charts/openebs-operator-1.6.0.yaml
+ local storageclass_timeout=300
+ local counter=0
+ echo "Waiting for storageclass"
+ while (( counter < storageclass_timeout ))
+ do
+ kubectl get storageclass openebs-hostpath &> /dev/null
+
+ if [ $? -eq 0 ] ; then
+ echo "Storageclass available"
+ break
+ else
+ counter=$((counter + 15))
+ sleep 15
+ fi
+ done
+ kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
+}
+
#deploys flannel as daemonsets
function deploy_cni_provider() {
CNI_DIR="$(mktemp -d -q --tmpdir "flannel.XXXXXX")"
}
function deploy_osm_pla_service() {
- # corresponding to parse_yaml
- [ ! $OSM_DOCKER_TAG == "7" ] && $WORKDIR_SUDO sed -i "s/opensourcemano\/pla:.*/opensourcemano\/pla:$OSM_DOCKER_TAG/g" $OSM_DOCKER_WORK_DIR/osm_pla/pla.yaml
# corresponding to namespace_vol
$WORKDIR_SUDO sed -i "s#path: /var/lib/osm#path: $OSM_NAMESPACE_VOL#g" $OSM_DOCKER_WORK_DIR/osm_pla/pla.yaml
# corresponding to deploy_osm_services
helm > /dev/null 2>&1
if [ $? != 0 ] ; then
# Helm is not installed. Install helm
+ echo "Helm is not installed, installing ..."
curl https://get.helm.sh/helm-v2.15.2-linux-amd64.tar.gz --output helm-v2.15.2.tar.gz
tar -zxvf helm-v2.15.2.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
helm init --service-account tiller
# Wait for Tiller to be up and running. If timeout expires, continue installing
- tiller_timeout=120; counter=0
+ tiller_timeout=120;
+ counter=0;
+ tiller_status=""
while (( counter < tiller_timeout ))
do
tiller_status=`kubectl -n kube-system get deployment.apps/tiller-deploy --no-headers | awk '{print $2'}`
- ( [ ! -z "$tiller_status" ] && [ $tiller_status == "1/1" ] ) && break
- num=$((counter + 2))
- sleep 2
+ ( [ ! -z "$tiller_status" ] && [ $tiller_status == "1/1" ] ) && echo "Tiller ready" && break
+ counter=$((counter + 5))
+ sleep 5
done
+ [ "$tiller_status" != "1/1" ] && echo "Tiller is NOT READY YET. Installation will continue"
fi
}
for osm in $osm_services; do
$WORKDIR_SUDO sed -i "s/opensourcemano\/$osm:.*/$DOCKER_USER\/$osm:$TAG/g" $OSM_K8S_WORK_DIR/$osm.yaml
done
+ $WORKDIR_SUDO sed -i "s/opensourcemano\/pla:.*/$DOCKER_USER\/\/pla:$OSM_DOCKER_TAG/g" $OSM_DOCKER_WORK_DIR/osm_pla/pla.yaml
}
function namespace_vol() {
pushd $OSM_DOCKER_WORK_DIR
if [ -n "$INSTALL_PLA" ]; then
- sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml -c $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml $OSM_STACK_NAME"
+ track deploy_osm_pla
+ sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml -c $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml -c $OSM_DOCKER_WORK_DIR/osm_pla/docker-compose.yaml $OSM_STACK_NAME"
else
- sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml $OSM_STACK_NAME"
+ sg docker -c ". ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml -c $OSM_DOCKER_WORK_DIR/docker-compose-ui.yaml $OSM_STACK_NAME"
fi
popd
}
function install_lightweight() {
- [ "${OSM_STACK_NAME}" == "osm" ] || OSM_DOCKER_WORK_DIR="$OSM_WORK_DIR/stack/$OSM_STACK_NAME"
- [ -n "$KUBERNETES" ] && OSM_K8S_WORK_DIR="$OSM_DOCKER_WORK_DIR/osm_pods" && OSM_NAMESPACE_VOL="${OSM_HOST_VOL}/${OSM_STACK_NAME}"
- [ ! -d "$OSM_DOCKER_WORK_DIR" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR
- [ ! -d "$OSM_DOCKER_WORK_DIR/osm_pla" -a -n "$INSTALL_PLA" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/osm_pla
- [ -n "$KUBERNETES" ] && $WORKDIR_SUDO cp -b $OSM_DEVOPS/installers/docker/cluster-config.yaml $OSM_DOCKER_WORK_DIR/cluster-config.yaml
-
track checkingroot
[ "$USER" == "root" ] && FATAL "You are running the installer as root. The installer is prepared to be executed as a normal user with sudo privileges."
track noroot
[ -n "$INSTALL_NODOCKER" ] || install_docker_ce
track docker_ce
+ echo "Creating folders for installation"
+ [ ! -d "$OSM_DOCKER_WORK_DIR" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR
+ [ ! -d "$OSM_DOCKER_WORK_DIR/osm_pla" -a -n "$INSTALL_PLA" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/osm_pla
+ [ -n "$KUBERNETES" ] && $WORKDIR_SUDO cp -b $OSM_DEVOPS/installers/docker/cluster-config.yaml $OSM_DOCKER_WORK_DIR/cluster-config.yaml
+
#Installs Kubernetes and deploys osm services
if [ -n "$KUBERNETES" ]; then
install_kube
[ -z "$DOCKER_NOBUILD" ] && generate_docker_images
track docker_build
+ if [ -n "$KUBERNETES" ]; then
+ generate_k8s_manifest_files
+ else
+ generate_docker_compose_files
+ fi
+ track manifest_files
+ generate_prometheus_grafana_files
generate_docker_env_files
+ track env_files
if [ -n "$KUBERNETES" ]; then
if [ -n "$INSTALL_K8S_MONITOR" ]; then
remove_k8s_namespace $OSM_STACK_NAME
deploy_cni_provider
kube_secrets
- [ ! $OSM_DOCKER_TAG == "7" ] && parse_yaml $OSM_DOCKER_TAG
+ [ ! $OSM_DOCKER_TAG == "8" ] && parse_yaml $OSM_DOCKER_TAG
namespace_vol
taint_master_node
deploy_osm_services
if [ -n "$INSTALL_PLA"]; then
# optional PLA install
deploy_osm_pla_service
+ track deploy_osm_pla
fi
track deploy_osm_services_k8s
install_k8s_storageclass
[ -z "$INSTALL_NOHOSTCLIENT" ] && install_osmclient
track osmclient
-
+
echo -e "Checking OSM health state..."
if [ -n "$KUBERNETES" ]; then
$OSM_DEVOPS/installers/osm_health.sh -s ${OSM_STACK_NAME} -k || \
[ -n "$KUBERNETES" ] && add_local_k8scluster
track add_local_k8scluster
-
wget -q -O- https://osm-download.etsi.org/ftp/osm-8.0-eight/README2.txt &> /dev/null
track end
return 0
OSM_VCA_SECRET=
OSM_VCA_PUBKEY=
OSM_VCA_CLOUDNAME="localhost"
+OSM_VCA_K8S_CLOUDNAME="k8scloud"
OSM_STACK_NAME=osm
NO_HOST_PORTS=""
DOCKER_NOBUILD=""
${OSM_DEVOPS}/installers/charmed_uninstall.sh -R $RELEASE -r $REPOSITORY -u $REPOSITORY_BASE -D /usr/share/osm-devops -t $DOCKER_TAG "$@"
else
${OSM_DEVOPS}/installers/charmed_install.sh -R $RELEASE -r $REPOSITORY -u $REPOSITORY_BASE -D /usr/share/osm-devops -t $DOCKER_TAG "$@"
-
- echo "Your installation is now complete, follow these steps for configuring the osmclient:"
- echo
- echo "1. Get the NBI IP with the following command:"
- echo
- echo NBI_IP='`juju status --format json | jq -rc '"'"'.applications."nbi-k8s".address'"'"'`'
- echo
- echo "2. Create the OSM_HOSTNAME environment variable with the NBI IP"
- echo
- echo "export OSM_HOSTNAME=\$NBI_IP"
- echo
- echo "3. Add the previous command to your .bashrc for other Shell sessions"
- echo
- echo "echo \"export OSM_HOSTNAME=\$NBI_IP\" >> ~/.bashrc"
- echo
- echo "DONE"
fi
exit 0
. $OSM_DEVOPS/common/all_funcs
+[ "${OSM_STACK_NAME}" == "osm" ] || OSM_DOCKER_WORK_DIR="$OSM_WORK_DIR/stack/$OSM_STACK_NAME"
+[ -n "$KUBERNETES" ] && OSM_K8S_WORK_DIR="$OSM_DOCKER_WORK_DIR/osm_pods" && OSM_NAMESPACE_VOL="${OSM_HOST_VOL}/${OSM_STACK_NAME}"
[ -n "$INSTALL_LIGHTWEIGHT" ] && [ -n "$UNINSTALL" ] && uninstall_lightweight && echo -e "\nDONE" && exit 0
[ -n "$INSTALL_ONLY" ] && [ -n "$INSTALL_ELK" ] && deploy_elk
#[ -n "$INSTALL_ONLY" ] && [ -n "$INSTALL_PERFMON" ] && deploy_perfmon
/* Change log:
* 1. Bug 745 : Jayant Madavi, Mrityunjay Yadav : JM00553988@techmahindra.com : 23-july-2019 : Improvement to the code, typically we have 2 * or more branches whose build gets triggered, ex master & release branch, the previous code was removing any/all docker.
- * Now removing previous docker of the same branch, so that the other branch failed docker should not be removed. It also
+ * Now removing previous docker of the same branch, so that the other branch failed docker should not be removed. It also
* acts as clean-up for previous docker remove failure.
* 2. Feature 7829 : Mrityunjay Yadav, Jayant Madavi: MY00514913@techmahindra.com : 19-Aug-2019 : Added a parameters & function to invoke Robot test.
*/
if (error) {
if ( !params.SAVE_CONTAINER_ON_FAIL ) {
uninstall_osm container_name
- sh "docker stop ${http_server_name}"
- sh "docker rm ${http_server_name}"
+ sh "docker stop ${http_server_name} || true"
+ sh "docker rm ${http_server_name} || true"
}
}
else {
if ( !params.SAVE_CONTAINER_ON_PASS ) {
uninstall_osm container_name
- sh "docker stop ${http_server_name}"
- sh "docker rm ${http_server_name}"
+ sh "docker stop ${http_server_name} || true"
+ sh "docker rm ${http_server_name} || true"
}
}
}