Merge "Add identity-credentials relation support" into stable/wallaby
This commit is contained in:
commit
7cd922842d
34
README.md
34
README.md
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
1
hooks/identity-credentials-relation-broken
Symbolic link
1
hooks/identity-credentials-relation-broken
Symbolic link
@ -0,0 +1 @@
|
||||
cinder_hooks.py
|
1
hooks/identity-credentials-relation-changed
Symbolic link
1
hooks/identity-credentials-relation-changed
Symbolic link
@ -0,0 +1 @@
|
||||
cinder_hooks.py
|
1
hooks/identity-credentials-relation-joined
Symbolic link
1
hooks/identity-credentials-relation-joined
Symbolic link
@ -0,0 +1 @@
|
||||
cinder_hooks.py
|
@ -26,6 +26,9 @@ requires:
|
||||
interface: rabbitmq
|
||||
identity-service:
|
||||
interface: keystone
|
||||
optional: true
|
||||
identity-credentials:
|
||||
interface: keystone-credentials
|
||||
ceph:
|
||||
interface: ceph-client
|
||||
image-service:
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user