Enable S3 storage backend for Gnocchi

This feature enables the use of a S3 storage backend for Gnocchi.

Charm specs PR: https://review.opendev.org/#/c/738631/
func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/334

Change-Id: I959ed69e08b178cddf72535f22499a66b24f9567
This commit is contained in:
camille.rodriguez 2020-06-09 14:22:43 -05:00 committed by Camille Rodriguez
parent cb7703cc90
commit b9a5c54da8
19 changed files with 935 additions and 24 deletions

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ test-charm/
**/__pycache__
interfaces
layers
.idea
.history

View File

@ -8,3 +8,4 @@ charm-tools>=2.4.4
# importlib-resources 1.1.0 removed Python 3.5 support
importlib-resources<1.1.0
simplejson
boto3

View File

@ -26,3 +26,14 @@ measures.
Gnocchi then needs to be initialized with the current ceilometer data:
juju run-action <ceilometer unit leader> ceilometer-upgrade
# Usage with S3 storage backend
> **Note**: S3 storage support for Gnocchi is available starting with OpenStack
Stein.
Gnocchi is configured to be deployed by default with Ceph, however,
it can also connect to an S3 storage backend. To configure Gnocchi with S3,
configuration options (`storage-backend`, `s3-region-name`, `s3-endpoint-url`,
`s3-access-key-id` and `s3-secret-access-key`) must be provided.
Please take a look at `config.yaml` for more details.

43
src/config.yaml Normal file
View File

@ -0,0 +1,43 @@
options:
storage-backend:
type: string
default: ceph
description: |
Storage backend to use for Gnocchi. Valid options are ceph or s3.
s3-endpoint-url:
type: string
default:
description: |
When using a S3 storage backend, user must provide the endpoint URL.
s3-region-name:
type: string
default:
description: |
When using a S3 storage backend, user must provide the S3 region name.
s3-access-key-id:
type: string
default:
description: |
When using a S3 storage backend, user must provide the S3 access key ID.
s3-secret-access-key:
type: string
default:
description: |
When using a S3 storage backend, user must provide the S3 secret access key.
s3-bucket-prefix:
type: string
default: "gnocchi"
description: |
When using a S3 storage backend, user must provide the prefix to namespace metric bucket.
s3-check-consistency-timeout:
type: int
default: 60
description: |
Maximum time to wait checking data consistency when writing to S3. Set to 0 to
disable data consistency validation. (floating point value). Minimum value: 0
s3-max-pool-connections:
type: int
default: 50
description: |
The maximum number of connections to keep in a connection pool. (integer value).
Minimum value: 1

View File

@ -19,6 +19,7 @@ import subprocess
import charmhelpers.contrib.openstack.utils as ch_utils
import charmhelpers.contrib.network.ip as ch_ip
import charmhelpers.core.host as host
import charmhelpers.core.hookenv as hookenv
import charms_openstack.charm
import charms_openstack.adapters as adapters
@ -95,12 +96,11 @@ class GnocchiCharmDatabaseRelationAdapter(adapters.DatabaseRelationAdapter):
return uri
class GnocchiCharmRelationAdapaters(adapters.OpenStackAPIRelationAdapters):
class GnocchiCharmRelationAdapters(adapters.OpenStackAPIRelationAdapters):
"""
Adapters collection to append specific adapters for Gnocchi
"""
relation_adapters = {
'storage_ceph': charms_openstack.plugins.CephRelationAdapter,
'shared_db': GnocchiCharmDatabaseRelationAdapter,
@ -109,8 +109,8 @@ class GnocchiCharmRelationAdapaters(adapters.OpenStackAPIRelationAdapters):
}
class GnochiCharmBase(charms_openstack.charm.HAOpenStackCharm,
charms_openstack.plugins.BaseOpenStackCephCharm):
class GnocchiCharmBase(charms_openstack.charm.HAOpenStackCharm,
charms_openstack.plugins.BaseOpenStackCephCharm):
"""
Base class for shared charm functions for all package types
@ -132,12 +132,9 @@ class GnochiCharmBase(charms_openstack.charm.HAOpenStackCharm,
}
}
required_relations = ['shared-db', 'identity-service',
'storage-ceph', 'coordinator-memcached']
ha_resources = ['vips', 'haproxy', 'dnsha']
adapters_class = GnocchiCharmRelationAdapaters
adapters_class = GnocchiCharmRelationAdapters
def enable_webserver_site(self):
"""Enable Gnocchi Webserver sites if rendered or installed"""
@ -149,6 +146,26 @@ class GnochiCharmBase(charms_openstack.charm.HAOpenStackCharm,
'username': 'gnocchi',
'hostname': ch_ip.get_relation_ip(DB_INTERFACE)}, ]
@property
def required_relations(self):
_required_relations = ['shared-db',
'identity-service',
'coordinator-memcached']
if self.options.storage_backend == 'ceph':
_required_relations.append('storage-ceph')
return _required_relations
@property
def mandatory_config(self):
_mandatory_config = []
if self.options.storage_backend == 's3':
s3_config = ['s3-region-name',
's3-endpoint-url',
's3-access-key-id',
's3-secret-access-key']
_mandatory_config.extend(s3_config)
return _mandatory_config
@property
def gnocchi_user(self):
'''Determine user gnocchi processes will run as
@ -180,8 +197,75 @@ class GnochiCharmBase(charms_openstack.charm.HAOpenStackCharm,
except KeyError:
return CEPH_KEYRING
def db_sync(self):
"""Override db_sync to catch exceptions for the s3 backend.
Perform a database sync using the command defined in the
self.sync_cmd attribute. The services defined in self.services are
restarted after the database sync.
"""
if not self.db_sync_done() and hookenv.is_leader():
try:
f = open("/var/log/gnocchi/gnocchi-upgrade.log", "w+")
subprocess.check_call(self.sync_cmd,
stdout=f,
stderr=subprocess.STDOUT)
hookenv.leader_set({'db-sync-done': True})
# Restart services immediately after db sync as
# render_domain_config needs a working system
self.restart_all()
except subprocess.CalledProcessError as e:
hookenv.status_set('blocked', 'An error occured while ' +
'running gnocchi-upgrade. Logs available ' +
'in /var/log/gnocchi/gnocchi-upgrade.log')
hookenv.log(e, hookenv.DEBUG)
raise e
class GnocchiCharm(GnochiCharmBase):
def do_openstack_upgrade_db_migration(self):
"""Overrides do_openstack_upgrade_db_migration for Openstack
upgrades. This function's purpose is to run a database migration
after the Openstack upgrade. A check of the S3 connection is
required first to avoid a failed migration, in the case of an S3
storage backend.
:returns: None
"""
self.db_sync()
def states_to_check(self, required_relations=None):
"""Custom states to check function.
Construct a custom set of connected and available states for each
of the relations passed, along with error messages and new status
conditions.
:param self: Self
:type self: GnocchiCharm instance
:param required_relations: List of relations which overrides
self.relations
:type required_relations: list of strings
:returns: {relation: [(state, err_status, err_msg), (...),]}
:rtype: dict
"""
states_to_check = super().states_to_check(required_relations)
states_to_check["gnocchi-upgrade"] = [
("gnocchi-storage-configuration.ready",
"blocked",
"Mandatory S3 configuration parameters missing."),
("gnocchi-storage-authentication.ready",
"blocked",
"Authentication to the storage backend failed. " +
"Please verify your S3 credentials."),
("gnocchi-storage-network.ready",
"blocked",
"Could not connect to the storage backend endpoint URL. " +
"Please verify your network and your s3 endpoint URL."),
("gnocchi-upgrade.ready",
"error",
"Storage backend not ready. Check logs for troubleshooting.")
]
return states_to_check
class GnocchiCharm(GnocchiCharmBase):
"""
Charm for Juju deployment of Gnocchi
@ -196,7 +280,7 @@ class GnocchiCharm(GnochiCharmBase):
# List of packages to install for this charm
packages = ['gnocchi-api', 'gnocchi-metricd', 'python-apt',
'ceph-common', 'python-rados', 'python-keystonemiddleware',
'apache2', 'libapache2-mod-wsgi']
'apache2', 'libapache2-mod-wsgi', 'python-boto3']
services = ['gnocchi-metricd', 'apache2']
@ -255,10 +339,10 @@ class GnocchiQueensCharm(GnocchiCharm):
packages = ['gnocchi-api', 'gnocchi-metricd', 'python3-apt',
'ceph-common', 'python3-rados', 'python3-keystonemiddleware',
'python3-memcache']
'python3-memcache', 'python3-boto3']
class GnocchiSnapCharm(GnochiCharmBase):
class GnocchiSnapCharm(GnocchiCharmBase):
"""
Charm for Juju deployment of Gnocchi via Snap

View File

@ -19,7 +19,8 @@ provides:
metric-service:
interface: gnocchi
requires:
storage-ceph:
interface: ceph-client
coordinator-memcached:
interface: memcache
storage-ceph:
interface: ceph-client
optional: True

View File

@ -15,6 +15,9 @@
import charms_openstack.charm as charm
import charms.reactive as reactive
import boto3
import botocore
import charm.openstack.gnocchi as gnocchi # noqa
import charmhelpers.core.hookenv as hookenv
@ -32,15 +35,85 @@ charm.use_defaults(
required_interfaces = ['coordinator-memcached.available',
'shared-db.available',
'identity-service.available',
'storage-ceph.pools.available']
'identity-service.available']
if hookenv.config('storage-backend').lower() == 'ceph':
required_interfaces.append('storage-ceph.pools.available')
storage_config = ['config.changed.storage-backend',
'config.changed.s3-endpoint-url',
'config.changed.s3-region-name',
'config.changed.s3-access-key-id',
'config.changed.s3-secret-access-key']
@reactive.when_any(*storage_config)
def storage_backend_connection():
"""Test the connection to the S3 backend provided."""
reactive.clear_flag('gnocchi-upgrade.ready')
reactive.clear_flag('storage-ceph.needed')
reactive.set_flag('gnocchi-storage-configuration.ready')
reactive.set_flag('gnocchi-storage-authentication.ready')
reactive.set_flag('gnocchi-storage-network.ready')
with charm.provide_charm_instance() as charm_class:
if charm_class.options.storage_backend == 's3':
kwargs = {
'region_name': charm_class.options.s3_region_name,
'aws_access_key_id': charm_class.options.s3_access_key_id,
'aws_secret_access_key':
charm_class.options.s3_secret_access_key,
'endpoint_url': charm_class.options.s3_endpoint_url,
}
for value in kwargs.values():
if not value:
hookenv.log('Mandatory S3 configuration parameters ' +
'missing.', hookenv.DEBUG)
reactive.clear_flag('gnocchi-storage-configuration.ready')
return
try:
boto3.client('s3', **kwargs)
hookenv.log('S3 successfully reachable.', hookenv.DEBUG)
reactive.set_flag('gnocchi-upgrade.ready')
except botocore.exceptions.ClientError as e:
hookenv.log("Authentication to S3 backend failed. Error : " +
"{}".format(e), hookenv.DEBUG)
reactive.clear_flag('gnocchi-storage-authentication.ready')
return
except botocore.exceptions.EndpointConnectionError as e:
hookenv.log("Could not connect to the endpoint URL: Error : " +
"{}".format(e), hookenv.DEBUG)
reactive.clear_flag('gnocchi-storage-network.ready')
return
except botocore.exceptions.SSLError as e:
# this status check does not check for ssl validation
reactive.set_flag('gnocchi-upgrade.ready')
return
except Exception as e:
hookenv.log("An error occured when trying to reach the S3 " +
"backend: {}".format(e), hookenv.DEBUG)
return
elif charm_class.options.storage_backend == 'ceph':
reactive.set_flag('storage-ceph.needed')
reactive.set_flag('gnocchi-upgrade.ready')
return
else:
reactive.set_flag('gnocchi-upgrade.ready')
@reactive.when('gnocchi-upgrade.ready')
@reactive.when(*required_interfaces)
def render_config(*args):
"""Render the configuration for charm when all the interfaces are
available.
Note that the storage-ceph interface is optional and thus is only
used if it is available.
"""
with charm.provide_charm_instance() as charm_class:
charm_class.upgrade_if_available(args)
charm_class.configure_ssl()
@ -50,12 +123,13 @@ def render_config(*args):
reactive.set_state('config.rendered')
# db_sync checks if sync has been done so rerunning is a noop
# db_sync checks if sync has been done so rerunning is a noop.
@reactive.when('config.rendered')
@reactive.when_not('db.synced')
def init_db():
with charm.provide_charm_instance() as charm_class:
charm_class.db_sync()
charm_class.assess_status()
hookenv.log("Database synced", hookenv.DEBUG)
reactive.set_state('db.synced')
@ -92,6 +166,7 @@ def check_ceph_request_status(ceph):
ceph.changed()
@reactive.when('storage-ceph.needed')
@reactive.when_not('storage-ceph.connected')
def storage_ceph_disconnected():
with charm.provide_charm_instance() as charm_instance:
@ -118,6 +193,7 @@ def provide_gnocchi_url(metric_service):
metric_service.set_gnocchi_url(charm_class.public_url)
@reactive.when('storage-ceph.needed')
@reactive.when_not('storage-ceph.connected')
@reactive.when_not('storage-ceph.pools.available')
def reset_state_create_pool_req_sent():

View File

@ -4,7 +4,7 @@
# local changes will be overwritten.
###############################################################################
[global]
{% if storage_ceph.auth -%}
{% if options.storage_backend == 'ceph' and storage_ceph.auth -%}
auth_supported = {{ storage_ceph.auth }}
mon host = {{ storage_ceph.monitors }}
{% endif -%}

View File

@ -26,12 +26,21 @@ workers = {{ options.workers }}
coordination_url = {{ coordinator_memcached.url }}
{%- endif %}
{% if storage_ceph.key -%}
{% if options.storage_backend == 'ceph' and storage_ceph.key -%}
driver = ceph
ceph_pool = {{ options.application_name }}
ceph_username = {{ options.application_name }}
ceph_secret = {{ storage_ceph.key }}
ceph_conffile = {{ options.ceph_config }}
{% elif options.storage_backend == 's3' -%}
driver = s3
s3_endpoint_url = {{ options.s3_endpoint_url }}
s3_region_name = {{ options.s3_region_name }}
s3_access_key_id = {{ options.s3_access_key_id }}
s3_secret_access_key = {{ options.s3_secret_access_key }}
s3_bucket_prefix = {{ options.s3_bucket_prefix }}
s3_check_consistency_timeout = {{ options.s3_check_consistency_timeout }}
s3_max_pool_connections = {{ options.s3_max_pool_connections }}
{%- endif %}
{% include "parts/section-keystone-authtoken" %}

View File

@ -26,14 +26,24 @@ url = {{ shared_db.uri }}
workers = {{ options.workers }}
[storage]
{% if storage_ceph.key -%}
{% if options.storage_backend == 'ceph' and storage_ceph.key -%}
driver = ceph
ceph_pool = {{ options.application_name }}
ceph_username = {{ options.application_name }}
ceph_secret = {{ storage_ceph.key }}
ceph_conffile = {{ options.ceph_config }}
{% elif options.storage_backend == 's3' -%}
driver = s3
s3_endpoint_url = {{ options.s3_endpoint_url }}
s3_region_name = {{ options.s3_region_name }}
s3_access_key_id = {{ options.s3_access_key_id }}
s3_secret_access_key = {{ options.s3_secret_access_key }}
s3_bucket_prefix = {{ options.s3_bucket_prefix }}
s3_check_consistency_timeout = {{ options.s3_check_consistency_timeout }}
s3_max_pool_connections = {{ options.s3_max_pool_connections }}
{%- endif %}
{% include "parts/section-keystone-authtoken" %}
{% include "parts/section-oslo-middleware" %}

View File

@ -0,0 +1,124 @@
variables:
openstack-origin: &openstack-origin cloud:bionic-stein
series: &series bionic
machines:
0:
constraints: "mem=3072M"
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
# We specify machine placements for these to improve iteration
# time, given that machine "0" comes up way before machine "6"
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
source: *openstack-origin
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
options:
source: *openstack-origin
to:
- '1'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '2'
ceilometer:
charm: cs:~openstack-charmers-next/ceilometer
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '3'
gnocchi:
series: *series
charm: ../../../gnocchi
num_units: 1
options:
openstack-origin: *openstack-origin
storage-backend: s3
to:
- '4'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '5'
#swift-proxy is used to test gnocchi against an S3 storage backend
swift-proxy:
charm: swift-proxy
series: bionic
num_units: 1
options:
zone-assignment: manual
replicas: 1
swift-hash: fdfef9d4-8b06-11e2-8ac0-531c923c8fae
openstack-origin: *openstack-origin
to:
- '6'
swift-storage:
charm: cs:~openstack-charmers-next/swift-storage
num_units: 1
storage:
block-devices: 'cinder,10G'
options:
openstack-origin: *openstack-origin
zone: 1
to:
- '7'
vault:
charm: cs:~openstack-charmers-next/vault
num_units: 1
series: *series
to:
- '8'
relations:
- - keystone:shared-db
- percona-cluster:shared-db
- - ceilometer:amqp
- rabbitmq-server:amqp
- - ceilometer:identity-credentials
- keystone:identity-credentials
- - ceilometer:identity-notifications
- keystone:identity-notifications
- - ceilometer:metric-service
- gnocchi:metric-service
- - gnocchi:identity-service
- keystone:identity-service
- - gnocchi:shared-db
- percona-cluster:shared-db
- - gnocchi:coordinator-memcached
- memcached:cache
- - swift-proxy:identity-service
- keystone:identity-service
- - swift-storage:swift-storage
- swift-proxy:swift-storage
- - vault:shared-db
- percona-cluster:shared-db
- - vault:certificates
- swift-proxy:certificates
- - vault:certificates
- gnocchi:certificates
- - vault:certificates
- ceilometer:certificates
- - vault:certificates
- keystone:certificates
- - vault:certificates
- rabbitmq-server:certificates

View File

@ -0,0 +1,123 @@
variables:
openstack-origin: &openstack-origin cloud:bionic-train
series: &series bionic
machines:
0:
constraints: "mem=3072M"
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
# We specify machine placements for these to improve iteration
# time, given that machine "0" comes up way before machine "6"
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
source: *openstack-origin
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
options:
source: *openstack-origin
to:
- '1'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '2'
ceilometer:
charm: cs:~openstack-charmers-next/ceilometer
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '3'
gnocchi:
series: *series
charm: ../../../gnocchi
num_units: 1
options:
openstack-origin: *openstack-origin
storage-backend: s3
to:
- '4'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '5'
#swift-proxy is used to test gnocchi against an S3 storage backend
swift-proxy:
charm: swift-proxy
series: bionic
num_units: 1
options:
zone-assignment: manual
replicas: 1
swift-hash: fdfef9d4-8b06-11e2-8ac0-531c923c8fae
openstack-origin: *openstack-origin
to:
- '6'
swift-storage:
charm: cs:~openstack-charmers-next/swift-storage
num_units: 1
storage:
block-devices: 'cinder,10G'
options:
openstack-origin: *openstack-origin
zone: 1
to:
- '7'
vault:
charm: cs:~openstack-charmers-next/vault
num_units: 1
series: *series
to:
- '8'
relations:
- - keystone:shared-db
- percona-cluster:shared-db
- - ceilometer:amqp
- rabbitmq-server:amqp
- - ceilometer:identity-credentials
- keystone:identity-credentials
- - ceilometer:identity-notifications
- keystone:identity-notifications
- - ceilometer:metric-service
- gnocchi:metric-service
- - gnocchi:identity-service
- keystone:identity-service
- - gnocchi:shared-db
- percona-cluster:shared-db
- - gnocchi:coordinator-memcached
- memcached:cache
- - swift-proxy:identity-service
- keystone:identity-service
- - swift-storage:swift-storage
- swift-proxy:swift-storage
- - vault:shared-db
- percona-cluster:shared-db
- - vault:certificates
- swift-proxy:certificates
- - vault:certificates
- gnocchi:certificates
- - vault:certificates
- ceilometer:certificates
- - vault:certificates
- keystone:certificates
- - vault:certificates
- rabbitmq-server:certificates

View File

@ -0,0 +1,123 @@
variables:
openstack-origin: &openstack-origin cloud:bionic-ussuri
series: &series bionic
machines:
0:
constraints: "mem=3072M"
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
# We specify machine placements for these to improve iteration
# time, given that machine "0" comes up way before machine "6"
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
source: *openstack-origin
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
options:
source: *openstack-origin
to:
- '1'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '2'
ceilometer:
charm: cs:~openstack-charmers-next/ceilometer
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '3'
gnocchi:
series: *series
charm: ../../../gnocchi
num_units: 1
options:
openstack-origin: *openstack-origin
storage-backend: s3
to:
- '4'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '5'
#swift-proxy is used to test gnocchi against an S3 storage backend
swift-proxy:
charm: swift-proxy
series: bionic
num_units: 1
options:
zone-assignment: manual
replicas: 1
swift-hash: fdfef9d4-8b06-11e2-8ac0-531c923c8fae
openstack-origin: *openstack-origin
to:
- '6'
swift-storage:
charm: cs:~openstack-charmers-next/swift-storage
num_units: 1
storage:
block-devices: 'cinder,10G'
options:
openstack-origin: *openstack-origin
zone: 1
to:
- '7'
vault:
charm: cs:~openstack-charmers-next/vault
num_units: 1
series: *series
to:
- '8'
relations:
- - keystone:shared-db
- percona-cluster:shared-db
- - ceilometer:amqp
- rabbitmq-server:amqp
- - ceilometer:identity-credentials
- keystone:identity-credentials
- - ceilometer:identity-notifications
- keystone:identity-notifications
- - ceilometer:metric-service
- gnocchi:metric-service
- - gnocchi:identity-service
- keystone:identity-service
- - gnocchi:shared-db
- percona-cluster:shared-db
- - gnocchi:coordinator-memcached
- memcached:cache
- - swift-proxy:identity-service
- keystone:identity-service
- - swift-storage:swift-storage
- swift-proxy:swift-storage
- - vault:shared-db
- percona-cluster:shared-db
- - vault:certificates
- swift-proxy:certificates
- - vault:certificates
- gnocchi:certificates
- - vault:certificates
- ceilometer:certificates
- - vault:certificates
- keystone:certificates
- - vault:certificates
- rabbitmq-server:certificates

View File

@ -0,0 +1,122 @@
variables:
openstack-origin: &openstack-origin distro
series: &series eoan
machines:
0:
constraints: "mem=3072M"
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
# We specify machine placements for these to improve iteration
# time, given that machine "0" comes up way before machine "6"
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
source: *openstack-origin
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
options:
source: *openstack-origin
to:
- '1'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '2'
ceilometer:
charm: cs:~openstack-charmers-next/ceilometer
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '3'
gnocchi:
series: *series
charm: ../../../gnocchi
num_units: 1
options:
openstack-origin: *openstack-origin
storage-backend: s3
to:
- '4'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '5'
#swift-proxy is used to test gnocchi against an S3 storage backend
swift-proxy:
charm: swift-proxy
num_units: 1
options:
zone-assignment: manual
replicas: 1
swift-hash: fdfef9d4-8b06-11e2-8ac0-531c923c8fae
openstack-origin: *openstack-origin
to:
- '6'
swift-storage:
charm: cs:~openstack-charmers-next/swift-storage
num_units: 1
storage:
block-devices: 'cinder,10G'
options:
openstack-origin: *openstack-origin
zone: 1
to:
- '7'
vault:
charm: cs:~openstack-charmers-next/vault
num_units: 1
series: *series
to:
- '8'
relations:
- - keystone:shared-db
- percona-cluster:shared-db
- - ceilometer:amqp
- rabbitmq-server:amqp
- - ceilometer:identity-credentials
- keystone:identity-credentials
- - ceilometer:identity-notifications
- keystone:identity-notifications
- - ceilometer:metric-service
- gnocchi:metric-service
- - gnocchi:identity-service
- keystone:identity-service
- - gnocchi:shared-db
- percona-cluster:shared-db
- - gnocchi:coordinator-memcached
- memcached:cache
- - swift-proxy:identity-service
- keystone:identity-service
- - swift-storage:swift-storage
- swift-proxy:swift-storage
- - vault:shared-db
- percona-cluster:shared-db
- - vault:certificates
- swift-proxy:certificates
- - vault:certificates
- gnocchi:certificates
- - vault:certificates
- ceilometer:certificates
- - vault:certificates
- keystone:certificates
- - vault:certificates
- rabbitmq-server:certificates

View File

@ -0,0 +1,145 @@
variables:
openstack-origin: &openstack-origin distro
series: &series focal
machines:
0:
constraints: "mem=3072M"
1:
constraints: "mem=3072M"
2:
constraints: "mem=3072M"
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10:
series: bionic
# We specify machine placements for these to improve iteration
# time, given that machine "0" comes up way before machine "6"
applications:
keystone-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
gnocchi-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
vault-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
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-next/keystone
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '4'
ceilometer:
charm: cs:~openstack-charmers-next/ceilometer
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '5'
gnocchi:
series: *series
charm: ../../../gnocchi
num_units: 1
options:
openstack-origin: *openstack-origin
storage-backend: s3
to:
- '6'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
# holding at bionic as memcached doesn't support focal yet
series: bionic
to:
- '10'
#swift-proxy is used to test gnocchi against an S3 storage backend
swift-proxy:
charm: swift-proxy
num_units: 1
options:
zone-assignment: manual
replicas: 1
swift-hash: fdfef9d4-8b06-11e2-8ac0-531c923c8fae
openstack-origin: *openstack-origin
to:
- '7'
swift-storage:
charm: cs:~openstack-charmers-next/swift-storage
num_units: 1
storage:
block-devices: 'cinder,10G'
options:
openstack-origin: *openstack-origin
zone: 1
to:
- '8'
vault:
charm: cs:~openstack-charmers-next/vault
num_units: 1
series: *series
to:
- '9'
relations:
- - keystone:shared-db
- keystone-mysql-router:shared-db
- - keystone-mysql-router:db-router
- mysql-innodb-cluster:db-router
- - gnocchi:shared-db
- gnocchi-mysql-router:shared-db
- - gnocchi-mysql-router:db-router
- mysql-innodb-cluster:db-router
- - ceilometer:amqp
- rabbitmq-server:amqp
- - ceilometer:identity-credentials
- keystone:identity-credentials
- - ceilometer:identity-notifications
- keystone:identity-notifications
- - ceilometer:metric-service
- gnocchi:metric-service
- - gnocchi:identity-service
- keystone:identity-service
- - gnocchi:coordinator-memcached
- memcached:cache
- - swift-proxy:identity-service
- keystone:identity-service
- - swift-storage:swift-storage
- swift-proxy:swift-storage
- - vault:shared-db
- vault-mysql-router:shared-db
- - vault-mysql-router:db-router
- mysql-innodb-cluster:db-router
- - vault:certificates
- swift-proxy:certificates
- - vault:certificates
- gnocchi:certificates
- - vault:certificates
- ceilometer:certificates
- - vault:certificates
- keystone:certificates
- - vault:certificates
- rabbitmq-server:certificates

View File

@ -10,21 +10,41 @@ gate_bundles:
- bionic-train
- bionic-ussuri
- focal-ussuri
- test-s3: bionic-stein-s3
- test-s3: bionic-train-s3
- test-s3: bionic-ussuri-s3
- test-s3: focal-ussuri-s3
smoke_bundles:
- bionic-train
- test-s3: bionic-train-s3
dev_bundles:
- eoan-train
tests:
- zaza.openstack.charm_tests.gnocchi.tests.GnocchiTest
- test-s3: eoan-train-s3
configure:
- zaza.openstack.charm_tests.ceilometer.setup.basic_setup
- test-s3:
- zaza.openstack.charm_tests.vault.setup.auto_initialize
- zaza.openstack.charm_tests.gnocchi.setup.configure_s3_backend
- zaza.openstack.charm_tests.ceilometer.setup.basic_setup
tests:
- zaza.openstack.charm_tests.gnocchi.tests.GnocchiTest
- test-s3:
- zaza.openstack.charm_tests.gnocchi.tests.GnocchiS3Test
- zaza.openstack.charm_tests.gnocchi.tests.GnocchiTest
target_deploy_status:
vault:
workload-status: blocked
workload-status-message: Vault needs to be initialized
ceilometer:
workload-status: blocked
workload-status-message: Run the ceilometer-upgrade action on the leader to initialize ceilometer and gnocchi
workload-status-message: ''
mongodb:
workload-status: unknown
workload-status-message: ''
gnocchi:
workload-status: blocked
workload-status-message: Mandatory S3 configuration parameters missing.
tests_options:
force_deploy:
- focal-ussuri
- focal-ussuri-s3

1
src/wheelhouse.txt Normal file
View File

@ -0,0 +1 @@
boto3

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import mock
import sys
sys.path.append('src')
@ -38,5 +39,9 @@ def mock_more_stuff():
charmhelpers.contrib.storage.linux.ceph
)
boto3 = mock.MagicMock()
botocore = mock.MagicMock()
sys.modules['boto3'] = boto3
sys.modules['botocore'] = botocore
mock_more_stuff()

View File

@ -37,11 +37,14 @@ class TestRegisteredHooks(test_utils.TestRegisteredHooks):
'certificates.available']
hook_set = {
'when': {
'define_storage_states': (
'config.changed.storage-backend',
),
'render_config': (
'coordinator-memcached.available',
'shared-db.available',
'identity-service.available',
'storage-ceph.pools.available',
'gnocchi-upgrade.ready',
),
'init_db': (
'config.rendered',
@ -63,6 +66,12 @@ class TestRegisteredHooks(test_utils.TestRegisteredHooks):
'check_ceph_request_status': (
'storage-ceph.connected',
),
'storage_ceph_disconnected': (
'storage-ceph.needed',
),
'reset_state_create_pool_req_sent': (
'storage-ceph.needed',
)
},
'when_not': {
'storage_ceph_disconnected': (
@ -106,6 +115,8 @@ class TestHandlers(test_utils.PatchHelper):
def test_render_stuff(self):
self.patch_object(handlers.reactive, 'set_state')
self.patch_object(handlers.charm, 'optional_interfaces')
handlers.render_config('arg1', 'arg2')
self.gnocchi_charm.render_with_interfaces.assert_called_once_with(
('arg1', 'arg2')