First draft
This commit is contained in:
commit
b3ae62ceba
3
.stestr.conf
Normal file
3
.stestr.conf
Normal file
@ -0,0 +1,3 @@
|
||||
[DEFAULT]
|
||||
test_path=./unit_tests
|
||||
top_dir=./
|
5
.zuul.yaml
Normal file
5
.zuul.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
- project:
|
||||
templates:
|
||||
- python35-charm-jobs
|
||||
- openstack-python3-ussuri-jobs
|
||||
- openstack-cover-jobs
|
22
README.md
Normal file
22
README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Overview
|
||||
|
||||
This is a "source" charm, which is intended to be strictly the top
|
||||
layer of a built charm. This structure declares that any included
|
||||
layer assets are not intended to be consumed as a layer from a
|
||||
functional or design standpoint.
|
||||
|
||||
# Test and Build
|
||||
|
||||
Building, pushing and publishing to the charm store is automated
|
||||
by CI to ensure consistent flow. Manually building is useful for
|
||||
development and testing, however.
|
||||
|
||||
```
|
||||
tox -e pep8
|
||||
tox -e py35 # or py36
|
||||
tox -e build
|
||||
```
|
||||
|
||||
# Contact Information
|
||||
|
||||
Freenode IRC: #openstack-charms
|
5
rebuild
Normal file
5
rebuild
Normal file
@ -0,0 +1,5 @@
|
||||
# This file is used to trigger rebuilds
|
||||
# when dependencies of the charm change,
|
||||
# but nothing in the charm needs to.
|
||||
# simply change the uuid to something new
|
||||
d9b38a7c-d02c-11ea-a4c2-3fba95671dc4
|
10
requirements.txt
Normal file
10
requirements.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# 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
|
||||
#
|
||||
# Build requirements
|
||||
charm-tools>=2.4.4
|
||||
# importlib-resources 1.1.0 removed Python 3.5 support
|
||||
importlib-resources<1.1.0
|
||||
simplejson
|
19
src/README.md
Normal file
19
src/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
netapp Storage Backend for Cinder
|
||||
-------------------------------
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This charm provides a netapp storage backend for use with the Cinder
|
||||
charm.
|
||||
|
||||
To use:
|
||||
|
||||
juju deploy cinder
|
||||
juju deploy cinder-netapp
|
||||
juju add-relation cinder-netapp cinder
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
See config.yaml for details of configuration options.
|
1
src/config.yaml
Normal file
1
src/config.yaml
Normal file
@ -0,0 +1 @@
|
||||
options:
|
12
src/layer.yaml
Normal file
12
src/layer.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
includes: ['layer:openstack', 'interface:cinder-backend']
|
||||
config:
|
||||
deletes:
|
||||
- debug
|
||||
- verbose
|
||||
- use-syslog
|
||||
- use-internal-endpoints
|
||||
- ssl_ca
|
||||
options:
|
||||
basic:
|
||||
use_venv: True
|
||||
repo: https://github.com/openstack-charmers/cinder-storage-backend-template
|
52
src/lib/charm/openstack/cinder_netapp.py
Normal file
52
src/lib/charm/openstack/cinder_netapp.py
Normal file
@ -0,0 +1,52 @@
|
||||
import charms_openstack.charm
|
||||
|
||||
charms_openstack.charm.use_defaults('charm.default-select-release')
|
||||
|
||||
|
||||
class CindernetappCharm(
|
||||
charms_openstack.charm.CinderStoragePluginCharm):
|
||||
|
||||
name = 'cinder_netapp'
|
||||
release = 'stein'
|
||||
stateless = True
|
||||
version_package = 'cinder-common'
|
||||
packages = []
|
||||
# Specify any config that the user *must* set.
|
||||
mandatory_config = [
|
||||
'netapp_storage_family', 'netapp_storage_protocol', 'netapp_server_hostname',
|
||||
'volume-backend-name']
|
||||
|
||||
def cinder_configuration(self):
|
||||
service = self.config.get('volume-backend-name')
|
||||
volumedriver = 'cinder.volume.drivers.netapp.common.NetAppDriver'
|
||||
driver_options_extension = []
|
||||
driver_options_common = [
|
||||
('netapp_storage_family', self.config.get('netapp-storage-family')),
|
||||
('netapp_storage_protocol', self.config.get('netapp-storage-protocol')),
|
||||
('netapp_vserver', self.config.get('netapp-vserver')),
|
||||
('netapp_server_hostname', self.config.get('netapp-server-hostname')),
|
||||
('netapp_server_port', self.config.get('netapp-vserver-port')),
|
||||
('netapp_login', self.config.get('netapp-login')),
|
||||
('netapp_password', self.config.get('netapp-password')),
|
||||
('netapp_lun_space_reservation', self.config.get('netapp-lun-space-reservation')),
|
||||
('netapp_transport_type', self.config.get('netapp-transport-type')),
|
||||
('volume_driver', volumedriver),
|
||||
('volume_backend_name', service)]
|
||||
|
||||
if self.config.get('netapp-storage-family') == "eseries":
|
||||
driver_options_extension = [
|
||||
('netapp_controller_ips', self.config.get('netapp-controller-ips')),
|
||||
('netapp_sa_password', self.config.get('netapp-array-password')),
|
||||
('netapp_storage_pools', self.config.get('netapp-storage-pools')),
|
||||
('use_multipath_for_image_xfer', self.config.get('use-multipath'))]
|
||||
|
||||
return driver_options_common + driver_options_extension
|
||||
|
||||
|
||||
class CindernetappCharmRocky(CindernetappCharm):
|
||||
|
||||
# Rocky needs py3 packages.
|
||||
release = 'rocky'
|
||||
version_package = 'cinder-common'
|
||||
packages = []
|
||||
|
24
src/metadata.yaml
Normal file
24
src/metadata.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
name: cinder-netapp
|
||||
summary: netapp integration for OpenStack Block Storage
|
||||
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
|
||||
description: |
|
||||
Cinder is the block storage service for the Openstack project.
|
||||
.
|
||||
This charm provides a netapp backend for Cinder
|
||||
tags:
|
||||
- openstack
|
||||
- storage
|
||||
- file-servers
|
||||
- misc
|
||||
series:
|
||||
- xenial
|
||||
- bionic
|
||||
subordinate: true
|
||||
provides:
|
||||
storage-backend:
|
||||
interface: cinder-backend
|
||||
scope: container
|
||||
requires:
|
||||
juju-info:
|
||||
interface: juju-info
|
||||
scope: container
|
35
src/reactive/cinder_netapp_handlers.py
Normal file
35
src/reactive/cinder_netapp_handlers.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2019
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import charms_openstack.charm
|
||||
import charms.reactive
|
||||
|
||||
# This charm's library contains all of the handler code associated with
|
||||
# this charm -- we will use the auto-discovery feature of charms.openstack
|
||||
# to get the definitions for the charm.
|
||||
import charms_openstack.bus
|
||||
charms_openstack.bus.discover()
|
||||
|
||||
charms_openstack.charm.use_defaults(
|
||||
'charm.installed',
|
||||
'update-status',
|
||||
'upgrade-charm',
|
||||
'storage-backend.connected',
|
||||
)
|
||||
|
||||
|
||||
@charms.reactive.when('config.changed.driver-source')
|
||||
def reinstall():
|
||||
with charms_openstack.charm.provide_charm_instance() as charm:
|
||||
charm.install()
|
3
src/test-requirements.txt
Normal file
3
src/test-requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
# zaza
|
||||
git+https://github.com/openstack-charmers/zaza.git#egg=zaza
|
||||
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack
|
50
src/tests/bundles/xenial-stein.yaml
Normal file
50
src/tests/bundles/xenial-stein.yaml
Normal file
@ -0,0 +1,50 @@
|
||||
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-netapp: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-stein
|
||||
to:
|
||||
- '1'
|
||||
cinder:
|
||||
charm: cs:~openstack-charmers-next/cinder
|
||||
num_units: 1
|
||||
options:
|
||||
openstack-origin: cloud:xenial-stein
|
||||
to:
|
||||
- '2'
|
||||
cinder-netapp:
|
||||
series: xenial
|
||||
charm: cinder-netapp
|
||||
options:
|
||||
# Add config options here
|
||||
rabbitmq-server:
|
||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
||||
num_units: 1
|
||||
to:
|
||||
- '3'
|
9
src/tests/tests.yaml
Normal file
9
src/tests/tests.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
charm_name: cinder-netapp
|
||||
tests:
|
||||
- tests.tests_cinder_netapp.CindernetappTest
|
||||
configure:
|
||||
- zaza.openstack.charm_tests.keystone.setup.add_demo_user
|
||||
gate_bundles:
|
||||
- xenial-stein
|
||||
smoke_bundles:
|
||||
- xenial-stein
|
70
src/tests/tests_cinder_netapp.py
Normal file
70
src/tests/tests_cinder_netapp.py
Normal file
@ -0,0 +1,70 @@
|
||||
#!/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-netapp 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 CindernetappTest(test_utils.OpenStackBaseTest):
|
||||
"""Encapsulate netapp tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Run class setup for running tests."""
|
||||
super(CindernetappTest, 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('netapp')
|
||||
expected_contents = {
|
||||
'cinder-netapp': {
|
||||
'iscsi_helper': ['tgtadm'],
|
||||
'volume_dd_blocksize': ['512']}}
|
||||
|
||||
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-netapp')
|
||||
self.cinder_client.volumes.delete(vol_new)
|
35
src/tox.ini
Normal file
35
src/tox.ini
Normal file
@ -0,0 +1,35 @@
|
||||
[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:pep8]
|
||||
basepython = python3
|
||||
deps=charm-tools
|
||||
commands = charm-proof
|
||||
|
||||
[testenv:func-noop]
|
||||
basepython = python3
|
||||
commands =
|
||||
true
|
||||
|
||||
[testenv:func]
|
||||
basepython = python3
|
||||
commands =
|
||||
functest-run-suite --keep-model
|
||||
|
||||
[testenv:func-smoke]
|
||||
basepython = python3
|
||||
commands =
|
||||
functest-run-suite --keep-model --smoke
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
2
src/wheelhouse.txt
Normal file
2
src/wheelhouse.txt
Normal file
@ -0,0 +1,2 @@
|
||||
#layer-basic uses wheelhouse to install python dependencies
|
||||
psutil
|
23
test-requirements.txt
Normal file
23
test-requirements.txt
Normal file
@ -0,0 +1,23 @@
|
||||
# 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
|
||||
#
|
||||
# Lint and unit test requirements
|
||||
flake8>=2.2.4,<=2.4.1
|
||||
stestr>=2.2.0
|
||||
requests>=2.18.4
|
||||
charms.reactive
|
||||
mock>=1.2
|
||||
nose>=1.3.7
|
||||
coverage>=3.6
|
||||
git+https://github.com/openstack/charms.openstack.git#egg=charms.openstack
|
||||
#
|
||||
# Revisit for removal / mock improvement:
|
||||
netifaces # vault
|
||||
psycopg2-binary # vault
|
||||
tenacity # vault
|
||||
pbr # vault
|
||||
cryptography # vault, keystone-saml-mellon
|
||||
lxml # keystone-saml-mellon
|
||||
hvac # vault, barbican-vault
|
97
tox.ini
Normal file
97
tox.ini
Normal file
@ -0,0 +1,97 @@
|
||||
# Source charm: ./tox.ini
|
||||
# This file is managed centrally by release-tools and should not be modified
|
||||
# within individual charm repos. See the 'global' dir contents for available
|
||||
# choices of tox.ini for OpenStack Charms:
|
||||
# https://github.com/openstack-charmers/release-tools
|
||||
|
||||
[tox]
|
||||
skipsdist = True
|
||||
envlist = pep8,py3
|
||||
# NOTE: Avoid build/test env pollution by not enabling sitepackages.
|
||||
sitepackages = False
|
||||
# NOTE: Avoid false positives by not skipping missing interpreters.
|
||||
skip_missing_interpreters = False
|
||||
|
||||
[testenv]
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
PYTHONHASHSEED=0
|
||||
TERM=linux
|
||||
LAYER_PATH={toxinidir}/layers
|
||||
INTERFACE_PATH={toxinidir}/interfaces
|
||||
JUJU_REPOSITORY={toxinidir}/build
|
||||
passenv = http_proxy https_proxy INTERFACE_PATH LAYER_PATH JUJU_REPOSITORY
|
||||
install_command =
|
||||
pip install {opts} {packages}
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
[testenv:build]
|
||||
basepython = python3
|
||||
commands =
|
||||
charm-build --log-level DEBUG -o {toxinidir}/build src {posargs}
|
||||
|
||||
[testenv:py3]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
|
||||
[testenv:py35]
|
||||
basepython = python3.5
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
|
||||
[testenv:py36]
|
||||
basepython = python3.6
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
|
||||
[testenv:py37]
|
||||
basepython = python3.7
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
|
||||
[testenv:py38]
|
||||
basepython = python3.8
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
|
||||
[testenv:pep8]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = flake8 {posargs} src unit_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}
|
||||
|
||||
[flake8]
|
||||
# E402 ignore necessary for path append before sys module import in actions
|
||||
ignore = E402,W504
|
22
unit_tests/__init__.py
Normal file
22
unit_tests/__init__.py
Normal file
@ -0,0 +1,22 @@
|
||||
# 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 sys
|
||||
|
||||
sys.path.append('src')
|
||||
sys.path.append('src/lib')
|
||||
|
||||
# Mock out charmhelpers so that we can test without it.
|
||||
import charms_openstack.test_mocks # noqa
|
||||
charms_openstack.test_mocks.mock_charmhelpers()
|
48
unit_tests/test_lib_charm_openstack_cinder_netapp.py
Normal file
48
unit_tests/test_lib_charm_openstack_cinder_netapp.py
Normal file
@ -0,0 +1,48 @@
|
||||
# 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 charmhelpers
|
||||
|
||||
import charm.openstack.cinder_netapp as cinder_netapp
|
||||
|
||||
import charms_openstack.test_utils as test_utils
|
||||
|
||||
|
||||
class TestCindernetappCharm(test_utils.PatchHelper):
|
||||
|
||||
def _patch_config_and_charm(self, config):
|
||||
self.patch_object(charmhelpers.core.hookenv, 'config')
|
||||
|
||||
def cf(key=None):
|
||||
if key is not None:
|
||||
return config[key]
|
||||
return config
|
||||
|
||||
self.config.side_effect = cf
|
||||
c = cinder_netapp.CindernetappCharm()
|
||||
return c
|
||||
|
||||
def test_cinder_base(self):
|
||||
charm = self._patch_config_and_charm({})
|
||||
self.assertEqual(charm.name, 'cinder_netapp')
|
||||
|
||||
def test_cinder_configuration(self):
|
||||
charm = self._patch_config_and_charm({'a': 'b'})
|
||||
config = charm.cinder_configuration()
|
||||
# Add check here that configuration is as expected.
|
||||
self.assertEqual(config, [('netapp_hostname', None),
|
||||
('netapp_login', None),
|
||||
('netapp_password', None),
|
||||
('volume_driver', None),
|
||||
('volume_backend_name', None)])
|
Loading…
Reference in New Issue
Block a user