--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+release/
+__pycache__
+.tox
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+---
+
+extends: default
+rules:
+ line-length: disable
+yaml-files:
+ - '*.yaml'
+ - '*.yml'
+ - '.yamllint'
+ignore: |
+ reactive/
+ .tox
+ release/
--- /dev/null
+<!-- 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.
+
+For those usages not covered by the Apache License, Version 2.0 please
+contact: legal@canonical.com
+
+To get in touch with the maintainers, please contact:
+osm-charmers@lists.launchpad.net -->
+
+# Overview
+
+Mongo for Juju CAAS
+
+## Actions
+
+### Backup
+
+Execute the following steps to do a backup.
+
+```bash
+$ juju run-action mongodb-k8s/0 backup --wait
+unit-mongodb-k8s-0:
+ UnitId: mongodb-k8s/0
+ id: "7"
+ results:
+ Stderr: "2020-02-26T14:13:56.448+0000\twriting admin.system.version to archive
+ '/data/backup.archive'\n2020-02-26T14:13:56.451+0000\tdone dumping admin.system.version
+ (1 document)\n"
+ copy:
+ cmd: kubectl cp mongo-ha/mongodb-k8s-0:/data/backup.archive backup.archive
+ restore:
+ cmd: kubectl cp backup.archive mongo-ha/mongodb-k8s-0:/data/backup.archive
+ juju: juju action mongodb-k8s/0 restore --wait
+ status: completed
+ timing:
+ completed: 2020-02-26 14:13:57 +0000 UTC
+ enqueued: 2020-02-26 14:13:55 +0000 UTC
+ started: 2020-02-26 14:13:56 +0000 UTC
+$ kubectl cp mongo-ha/mongodb-k8s-0:/data/backup.archive backup.archive
+```
+
+> Additional note: You can add `--string-args target=PRIMARY|SECONDARY` if you want this action to be run in a specific mongo unit. If `SECONDARY` is set, but the mongo unit isn't the `SECONDARY`, the action will fail.
+
+### Restore
+
+When the backup function is executed, you will see the commands you need to execute for restoring from a backup.
+
+```bash
+$ kubectl cp backup.archive mongo-ha/mongodb-k8s-0:/data/backup.archive
+Defaulting container name to mongodb-k8s.
+$ juju run-action mongodb-k8s/0 restore --wait
+unit-mongodb-k8s-0:
+ UnitId: mongodb-k8s/0
+ id: "8"
+ results:
+ Stderr: "2020-02-26T14:17:00.300+0000\tpreparing collections to restore from\n2020-02-26T14:17:00.312+0000\t0
+ document(s) restored successfully. 0 document(s) failed to restore.\n"
+ status: completed
+ timing:
+ completed: 2020-02-26 14:17:01 +0000 UTC
+ enqueued: 2020-02-26 14:16:57 +0000 UTC
+ started: 2020-02-26 14:17:00 +0000 UTC
+```
+
+### Remove backup
+
+When a backup is made, it is stored in the unit. To easily remove the backup, execute this action:
+
+```bash
+$ juju run-action mongodb-k8s/0 remove-backup --wait
+unit-mongodb-k8s-0:
+ UnitId: mongodb-k8s/0
+ id: "4"
+ results:
+ Stdout: |
+ Backup successfully removed!
+ status: completed
+ timing:
+ completed: 2020-02-26 16:31:11 +0000 UTC
+ enqueued: 2020-02-26 16:31:08 +0000 UTC
+ started: 2020-02-26 16:31:10 +0000 UTC
+```
+
+### Is primary?
+
+To check if the unit is primary:
+
+```bash
+$ juju run-action mongodb-k8s/0 is-primary --wait
+unit-mongodb-k8s-0:
+ UnitId: mongodb-k8s/0
+ id: "5"
+ results:
+ unit:
+ ip: 10.1.31.92
+ primary: "true"
+ status: completed
+ timing:
+ completed: 2020-02-26 16:32:10 +0000 UTC
+ enqueued: 2020-02-26 16:32:08 +0000 UTC
+ started: 2020-02-26 16:32:09 +0000 UTC
+$ juju run-action mongodb-k8s/1 is-primary --wait
+unit-mongodb-k8s-1:
+ UnitId: mongodb-k8s/1
+ id: "6"
+ results:
+ unit:
+ ip: 10.1.31.93
+ primary: "false"
+ status: completed
+ timing:
+ completed: 2020-02-26 16:32:34 +0000 UTC
+ enqueued: 2020-02-26 16:32:32 +0000 UTC
+ started: 2020-02-26 16:32:33 +0000 UTC
+```
+
+## Backup remotely
+
+If we want to perform a backup remotely, follow the next steps:
+
+```bash
+$ sudo apt install mongo-tools-y
+$ juju status mongodb-k8s
+Model Controller Cloud/Region Version SLA Timestamp
+mongo-ha microk8s-localhost microk8s/localhost 2.7.2 unsupported 16:26:02+01:00
+
+App Version Status Scale Charm Store Rev OS Address Notes
+mongodb-k8s mongo:latest active 2 mongodb-k8s local 0 kubernetes 10.152.183.90
+
+Unit Workload Agent Address Ports Message
+mongodb-k8s/0* active idle 10.1.31.75 27017/TCP ready
+mongodb-k8s/1 active idle 10.1.31.76 27017/TCP ready
+$ mongodump --host 10.152.183.90 --port 27017 --gzip --archive=backup.archive --forceTableScan
+2020-02-26T16:41:23.777+0100 writing admin.system.version to archive 'backup.archive'
+2020-02-26T16:41:23.779+0100 done dumping admin.system.version (1 document)
+$ mongorestore --host 10.152.183.90 --port 27017 --gzip --archive=backup.archive
+```
+
+## Testing
+
+The tests of this charm are done using tox and Zaza.
+
+### Prepare environment
+
+The machine in which the tests are run needs access to a juju k8s controller. The easiest way to approach this is by executing the following commands:
+
+```bash
+sudo apt install tox -y
+sudo snap install microk8s --classic
+sudo snap install juju
+
+microk8s.status --wait-ready
+microk8s.enable storage dashboard dns
+
+juju bootstrap microk8s k8s-cloud
+```
+
+### Test charm with Tox
+
+```bash
+tox -e black # Check syntax
+tox -e build # Build the charm
+tox -e func # Test charm
+```
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+backup:
+ description: "Do a mongodb backup"
+ params:
+ target:
+ description: "The unit in which it should be performed the action. (ANY, PRIMARY, SECONDARY)"
+ type: string
+ default: "ANY"
+ path:
+ description: "Path for the backup inside the unit"
+ type: string
+ default: "/data"
+restore:
+ description: "Restore from a MongoDB Backup"
+ params:
+ path:
+ description: "Path for the backup inside the unit"
+ type: string
+ default: "/data"
+remove-backup:
+ description: "Remove backup from unit"
+ params:
+ path:
+ description: "Path for the backup inside the unit"
+ type: string
+ default: "/data"
+is-primary:
+ description: "Check if the unit is the primary"
--- /dev/null
+#!/bin/bash
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+MASTER=`mongo --quiet --eval "d=db.isMaster(); print( d['ismaster'] );"`
+
+TARGET=`action-get target`
+DB_BACKUP_PATH=`action-get path`
+
+mkdir -p $DB_BACKUP_PATH
+
+if [ "$TARGET" == "SECONDARY" ]; then
+ if [ "$MASTER" == "true" ]; then
+ action-fail "This action should be run in a Secondary"
+ exit
+ fi
+elif [ "$TARGET" == "PRIMARY" ]; then
+ if [ "$MASTER" == "false" ]; then
+ action-fail "This action should be run in a Primary"
+ exit
+ fi
+fi
+
+mongodump --gzip --archive=$DB_BACKUP_PATH/backup.archive
+action-set copy.cmd="kubectl cp $JUJU_MODEL_NAME/$HOSTNAME:$DB_BACKUP_PATH/backup.archive backup.archive"
+action-set restore.cmd="kubectl cp backup.archive $JUJU_MODEL_NAME/$HOSTNAME:$DB_BACKUP_PATH/backup.archive"
+action-set restore.juju="juju run-action $JUJU_UNIT_NAME restore --wait"
+
--- /dev/null
+#!/bin/bash
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+MASTER=`mongo --quiet --eval "d=db.isMaster(); print( d['ismaster'] );"`
+action-set unit.primary=$MASTER
+action-set unit.ip=`network-get mongo --bind-address`
\ No newline at end of file
--- /dev/null
+#!/bin/bash
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+DB_BACKUP_PATH=`action-get path`
+rm $DB_BACKUP_PATH/backup.archive || exit
+echo Backup successfully removed!
--- /dev/null
+#!/bin/bash
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+DB_BACKUP_PATH=`action-get path`
+mongorestore --gzip --archive=$DB_BACKUP_PATH/backup.archive
+
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+options:
+ advertised-hostname:
+ description: MongoDB Hostname
+ type: string
+ default: mongodb-k8s
+ advertised-port:
+ description: MongoDB port
+ type: int
+ default: 27017
+ replica-set:
+ description: Mongo Replica-set name
+ type: string
+ default: rs0
+ namespace:
+ description: Kubernetes namespace
+ type: string
+ default: osm
+ service-name:
+ description: Headless service name
+ type: string
+ default: mongodb-k8s-endpoints
+ cluster-domain:
+ description: Cluster domain
+ type: string
+ default: cluster.local
+ enable-sidecar:
+ description: Enable sidecar
+ type: boolean
+ default: false
+ mongodb-image:
+ type: string
+ description: OCI image
+ default: rocks.canonical.com:443/mongo:latest
+ sidecar-image:
+ type: string
+ description: OCI image
+ default: rocks.canonical.com:443/cvallance/mongo-k8s-sidecar:latest
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="96"
+ height="96"
+ id="svg6517"
+ version="1.1"
+ inkscape:version="0.91+devel r"
+ sodipodi:docname="mongoDB.svg"
+ viewBox="0 0 96 96">
+ <defs
+ id="defs6519">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient896">
+ <stop
+ style="stop-color:#198332;stop-opacity:1"
+ offset="0"
+ id="stop898" />
+ <stop
+ style="stop-color:#24933b;stop-opacity:1"
+ offset="1"
+ id="stop900" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient888">
+ <stop
+ style="stop-color:#0f9b36;stop-opacity:1"
+ offset="0"
+ id="stop890" />
+ <stop
+ style="stop-color:#64bb66;stop-opacity:1"
+ offset="1"
+ id="stop892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient878">
+ <stop
+ style="stop-color:#e3e2ce;stop-opacity:1"
+ offset="0"
+ id="stop880" />
+ <stop
+ id="stop886"
+ offset="0.45080602"
+ style="stop-color:#ceceb5;stop-opacity:1;" />
+ <stop
+ style="stop-color:#95966f;stop-opacity:1"
+ offset="1"
+ id="stop882" />
+ </linearGradient>
+ <linearGradient
+ id="Background">
+ <stop
+ id="stop4178"
+ offset="0"
+ style="stop-color:#22779e;stop-opacity:1" />
+ <stop
+ id="stop4180"
+ offset="1"
+ style="stop-color:#2991c0;stop-opacity:1" />
+ </linearGradient>
+ <filter
+ style="color-interpolation-filters:sRGB"
+ inkscape:label="Inner Shadow"
+ id="filter1121">
+ <feFlood
+ flood-opacity="0.59999999999999998"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood1123" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="out"
+ result="composite1"
+ id="feComposite1125" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="1"
+ result="blur"
+ id="feGaussianBlur1127" />
+ <feOffset
+ dx="0"
+ dy="2"
+ result="offset"
+ id="feOffset1129" />
+ <feComposite
+ in="offset"
+ in2="SourceGraphic"
+ operator="atop"
+ result="composite2"
+ id="feComposite1131" />
+ </filter>
+ <filter
+ style="color-interpolation-filters:sRGB"
+ inkscape:label="Drop Shadow"
+ id="filter950">
+ <feFlood
+ flood-opacity="0.25"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood952" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="in"
+ result="composite1"
+ id="feComposite954" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="1"
+ result="blur"
+ id="feGaussianBlur956" />
+ <feOffset
+ dx="0"
+ dy="1"
+ result="offset"
+ id="feOffset958" />
+ <feComposite
+ in="SourceGraphic"
+ in2="offset"
+ operator="over"
+ result="composite2"
+ id="feComposite960" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath873">
+ <g
+ transform="matrix(0,-0.66666667,0.66604479,0,-258.25992,677.00001)"
+ id="g875"
+ inkscape:label="Layer 1"
+ style="display:inline;fill:#ff00ff;fill-opacity:1;stroke:none">
+ <path
+ style="display:inline;fill:#ff00ff;fill-opacity:1;stroke:none"
+ d="M 46.702703,898.22775 H 97.297297 C 138.16216,898.22775 144,904.06497 144,944.92583 v 50.73846 c 0,40.86071 -5.83784,46.69791 -46.702703,46.69791 H 46.702703 C 5.8378378,1042.3622 0,1036.525 0,995.66429 v -50.73846 c 0,-40.86086 5.8378378,-46.69808 46.702703,-46.69808 z"
+ id="path877"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssss" />
+ </g>
+ </clipPath>
+ <style
+ id="style867"
+ type="text/css"><![CDATA[
+ .fil0 {fill:#1F1A17}
+ ]]></style>
+ <clipPath
+ id="clipPath16">
+ <path
+ id="path18"
+ d="M -9,-9 H 605 V 222 H -9 Z"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath116">
+ <path
+ id="path118"
+ d="m 91.7368,146.3253 -9.7039,-1.577 -8.8548,-3.8814 -7.5206,-4.7308 -7.1566,-8.7335 -4.0431,-4.282 -3.9093,-1.4409 -1.034,2.5271 1.8079,2.6096 0.4062,3.6802 1.211,-0.0488 1.3232,-1.2069 -0.3569,3.7488 -1.4667,0.9839 0.0445,1.4286 -3.4744,-1.9655 -3.1462,-3.712 -0.6559,-3.3176 1.3453,-2.6567 1.2549,-4.5133 2.5521,-1.2084 2.6847,0.1318 2.5455,1.4791 -1.698,-8.6122 1.698,-9.5825 -1.8692,-4.4246 -6.1223,-6.5965 1.0885,-3.941 2.9002,-4.5669 5.4688,-3.8486 2.9007,-0.3969 3.225,-0.1094 -2.012,-8.2601 7.3993,-3.0326 9.2188,-1.2129 3.1535,2.0619 0.2427,5.5797 3.5178,5.8224 0.2426,4.6094 8.4909,-0.6066 7.8843,0.7279 -7.8843,-4.7307 1.3343,-5.701 4.9731,-7.763 4.8521,-2.0622 3.8814,1.5769 1.577,3.1538 8.1269,6.1861 1.5769,-1.3343 12.7363,-0.485 2.5473,2.0619 0.2426,3.6391 -0.849,1.5767 -0.6066,9.8251 -4.2454,8.4909 0.7276,3.7605 2.5475,-1.3343 7.1566,-6.6716 3.5175,-0.2424 3.8815,1.5769 3.8818,2.9109 1.9406,6.3077 11.4021,-0.7277 6.914,2.6686 5.5797,5.2157 4.0028,7.5206 0.9706,8.8546 -0.8493,10.3105 -2.1832,9.2185 -2.1836,2.9112 -3.0322,0.9706 -5.3373,-5.8224 -4.8518,-1.6982 -4.2455,7.0353 -4.2454,3.8815 -2.3049,1.4556 -9.2185,7.6419 -7.3993,4.0028 -7.3993,0.6066 -8.6119,-1.4556 -7.5206,-2.7899 -5.2158,-4.2454 -4.1241,-4.9734 -4.2454,-1.2129"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath128">
+ <path
+ id="path130"
+ d="m 91.7368,146.3253 -9.7039,-1.577 -8.8548,-3.8814 -7.5206,-4.7308 -7.1566,-8.7335 -4.0431,-4.282 -3.9093,-1.4409 -1.034,2.5271 1.8079,2.6096 0.4062,3.6802 1.211,-0.0488 1.3232,-1.2069 -0.3569,3.7488 -1.4667,0.9839 0.0445,1.4286 -3.4744,-1.9655 -3.1462,-3.712 -0.6559,-3.3176 1.3453,-2.6567 1.2549,-4.5133 2.5521,-1.2084 2.6847,0.1318 2.5455,1.4791 -1.698,-8.6122 1.698,-9.5825 -1.8692,-4.4246 -6.1223,-6.5965 1.0885,-3.941 2.9002,-4.5669 5.4688,-3.8486 2.9007,-0.3969 3.225,-0.1094 -2.012,-8.2601 7.3993,-3.0326 9.2188,-1.2129 3.1535,2.0619 0.2427,5.5797 3.5178,5.8224 0.2426,4.6094 8.4909,-0.6066 7.8843,0.7279 -7.8843,-4.7307 1.3343,-5.701 4.9731,-7.763 4.8521,-2.0622 3.8814,1.5769 1.577,3.1538 8.1269,6.1861 1.5769,-1.3343 12.7363,-0.485 2.5473,2.0619 0.2426,3.6391 -0.849,1.5767 -0.6066,9.8251 -4.2454,8.4909 0.7276,3.7605 2.5475,-1.3343 7.1566,-6.6716 3.5175,-0.2424 3.8815,1.5769 3.8818,2.9109 1.9406,6.3077 11.4021,-0.7277 6.914,2.6686 5.5797,5.2157 4.0028,7.5206 0.9706,8.8546 -0.8493,10.3105 -2.1832,9.2185 -2.1836,2.9112 -3.0322,0.9706 -5.3373,-5.8224 -4.8518,-1.6982 -4.2455,7.0353 -4.2454,3.8815 -2.3049,1.4556 -9.2185,7.6419 -7.3993,4.0028 -7.3993,0.6066 -8.6119,-1.4556 -7.5206,-2.7899 -5.2158,-4.2454 -4.1241,-4.9734 -4.2454,-1.2129"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3850"
+ inkscape:collect="always">
+ <stop
+ id="stop3852"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3854"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath3095">
+ <path
+ d="M 976.648,389.551 H 134.246 V 1229.55 H 976.648 V 389.551"
+ id="path3097"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath3195">
+ <path
+ d="m 611.836,756.738 -106.34,105.207 c -8.473,8.289 -13.617,20.102 -13.598,33.379 L 598.301,790.207 c -0.031,-13.418 5.094,-25.031 13.535,-33.469"
+ id="path3197"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath3235">
+ <path
+ d="m 1095.64,1501.81 c 35.46,-35.07 70.89,-70.11 106.35,-105.17 4.4,-4.38 7.11,-10.53 7.11,-17.55 l -106.37,105.21 c 0,7 -2.71,13.11 -7.09,17.51"
+ id="path3237"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4591"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 1106.6009,730.43734 -0.036,21.648 c -0.01,3.50825 -2.8675,6.61375 -6.4037,6.92525 l -83.6503,7.33162 c -3.5205,0.30763 -6.3812,-2.29987 -6.3671,-5.8145 l 0.036,-21.6475 20.1171,-1.76662 -0.011,4.63775 c 0,1.83937 1.4844,3.19925 3.3262,3.0395 l 49.5274,-4.33975 c 1.8425,-0.166 3.3425,-1.78125 3.3538,-3.626 l 0.01,-4.63025 20.1,-1.7575"
+ style="fill:#ff00ff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path4593" />
+ </clipPath>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.4333926,-2.2742838,1.1731823,-0.73941125,-174.08025,98.374394)"
+ r="20.40658"
+ fy="93.399292"
+ fx="-26.508606"
+ cy="93.399292"
+ cx="-26.508606"
+ id="radialGradient3856"
+ xlink:href="#linearGradient3850"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-318.48033,212.32022)"
+ gradientUnits="userSpaceOnUse"
+ y2="993.19702"
+ x2="-51.879555"
+ y1="593.11615"
+ x1="348.20132"
+ id="linearGradient3895"
+ xlink:href="#linearGradient3850"
+ inkscape:collect="always" />
+ <clipPath
+ id="clipPath3906"
+ clipPathUnits="userSpaceOnUse">
+ <rect
+ transform="scale(1,-1)"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.8;fill:#ff00ff;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
+ id="rect3908"
+ width="1019.1371"
+ height="1019.1371"
+ x="357.9816"
+ y="-1725.8152" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient878"
+ id="linearGradient884"
+ x1="-856.05945"
+ y1="917.14075"
+ x2="-897.81281"
+ y2="890.35901"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient888"
+ id="linearGradient894"
+ x1="-1031.014"
+ y1="698.59906"
+ x2="-871.2926"
+ y2="549.73865"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient896"
+ id="linearGradient902"
+ x1="-845.72949"
+ y1="857.26373"
+ x2="-845.85956"
+ y2="536.13733"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.0931702"
+ inkscape:cx="-18.232516"
+ inkscape:cy="4.2657717"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1029"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ showborder="true"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ inkscape:showpageshadow="false"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:object-nodes="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-page="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid821" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="16,48"
+ id="guide823"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="64,80"
+ id="guide825"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="80,40"
+ id="guide827"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="64,16"
+ id="guide829"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata6522">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="BACKGROUND"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(268,-635.29076)"
+ style="display:inline">
+ <path
+ style="display:inline;fill:#513721;fill-opacity:1;stroke:none"
+ d="M 48 0 A 48 48 0 0 0 0 48 A 48 48 0 0 0 48 96 A 48 48 0 0 0 96 48 A 48 48 0 0 0 48 0 z "
+ transform="translate(-268,635.29076)"
+ id="path6455" />
+ <g
+ id="g904"
+ transform="matrix(0.18303902,0,0,0.18303902,-61.510334,551.26852)"
+ style="filter:url(#filter950)">
+ <path
+ sodipodi:nodetypes="cssccccssc"
+ inkscape:connector-curvature="0"
+ id="path1268"
+ d="m -868.19899,524.60454 c -1.09201,-0.17404 2.2458,6.31938 -5.76173,16.46507 -8.62836,10.93231 -78.08998,55.87715 -80.25267,176.97194 -1.47326,82.49185 63.69591,140.08497 80.26221,150.82239 0,0 6.10773,21.21068 6.30878,46.24185 l 10.94779,2.8528 c -1.30685,-25.73485 -1.6868,-40.61122 5.75219,-51.97075 10.43063,-4.90853 76.14358,-61.15169 73.3404,-148.11885 -3.3392,-103.59672 -61.5131,-148.52136 -78.06619,-170.12132 -7.15576,-9.33748 -10.21866,-22.94207 -12.53078,-23.14313 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient884);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:12;marker:none;enable-background:accumulate" />
+ <path
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient902);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:12;marker:none;enable-background:accumulate"
+ d="m -868.19899,524.60454 c 6.02168,19.47655 4.90908,108.16194 6.20984,193.26637 1.17969,77.18297 -13.32661,137.08201 11.04673,148.11693 10.43063,-4.90853 76.14358,-61.15169 73.3404,-148.11885 -3.3392,-103.59672 -61.5131,-148.52136 -78.06619,-170.12132 -7.15576,-9.33748 -10.21866,-22.94207 -12.53078,-23.14313 z"
+ id="path871"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cscssc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path873"
+ d="m -868.1875,524.60326 c -1.09201,-0.17404 2.22628,6.32306 -5.78125,16.46875 -8.62836,10.93231 -78.08731,55.87396 -80.25,176.96875 -1.47326,82.49185 63.71495,140.07508 80.28125,150.8125 4.55456,-2.09183 6.73773,-23.58984 8.71875,-48.5 0.1491,-26.4041 3.83655,-62.04848 3.21875,-102.46875 -1.21946,-79.7854 -0.31201,-162.74064 -5.15625,-188.84375 -0.0125,-0.0672 -0.0187,-0.12101 -0.0312,-0.1875 -0.32738,-1.41709 -0.65813,-2.83452 -1.00005,-4.25 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient894);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:12;marker:none;enable-background:accumulate" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+includes:
+ - "layer:caas-base"
+ - 'layer:status'
+ - 'layer:leadership'
+ - "layer:osm-common"
+ - 'interface:mongodb'
+
+repo: https://code.launchpad.net/osm-k8s-bundle
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+name: "mongodb-k8s"
+summary: "MongoDB charm for Kubernetes."
+maintainers:
+ - "SolutionsQA <solutionsqa@lists.canonical.com>"
+description: |
+ A CAAS charm to deploy MongoDB.
+tags:
+ - "application"
+series:
+ - "kubernetes"
+provides:
+ mongo:
+ interface: mongodb
+storage:
+ database:
+ type: filesystem
+ location: /data/db
+deployment:
+ type: stateful
+ service: cluster
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+from charms.layer.caas_base import pod_spec_set
+from charms.reactive import endpoint_from_flag
+from charms.reactive import when, when_not, hook
+from charms.reactive.flags import set_flag, clear_flag
+from charmhelpers.core.hookenv import log, metadata, config, goal_state
+from charms import layer
+
+
+@hook("upgrade-charm")
+@when("leadership.is_leader")
+def upgrade():
+ clear_flag("mongodb-k8s.configured")
+
+
+@when("config.changed")
+@when("leadership.is_leader")
+def restart():
+ clear_flag("mongodb-k8s.configured")
+
+
+@when_not("mongodb-k8s.configured")
+@when("leadership.is_leader")
+def configure():
+ layer.status.maintenance("Configuring MongoDB container")
+ try:
+ spec = make_pod_spec()
+ log("set pod spec:\n{}".format(spec))
+ pod_spec_set(spec)
+ set_flag("mongodb-k8s.configured")
+ except Exception as e:
+ layer.status.blocked("k8s spec failed to deploy: {}".format(e))
+
+
+@when("mongodb-k8s.configured")
+def set_mongodb_active():
+ layer.status.active("ready")
+
+
+@when_not("leadership.is_leader")
+def non_leaders_active():
+ layer.status.active("ready")
+
+
+@when("mongodb-k8s.configured", "mongo.joined")
+def send_config():
+ layer.status.maintenance("Sending mongo configuration")
+ try:
+ mongo = endpoint_from_flag("mongo.joined")
+ if mongo:
+ cfg = config()
+ mongo_uri = "mongodb://"
+ for i, unit in enumerate(goal_state()["units"]):
+ pod_base_name = unit.split("/")[0]
+ service_name = cfg.get("service-name")
+ pod_name = "{}-{}".format(pod_base_name, i)
+ if i:
+ mongo_uri += ","
+ mongo_uri += "{}.{}:{}".format(
+ pod_name, service_name, get_mongodb_port()
+ )
+ if cfg.get("enable-sidecar"):
+ mongo_uri += "/?replicaSet={}".format(get_mongodb_replset())
+ log("Mongo URI: {}".format(mongo_uri))
+ mongo.send_connection_string(mongo_uri)
+ clear_flag("mongo.joined")
+ except Exception as e:
+ log("Exception sending config: {}".format(e))
+ clear_flag("mongo.joined")
+
+
+def make_pod_spec():
+ """Make pod specification for Kubernetes
+
+ Returns:
+ pod_spec: Pod specification for Kubernetes
+ """
+ md = metadata()
+ cfg = config()
+
+ if cfg.get("enable-sidecar"):
+ with open("reactive/spec_template_ha.yaml") as spec_file:
+ pod_spec_template = spec_file.read()
+ else:
+ with open("reactive/spec_template.yaml") as spec_file:
+ pod_spec_template = spec_file.read()
+
+ data = {
+ "name": md.get("name"),
+ "docker_image": cfg.get("mongodb-image"),
+ "sc_docker_image": cfg.get("sidecar-image"),
+ "pod_labels": "juju-app={}".format(cfg.get("advertised-hostname")),
+ }
+
+ data.update(cfg)
+ return pod_spec_template % data
+
+
+def get_mongodb_port():
+ """Returns MongoDB port"""
+ cfg = config()
+ return cfg.get("advertised-port")
+
+
+def get_mongodb_replset():
+ """Returns MongoDB port"""
+ cfg = config()
+ return cfg.get("replica-set")
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+version: 2
+containers:
+ - name: %(name)s
+ image: %(docker_image)s
+ command:
+ - mongod
+ - "--bind_ip"
+ - "0.0.0.0"
+ ports:
+ - containerPort: %(advertised-port)s
+ protocol: TCP
+ config:
+ ALLOW_ANONYMOUS_LOGIN: 'yes'
+ kubernetes:
+ readinessProbe:
+ tcpSocket:
+ port: %(advertised-port)s
+ timeoutSeconds: 5
+ periodSeconds: 5
+ initialDelaySeconds: 10
+ livenessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - mongo --port %(advertised-port)s --eval "rs.status()" | grep -vq "REMOVED"
+ initialDelaySeconds: 45
+ timeoutSeconds: 5
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+version: 2
+serviceAccount:
+ rules:
+ - apiGroups: [""]
+ resources: ["pods"]
+ verbs: ["list"]
+containers:
+ - name: %(name)s
+ image: %(docker_image)s
+ command:
+ - mongod
+ - "--replSet"
+ - %(replica-set)s
+ - "--bind_ip"
+ - "0.0.0.0"
+ ports:
+ - containerPort: %(advertised-port)s
+ protocol: TCP
+ config:
+ ALLOW_ANONYMOUS_LOGIN: 'yes'
+ kubernetes:
+ readinessProbe:
+ tcpSocket:
+ port: %(advertised-port)s
+ timeoutSeconds: 5
+ periodSeconds: 5
+ initialDelaySeconds: 10
+ livenessProbe:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - mongo --port %(advertised-port)s --eval "rs.status()" | grep -vq "REMOVED"
+ initialDelaySeconds: 45
+ timeoutSeconds: 5
+ - name: 'mongodb-sidecar-k8s'
+ image: %(sc_docker_image)s
+ config:
+ KUBERNETES_MONGO_SERVICE_NAME: %(service-name)s
+ KUBE_NAMESPACE: %(namespace)s
+ MONGO_SIDECAR_POD_LABELS: %(pod_labels)s
+ KUBERNETES_CLUSTER_DOMAIN: %(cluster-domain)s
\ No newline at end of file
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+git+https://github.com/davigar15/zaza.git#egg=zaza
+pymongo
\ No newline at end of file
--- /dev/null
+#!/usr/bin/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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+import unittest
+import zaza.model as model
+from pymongo import MongoClient
+
+
+def get_mongo_uri():
+ mongo_uri = "mongodb://"
+ mongo_units = model.get_status().applications["mongodb-k8s"]["units"]
+ for i, unit_name in enumerate(mongo_units.keys()):
+ if i:
+ mongo_uri += ","
+ unit_ip = mongo_units[unit_name]["address"]
+ unit_port = mongo_units[unit_name]["opened-ports"][0].split("/")[0]
+ mongo_uri += "{}:{}".format(unit_ip, unit_port)
+
+ return mongo_uri
+
+
+class BasicDeployment(unittest.TestCase):
+ def test_get_mongo_uri(self):
+ get_mongo_uri()
+
+ def test_mongodb_connection(self):
+ mongo_uri = get_mongo_uri()
+ client = MongoClient(mongo_uri)
+ client.server_info()
+
+ def test_mongodb_create_empty_database_collection(self):
+ mongo_uri = get_mongo_uri()
+ client = MongoClient(mongo_uri)
+ DB_NAME = "test_database"
+ COLLECTION_NAME = "test_collection"
+
+ db = client[DB_NAME]
+ _ = client.list_database_names()
+
+ collection = db[COLLECTION_NAME]
+ _ = db.list_collection_names()
+
+ data = {}
+
+ id = collection.insert_one(data)
+
+ for x in collection.find({"_id": id.inserted_id}):
+ self.assertEqual(id.inserted_id, x["_id"])
+
+ def test_mongodb_insert_one(self):
+ mongo_uri = get_mongo_uri()
+ client = MongoClient(mongo_uri)
+ DB_NAME = "test_database"
+ COLLECTION_NAME = "test_collection"
+
+ db = client[DB_NAME]
+ _ = client.list_database_names()
+
+ collection = db[COLLECTION_NAME]
+ _ = db.list_collection_names()
+
+ data = {
+ "name": "Canonical LTD",
+ "address": "5th Floor of the Blue Fin Building",
+ }
+
+ id = collection.insert_one(data)
+
+ for x in collection.find({"_id": id.inserted_id}):
+ self.assertEqual(id.inserted_id, x["_id"])
+
+ def test_mongodb_insert_many(self):
+ mongo_uri = get_mongo_uri()
+ client = MongoClient(mongo_uri)
+ DB_NAME = "test_database"
+ COLLECTION_NAME = "test_collection"
+
+ db = client[DB_NAME]
+ _ = client.list_database_names()
+
+ collection = db[COLLECTION_NAME]
+ _ = db.list_collection_names()
+
+ data = [
+ {"name": "Amy", "address": "Apple st 652"},
+ {"name": "Hannah", "address": "Mountain 21"},
+ {"name": "Michael", "address": "Valley 345"},
+ {"name": "Sandy", "address": "Ocean blvd 2"},
+ {"name": "Betty", "address": "Green Grass 1"},
+ {"name": "Richard", "address": "Sky st 331"},
+ {"name": "Susan", "address": "One way 98"},
+ {"name": "Vicky", "address": "Yellow Garden 2"},
+ {"name": "Ben", "address": "Park Lane 38"},
+ {"name": "William", "address": "Central st 954"},
+ {"name": "Chuck", "address": "Main Road 989"},
+ {"name": "Viola", "address": "Sideway 1633"},
+ ]
+
+ ids = collection.insert_many(data)
+
+ for id in ids.inserted_ids:
+ x = collection.find_one({"_id": id})
+ self.assertEqual(x["_id"], id)
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+bundle: kubernetes
+applications:
+ mongodb-k8s:
+ charm: '../../release/'
+ scale: 2
+ options:
+ enable-sidecar: true
+ namespace: mongo-ha
+ series: kubernetes
+ storage:
+ database: 50M
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+bundle: kubernetes
+applications:
+ mongodb-k8s:
+ charm: '../../release/'
+ scale: 1
+ series: kubernetes
+ storage:
+ database: 50M
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+gate_bundles:
+ - mongodb
+smoke_bundles:
+ - mongodb
+tests:
+ - tests.basic_deployment.BasicDeployment
--- /dev/null
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: legal@canonical.com
+#
+# To get in touch with the maintainers, please contact:
+# osm-charmers@lists.launchpad.net
+##
+
+[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:build]
+basepython = python3
+passenv=HTTP_PROXY HTTPS_PROXY NO_PROXY
+setenv = CHARM_LAYERS_DIR = /tmp
+ CHARM_INTERFACES_DIR = /tmp/canonical-osm/charms/interfaces/
+whitelist_externals = git
+ charm
+ rm
+ mv
+commands =
+ rm -rf /tmp/canonical-osm /tmp/osm-common
+ rm -rf release/
+ git clone https://git.launchpad.net/canonical-osm /tmp/canonical-osm
+ git clone https://git.launchpad.net/charm-osm-common /tmp/osm-common
+ git clone https://git.launchpad.net/interface-mongodb /tmp/canonical-osm/charms/interfaces/mongodb
+ charm build . --build-dir /tmp
+ mv /tmp/mongodb-k8s/ release/
+
+[testenv:black]
+basepython = python3
+deps =
+ black
+ yamllint
+ flake8
+commands =
+ black --check --diff .
+ yamllint .
+ flake8 reactive/ --max-line-length=88
+ flake8 tests/ --max-line-length=88
+
+[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
+ functest-prepare -m mongo-ha
+ juju switch mongo-ha
+ functest-deploy -m mongo-ha -b ./tests/bundles/mongodb-ha.yaml
+ ; functest-test -m mongo-ha
+ functest-destroy -m mongo-ha
+
+
+[testenv:func-smoke]
+basepython = python3
+commands = functest-run-suite --keep-model --smoke
+
+[testenv:venv]
+commands = {posargs}