Merge "Add identity-credentials relation support" into stable/wallaby

This commit is contained in:
Zuul 2023-02-16 12:55:50 +00:00 committed by Gerrit Code Review
commit 7cd922842d
8 changed files with 106 additions and 0 deletions

View File

@ -97,8 +97,42 @@ Cinder can be backed by a NetApp appliance local to the cinder unit, where
volumes are offered via iSCSI or NFS. This functionality is provided by the
[cinder-netapp][cinder-netapp-charm] subordinate charm.
### Pure Storage-backed storage
Cinder can be backed by a Pure Storage appliance reachable by its API endpoint.
This functionality is provided by the
[cinder-purestorage][cinder-purestorage-charm] subordinate charm.
## Separate Volume Service
For certain operations when an instance is not involved, the cinder application
will connect directly to the storage for operations such as cloning a volume
from a glance image. You can deploy a second cinder application for the volume
service only where the primary cinder application cannot connect to this
storage. This may be required for iSCSI connections because LXD containers
cannot create iSCSI connections or where you need a physical Fibre Channel
connection. This is not required for Ceph deployments which use userspace RBD
tools.
1. Deploy cinder with enabled-services=api,scheduler
2. Deploy a second application of cinder named 'cinder-volume' with
enabled-services=volume
3. Relate the storage subordinate (e.g. cinder-purestorage) to the
cinder-volume application only (not to the 'cinder' application)
4. Keystone should be related to cinder:identity-__service__ but
cinder-volume:identity-__credentials__
The primary cinder application gets keystone credentials when registering a
service endpoint via the identity-service relation. The cinder-volume
application does not register a service, so we need to relate
identity-credentials instead. The image volume cache will not work without
this relation.
5. Both cinder and cinder-volume should otherwise have the same relations
## High availability
This charm supports high availability via HAcluster.
When more than one unit is deployed with the [hacluster][hacluster-charm]
application the charm will bring up an HA active/active cluster.

View File

@ -465,6 +465,21 @@ def identity_changed():
configure_https()
@hooks.hook('identity-credentials-relation-joined')
def identity_credentials_joined(rid=None):
if service_enabled('volume') and not service_enabled('api'):
settings = {'username': 'cinder', 'requested_roles': 'Admin'}
relation_set(relation_id=rid, **settings)
@hooks.hook('identity-credentials-relation-changed')
@restart_on_change(restart_map())
def identity_credentials_changed():
if service_enabled('volume') and not service_enabled('api'):
if 'identity-credentials' in CONFIGS.complete_contexts():
CONFIGS.write(CINDER_CONF)
@hooks.hook('ceph-relation-joined')
def ceph_joined():
if not os.path.isdir('/etc/ceph'):
@ -582,6 +597,7 @@ def image_service_changed():
@hooks.hook('amqp-relation-broken',
'identity-service-relation-broken',
'identity-credentials-relation-broken',
'image-service-relation-broken',
'shared-db-relation-broken')
@restart_on_change(restart_map(), stopstart=True)

View File

@ -218,6 +218,9 @@ BASE_RESOURCE_MAP = OrderedDict([
config_file=CINDER_CONF),
cinder_contexts.StorageBackendContext(),
cinder_contexts.LoggingConfigContext(),
context.IdentityCredentialsContext(
service='cinder',
service_user='cinder'),
context.IdentityServiceContext(
service='cinder',
service_user='cinder'),
@ -874,6 +877,9 @@ def get_optional_interfaces():
if relation_ids('image-service'):
optional_interfaces['image'] = ['image-service']
if service_enabled('volume') and not service_enabled('api'):
optional_interfaces['identity-credentials'] = ['identity-credentials']
return optional_interfaces

View File

@ -0,0 +1 @@
cinder_hooks.py

View File

@ -0,0 +1 @@
cinder_hooks.py

View File

@ -0,0 +1 @@
cinder_hooks.py

View File

@ -26,6 +26,9 @@ requires:
interface: rabbitmq
identity-service:
interface: keystone
optional: true
identity-credentials:
interface: keystone-credentials
ceph:
interface: ceph-client
image-service:

View File

@ -126,6 +126,14 @@ class TestChangedHooks(CharmTestCase):
'identity-service': ['identity-service:1'],
}
def svc_enabled(self, svc):
enabled = self.test_config.get('enabled-services')
if enabled == 'all':
return True
return svc in enabled
def setUp(self):
super(TestChangedHooks, self).setUp(hooks, TO_PATCH)
self.config.side_effect = self.test_config.get
@ -328,6 +336,42 @@ class TestChangedHooks(CharmTestCase):
hooks.hooks.execute(['hooks/identity-service-relation-changed'])
self.assertFalse(self.CONFIGS.write.called)
@patch.object(hooks, 'service_enabled')
def test_identity_credentials_joined_without_api(self, service_enabled):
'It requests keystone credentials without API service'
self.test_config.set('enabled-services', 'volume')
service_enabled.side_effect = self.svc_enabled
hooks.hooks.execute(['hooks/identity-credentials-relation-joined'])
expected = {'relation_id': None,
'username': 'cinder',
'requested_roles': 'Admin'}
self.relation_set.assert_called_with(**expected)
@patch.object(hooks, 'service_enabled')
def test_identity_credentials_joined_with_api(self, service_enabled):
'It requests keystone credentials with API service'
self.test_config.set('enabled-services', 'all')
service_enabled.side_effect = self.svc_enabled
hooks.hooks.execute(['hooks/identity-credentials-relation-joined'])
self.relation_set.assert_not_called()
@patch.object(hooks, 'service_enabled')
def test_identity_credentials_changed(self, service_enabled):
'It writes out cinder.conf on identity-credentials changed'
self.CONFIGS.complete_contexts.return_value = ['identity-credentials']
self.test_config.set('enabled-services', 'volume')
service_enabled.side_effect = self.svc_enabled
hooks.hooks.execute(['hooks/identity-credentials-relation-changed'])
self.CONFIGS.write.assert_called_with('/etc/cinder/cinder.conf')
@patch.object(hooks, 'service_enabled')
def test_identity_credentials_changed_incomplete(self, service_enabled):
'It does not write cinder.conf with incomplete identity-service'
self.test_config.set('enabled-services', 'volume')
service_enabled.side_effect = self.svc_enabled
hooks.hooks.execute(['hooks/identity-credentials-relation-changed'])
self.assertFalse(self.CONFIGS.write.called)
@patch.object(hooks, 'identity_joined')
def test_configure_https_enable(self, identity_joined):
'It enables https from hooks when we have https data'