commit 4383eb6d5836247188fa5598fe742b4054c61205 Author: Gustavo Sanchez Date: Fri Jan 7 14:37:51 2022 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..08f79eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +build +/*.charm +.tox +.stestr + +layers +interfaces +.testrepository +*__pycache__* +*.pyc +venv + +.vscode +tests/bundles/*@dev* \ No newline at end of file diff --git a/.stestr.conf b/.stestr.conf new file mode 100644 index 0000000..5fcccac --- /dev/null +++ b/.stestr.conf @@ -0,0 +1,3 @@ +[DEFAULT] +test_path=./unit_tests +top_dir=./ diff --git a/README.md b/README.md new file mode 100644 index 0000000..79643bb --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +NimbleStorage Storage Backend for Cinder +------------------------------- + +## Overview + +This charm provides a NimbleStorage storage backend for use with the Cinder charm. + +To use: + + juju deploy cinder + juju deploy cinder-nimblestorage + juju add-relation cinder-nimblestorage cinder + +## Deployment + +This charm's primary use is as a backend for the cinder charm. To do so, add a relation betweeen both charms: + + juju add-relation cinder-nimblestorage:storage-backend cinder:storage-backend + +# Documentation + +The OpenStack Charms project maintains two documentation guides: + +* [OpenStack Charm Guide][cg]: for project information, including development + and support notes +* [OpenStack Charms Deployment Guide][cdg]: for charm usage information + +[cg]: https://docs.openstack.org/charm-guide +[cdg]: https://docs.openstack.org/project-deploy-guide/charm-deployment-guide diff --git a/build-requirements.txt b/build-requirements.txt new file mode 100644 index 0000000..271d895 --- /dev/null +++ b/build-requirements.txt @@ -0,0 +1 @@ +git+https://github.com/canonical/charmcraft.git@0.10.2#egg=charmcraft diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..9e201ae --- /dev/null +++ b/config.yaml @@ -0,0 +1,73 @@ +options: + san-ip: + type: string + description: | + Management IP address of Nimble Storage array/group. + san-login: + type: string + description: | + Nimble Storage account login with minimum power user (admin) privilege + if RBAC is used. + san-password: + type: string + description: | + Password of the admin account for nimble array. + volume-driver: + type: string + description: | + Use either 'iscsi' for iSCSI or 'fc' for Fibre Channel. + default: iscsi + volume-backend-name: + type: string + description: | + A volume back-end name which is specified in the cinder.conf file. + This is also used while assigning a back-end name to the Nimble + volume type. + default: cinder_nimblestorage + use-multipath-for-image-xfer: + type: boolean + description: | + Enables or disables the use of multipathing. + encryption: + type: string + description: | + Used to enable encryption for a volume-type. Either 'yes' or 'no'. + performance-policy-name: + type: string + description: | + The name of a performance policy which exists on the Nimble array + and should be enabled for every volume in a volume type. + multi-initiator: + type: boolean + description: | + Used to enable multi-initiator access for a volume-type. + dedupe: + type: boolean + description: Used to enable dedupe support for a volume-type. + iops-limit: + type: string + description: | + Used to set the IOPS_LIMIT between 256 and 4294967294 for + all volumes created for this volume-type. + folder: + type: string + description: | + It is the name of the folder which exists on the + Nimble/Alletra 6k array and should be enabled for every + volume in a volume type + pool-name: + type: string + description: | + Nimble Controller pool name + subnet-label: + type: string + description: | + Nimble Subnet Label + verify-cert-path: + type: string + description: | + Path to Nimble Array SSL certificate + verify-cert: + type: string + description: | + Whether to verify Nimble SSL Certificate diff --git a/metadata.yaml b/metadata.yaml new file mode 100644 index 0000000..f1b1c95 --- /dev/null +++ b/metadata.yaml @@ -0,0 +1,24 @@ +name: cinder-nimblestorage +summary: NimbleStorage integration for OpenStack Block Storage +maintainer: OpenStack Charmers +description: | + Cinder is the block storage service for the Openstack project. + This charm provides a NimbleStorage backend for Cinder. +tags: + - openstack + - storage + - file-servers + - misc +series: + - xenial + - bionic + - focal +subordinate: true +provides: + storage-backend: + interface: cinder-backend + scope: container +requires: + juju-info: + interface: juju-info + scope: container diff --git a/pip.sh b/pip.sh new file mode 100755 index 0000000..9a7e6b0 --- /dev/null +++ b/pip.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of tox.ini for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools +# +# setuptools 58.0 dropped the support for use_2to3=true which is needed to +# install blessings (an indirect dependency of charm-tools). +# +# More details on the beahvior of tox and virtualenv creation can be found at +# https://github.com/tox-dev/tox/issues/448 +# +# This script is wrapper to force the use of the pinned versions early in the +# process when the virtualenv was created and upgraded before installing the +# depedencies declared in the target. +pip install 'pip<20.3' 'setuptools<50.0.0' +pip "$@" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..86315ca --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +ops +git+https://opendev.org/openstack/charm-ops-openstack#egg=ops_openstack diff --git a/src/charm.py b/src/charm.py new file mode 100755 index 0000000..868c6db --- /dev/null +++ b/src/charm.py @@ -0,0 +1,78 @@ +#! /usr/bin/env python3 + +# Copyright 2021 Canonical Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + +from ops.main import main +from ops_openstack.plugins.classes import CinderStoragePluginCharm + +logger = logging.getLogger(__name__) + +VOLUME_DRIVERS = { + 'fc': 'cinder.volume.drivers.nimble.NimbleFCDriver', + 'iscsi': 'cinder.volume.drivers.nimble.NimbleISCSIDriver'} + + +class CinderNimblestorageCharm(CinderStoragePluginCharm): + + PACKAGES = ['cinder-common'] + # Overriden from the parent. May be set depending on the charm's properties + stateless = True + active_active = False + + mandatory_config = [ + 'san-ip', 'san-login', 'san-password'] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._stored.is_started = True + + def cinder_configuration(self, charm_config) -> 'list[tuple]': + """Return the configuration to be set by the principal""" + cget = charm_config.get + + volume_driver = cget('volume-driver') + + raw_options = [ + ('volume_driver', VOLUME_DRIVERS[volume_driver]), + ('san_ip', cget('san-ip')), + ('san_login', cget('san-login')), + ('san_password', cget('san-password')), + ('use_multipath_for_image_xfer', + cget('use-multipath-for-image-xfer')), + ('nimble:encryption', cget('encryption')), + ('nimble:perfpol-name', + cget('performance-policy-name')), + + # When upgrading to OpenStack deployment + # to Victoria or later, do unset nimble:multi-initiator extra-spec + # and set multiattach=' True'. + ('nimble:multi-initiator', cget('multi-initiator')), + ('nimble:dedupe', cget('dedupe')), + ('nimble:iops-limit', cget('iops-limit')), + ('nimble:folder', cget('folder')), + ('nimble_pool_name', cget('pool-name')), + ('nimble_subnet_label', cget('subnet-label')), + ('nimble_verify_cert_path', cget('verify-cert-path')), + ('nimble_verify_certificate', cget('verify-cert')) + ] + options = [(x, y) for x, y in raw_options if y] + return options + + +if __name__ == '__main__': + main(CinderNimblestorageCharm) diff --git a/src/test-requirements.txt b/src/test-requirements.txt new file mode 100644 index 0000000..e771023 --- /dev/null +++ b/src/test-requirements.txt @@ -0,0 +1,9 @@ +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of *requirements.txt files for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools +# + +# Functional Test Requirements (let Zaza's dependencies solve all dependencies here!) +git+https://github.com/openstack-charmers/zaza.git#egg=zaza +git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack diff --git a/src/tox.ini b/src/tox.ini new file mode 100644 index 0000000..b40d295 --- /dev/null +++ b/src/tox.ini @@ -0,0 +1,61 @@ +# Source charm (with zaza): ./src/tox.ini +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of tox.ini for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools + +[tox] +envlist = pep8 +skipsdist = True +# NOTE: Avoid build/test env pollution by not enabling sitepackages. +sitepackages = False +# NOTE: Avoid false positives by not skipping missing interpreters. +skip_missing_interpreters = False +# NOTES: +# * We avoid the new dependency resolver by pinning pip < 20.3, see +# https://github.com/pypa/pip/issues/9187 +# * Pinning dependencies requires tox >= 3.2.0, see +# https://tox.readthedocs.io/en/latest/config.html#conf-requires +# * It is also necessary to pin virtualenv as a newer virtualenv would still +# lead to fetching the latest pip in the func* tox targets, see +# https://stackoverflow.com/a/38133283 +requires = pip < 20.3 + virtualenv < 20.0 +# NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci +minversion = 3.18.0 + +[testenv] +setenv = VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 +allowlist_externals = juju +passenv = HOME TERM CS_* OS_* TEST_* +deps = -r{toxinidir}/test-requirements.txt +install_command = + pip install {opts} {packages} + +[testenv:pep8] +basepython = python3 +commands = charm-proof + +[testenv:func-noop] +basepython = python3 +commands = + functest-run-suite --help + +[testenv:func] +basepython = python3 +commands = + functest-run-suite --keep-model + +[testenv:func-smoke] +basepython = python3 +commands = + functest-run-suite --keep-model --smoke + +[testenv:func-target] +basepython = python3 +commands = + functest-run-suite --keep-model --bundle {posargs} + +[testenv:venv] +commands = {posargs} diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..170df5e --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,16 @@ +# This file is managed centrally. If you find the need to modify this as a +# one-off, please don't. Intead, consult #openstack-charms and ask about +# requirements management in charms via bot-control. Thank you. +charm-tools>=2.4.4 +coverage>=3.6 +mock>=1.2 +flake8>=4.0.1 +stestr>=2.2.0 +requests>=2.18.4 +psutil +# oslo.i18n dropped py35 support +oslo.i18n<4.0.0 +git+https://github.com/openstack-charmers/zaza.git#egg=zaza +git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack +pytz # workaround for 14.04 pip/tox +pyudev # for ceph-* charm unit tests (not mocked?) diff --git a/tests/bundles/bionic-rocky.yaml b/tests/bundles/bionic-rocky.yaml new file mode 100644 index 0000000..b1b954b --- /dev/null +++ b/tests/bundles/bionic-rocky.yaml @@ -0,0 +1,60 @@ +series: bionic +comment: +- 'machines section to decide order of deployment. database sooner = faster' +machines: + '0': + constraints: mem=3072M + '1': + '2': + '3': + +applications: + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + to: + - '0' + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + to: + - '1' + cinder: + charm: cs:~openstack-charmers-next/cinder + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + to: + - '2' + cinder-nimblestorage: + series: bionic + charm: cinder-nimblestorage + options: + volume-driver: 'iscsi' + volume-backend-name: 'nimble-storage-iscsi' + san-ip: '10.11.12.13' + san-login: 'admin' + san-password: 'admin' + use-multipath-for-image-xfer: True + encryption: 'yes' + performance-policy-name: 'test-performance-policy' + multi-initiator: True + pool-name: 'default' + subnet-label: '*' + verify-cert-path: 'None' + verify-cert: 'False' +# Add config options here + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + to: + - '3' + +relations: + - [ keystone:shared-db, mysql:shared-db ] + - [ cinder:shared-db, mysql:shared-db ] + - [ cinder:identity-service, keystone:identity-service ] + - [ cinder:amqp, rabbitmq-server:amqp ] + - [ cinder:storage-backend, cinder-nimblestorage:storage-backend ] diff --git a/tests/bundles/focal-ussuri.yaml b/tests/bundles/focal-ussuri.yaml new file mode 100644 index 0000000..d09d761 --- /dev/null +++ b/tests/bundles/focal-ussuri.yaml @@ -0,0 +1,84 @@ +series: focal +variables: + openstack-origin: &openstack-origin distro +comment: + - machines section to decide order of deployment. database sooner = faster + +machines: + '0': + constraints: mem=3072M + '1': + constraints: mem=3072M + '2': + constraints: mem=3072M + '3': + '4': + '5': + constraints: mem=4G root-disk=16G + +applications: + mysql-innodb-cluster: + charm: cs:~openstack-charmers-next/mysql-innodb-cluster + num_units: 3 + options: + source: *openstack-origin + to: + - '0' + - '1' + - '2' + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + options: + source: *openstack-origin + to: + - '3' + keystone: + charm: cs:~openstack-charmers/keystone + options: + openstack-origin: *openstack-origin + num_units: 1 + to: + - '4' + keystone-mysql-router: + charm: cs:~openstack-charmers-next/mysql-router + cinder: + charm: cs:~openstack-charmers-next/cinder + num_units: 1 + storage: + block-devices: '40G' + options: + openstack-origin: *openstack-origin + block-device: None + overwrite: "true" + to: + - '5' + + cinder-mysql-router: + charm: cs:~openstack-charmers-next/mysql-router + + cinder-nimblestorage: + charm: cinder-nimblestorage + options: + volume-driver: 'iscsi' + volume-backend-name: 'nimble-storage-iscsi' + san-ip: '10.11.12.13' + san-login: 'admin' + san-password: 'admin' + use-multipath-for-image-xfer: True + encryption: 'yes' + performance-policy-name: 'test-performance-policy' + multi-initiator: True + pool-name: 'default' + subnet-label: '*' + verify-cert-path: 'None' + verify-cert: 'False' + +relations: + - [ keystone:shared-db, keystone-mysql-router:shared-db ] + - [ keystone-mysql-router:db-router, mysql-innodb-cluster:db-router ] + - [ cinder:shared-db, cinder-mysql-router:shared-db ] + - [ cinder-mysql-router:db-router, mysql-innodb-cluster:db-router ] + - [ cinder:identity-service, keystone:identity-service ] + - [ cinder:amqp, rabbitmq-server:amqp ] + - [ cinder:storage-backend, cinder-nimblestorage:storage-backend ] diff --git a/tests/bundles/overlays/local-charm-overlay.yaml.j2 b/tests/bundles/overlays/local-charm-overlay.yaml.j2 new file mode 100644 index 0000000..226fad9 --- /dev/null +++ b/tests/bundles/overlays/local-charm-overlay.yaml.j2 @@ -0,0 +1,6 @@ +applications: + cinder-nimblestorage: + options: + san-ip: {{ TEST_NIMBLESTORAGE_SAN_IP }} + san-login: {{ TEST_NIMBLESTORAGE_SAN_USERNAME }} + san-password: {{ TEST_NIMBLESTORAGE_SAN_PASSWORD }} diff --git a/tests/bundles/xenial-ocata.yaml b/tests/bundles/xenial-ocata.yaml new file mode 100644 index 0000000..1f514a6 --- /dev/null +++ b/tests/bundles/xenial-ocata.yaml @@ -0,0 +1,63 @@ +series: xenial +comment: +- 'machines section to decide order of deployment. database sooner = faster' +machines: + '0': + constraints: mem=3072M + '1': + '2': + '3': +relations: +- - keystone:shared-db + - mysql:shared-db +- - cinder:shared-db + - mysql:shared-db +- - cinder:identity-service + - keystone:identity-service +- - cinder:amqp + - rabbitmq-server:amqp +- - cinder:storage-backend + - cinder-nimblestorage:storage-backend +applications: + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + to: + - '0' + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:xenial-ocata + to: + - '1' + cinder: + charm: cs:~openstack-charmers-next/cinder + num_units: 1 + options: + openstack-origin: cloud:xenial-ocata + to: + - '2' + cinder-nimblestorage: + series: xenial + charm: cinder-nimblestorage + options: + volume-driver: 'iscsi' + volume-backend-name: 'nimble-storage-iscsi' + san-ip: '10.11.12.13' + san-login: 'admin' + san-password: 'admin' + use-multipath-for-image-xfer: True + encryption: 'yes' + performance-policy-name: 'test-performance-policy' + multi-initiator: True + pool-name: 'default' + subnet-label: '*' + verify-cert-path: 'None' + verify-cert: 'False' +# Add config options here + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + to: + - '3' diff --git a/tests/tests.yaml b/tests/tests.yaml new file mode 100644 index 0000000..a25b864 --- /dev/null +++ b/tests/tests.yaml @@ -0,0 +1,9 @@ +charm_name: cinder-nimblestorage +tests: + - tests.tests_cinder_nimblestorage.CinderNimblestorageTest +configure: + - zaza.openstack.charm_tests.keystone.setup.add_demo_user +gate_bundles: + - focal-ussuri +smoke_bundles: + - focal-ussuri diff --git a/tests/tests_cinder_nimblestorage.py b/tests/tests_cinder_nimblestorage.py new file mode 100644 index 0000000..7154b78 --- /dev/null +++ b/tests/tests_cinder_nimblestorage.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 + +# Copyright 2019 Canonical Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Encapsulate cinder-nimblestorage testing.""" + +import logging +import uuid + +import zaza.model +import zaza.openstack.charm_tests.test_utils as test_utils +import zaza.openstack.utilities.openstack as openstack_utils + + +class CinderNimblestorageTest(test_utils.OpenStackBaseTest): + """Encapsulate NimbleStorage tests.""" + + @classmethod + def setUpClass(cls): + """Run class setup for running tests.""" + super(CinderNimblestorageTest, cls).setUpClass() + cls.keystone_session = openstack_utils.get_overcloud_keystone_session() + cls.model_name = zaza.model.get_juju_model() + cls.cinder_client = openstack_utils.get_cinder_session_client( + cls.keystone_session) + + def test_cinder_config(self): + logging.info('nimblestorage') + expected_contents = { + 'cinder-nimblestorage': { + 'volume_driver': + ['cinder.volume.drivers.nimble.NimbleISCSIDriver'], + 'volume_backend_name': ['cinder_nimblestorage'], + 'san_ip': ['10.11.12.13'], + 'san_login': ['admin'], + 'san_password': ['admin'], + 'use_multipath_for_image_xfer': [True], + 'nimble:encryption': ['yes'], + 'nimble:perfpol-name': ['test-performance-policy'], + 'nimble:multi-initiator': [True], + 'nimble_pool_name': ['default'], + 'nimble_subnet_label': ['*'], + 'nimble_verify_cert_path': ['None'], + 'nimble_verify_certificate': ['False']}} + + zaza.model.run_on_leader( + 'cinder', + 'sudo cp /etc/cinder/cinder.conf /tmp/', + model_name=self.model_name) + zaza.model.block_until_oslo_config_entries_match( + 'cinder', + '/tmp/cinder.conf', + expected_contents, + model_name=self.model_name, + timeout=2) + + def test_create_volume(self): + test_vol_name = "zaza{}".format(uuid.uuid1().fields[0]) + vol_new = self.cinder_client.volumes.create( + name=test_vol_name, + size=2) + openstack_utils.resource_reaches_status( + self.cinder_client.volumes, + vol_new.id, + expected_status='available') + test_vol = self.cinder_client.volumes.find(name=test_vol_name) + self.assertEqual( + getattr(test_vol, 'os-vol-host-attr:host').split('#')[0], + 'cinder@cinder-nimblestorage') + self.cinder_client.volumes.delete(vol_new) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..99cf840 --- /dev/null +++ b/tox.ini @@ -0,0 +1,133 @@ +# Operator charm (with zaza): tox.ini + +[tox] +envlist = pep8,py3 +skipsdist = True +# NOTE: Avoid build/test env pollution by not enabling sitepackages. +sitepackages = False +# NOTE: Avoid false positives by not skipping missing interpreters. +skip_missing_interpreters = False +# NOTES: +# * We avoid the new dependency resolver by pinning pip < 20.3, see +# https://github.com/pypa/pip/issues/9187 +# * Pinning dependencies requires tox >= 3.2.0, see +# https://tox.readthedocs.io/en/latest/config.html#conf-requires +# * It is also necessary to pin virtualenv as a newer virtualenv would still +# lead to fetching the latest pip in the func* tox targets, see +# https://stackoverflow.com/a/38133283 +requires = pip < 20.3 + virtualenv < 20.0 +# NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci +minversion = 3.2.0 + +[testenv] +setenv = VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 + CHARM_DIR={envdir} +install_command = + pip install {opts} {packages} +commands = stestr run --slowest {posargs} +whitelist_externals = + git + add-to-archive.py + bash +passenv = HOME TERM CS_* OS_* TEST_* +deps = -r{toxinidir}/test-requirements.txt + +[testenv:py35] +basepython = python3.5 +# python3.5 is irrelevant on a focal+ charm. +commands = /bin/true + +[testenv:py36] +basepython = python3.6 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:py37] +basepython = python3.7 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:py38] +basepython = python3.8 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:py3] +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:pep8] +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +commands = flake8 {posargs} src unit_tests tests + +[testenv:cover] +# Technique based heavily upon +# https://github.com/openstack/nova/blob/master/tox.ini +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +setenv = + {[testenv]setenv} + PYTHON=coverage run +commands = + coverage erase + stestr run --slowest {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report + +[coverage:run] +branch = True +concurrency = multiprocessing +parallel = True +source = + . +omit = + .tox/* + */charmhelpers/* + unit_tests/* + +[testenv:venv] +basepython = python3 +commands = {posargs} + +[testenv:build] +basepython = python3 +deps = -r{toxinidir}/build-requirements.txt +commands = + charmcraft build + +[testenv:func-noop] +basepython = python3 +commands = + functest-run-suite --help + +[testenv:func] +basepython = python3 +commands = + functest-run-suite --keep-model + +[testenv:func-smoke] +basepython = python3 +commands = + functest-run-suite --keep-model --smoke + +[testenv:func-dev] +basepython = python3 +commands = + functest-run-suite --keep-model --dev + +[testenv:func-target] +basepython = python3 +commands = + functest-run-suite --keep-model --bundle {posargs} + +[flake8] +# Ignore E902 because the unit_tests directory is missing in the built charm. +ignore = E402,E226,W503,W504,E902 diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py new file mode 100644 index 0000000..8381d13 --- /dev/null +++ b/unit_tests/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/unit_tests/test_cinder_nimblestorage_charm.py b/unit_tests/test_cinder_nimblestorage_charm.py new file mode 100644 index 0000000..f004b30 --- /dev/null +++ b/unit_tests/test_cinder_nimblestorage_charm.py @@ -0,0 +1,60 @@ +# Copyright 2016 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 unittest +from src.charm import CinderSolidfireCharm +from ops.model import ActiveStatus +from ops.testing import Harness + + +class TestCinderSolidfireCharm(unittest.TestCase): + + def setUp(self): + self.harness = Harness(CinderSolidfireCharm) + self.addCleanup(self.harness.cleanup) + self.harness.begin() + self.harness.set_leader(True) + relation_id = self.harness.add_relation('storage-backend', 'cinder') + self.harness.add_relation_unit(relation_id, 'cinder/0') + + def test_base(self): + self.assertEqual( + self.harness.framework.model.app.name, + 'cinder-nimblestorage') + self.harness.update_config({}) + self.assertTrue(isinstance( + self.harness.model.unit.status, ActiveStatus)) + + def test_configuration(self): + test_config = { + 'volume-driver': 'iscsi', + 'volume-backend-name': 'nimble-storage-iscsi', + 'san-ip': '10.11.12.13', + 'san-login': 'admin', + 'san-password': 'admin', + 'use-multipath-for-image-xfer': True, + 'encryption': 'yes', + 'performance-policy-name': 'test-performance-policy', + 'multi-initiator': True, + 'pool-name': 'default', + 'subnet-label': '*', + 'verify-cert-path': 'None', + 'verify-cert': 'False' + } + config = self.harness.model.config + + self.harness.update_config(test_config) + + for k in test_config: + self.assertEqual(test_config[k], config[k])