Advertise Nova API readiness
Adds a new relation 'nova-api' that can be used by services that consume the nova api in some way or another. We use it to simply pass a flag to remote services that states whether the API service is ready to be used, based on the complete context of required interfaces.
This commit is contained in:
parent
00791f3f9d
commit
962790239b
|
@ -81,6 +81,7 @@ from nova_cc_utils import (
|
|||
do_openstack_upgrade,
|
||||
enable_services,
|
||||
git_install,
|
||||
is_api_ready,
|
||||
keystone_ca_cert_b64,
|
||||
migrate_neutron_database,
|
||||
migrate_nova_database,
|
||||
|
@ -286,6 +287,9 @@ def amqp_changed():
|
|||
[nova_cell_relation_joined(rid=rid)
|
||||
for rid in relation_ids('cell')]
|
||||
|
||||
for r_id in relation_ids('nova-api'):
|
||||
nova_api_relation_joined(rid=r_id)
|
||||
|
||||
|
||||
def conditional_neutron_migration():
|
||||
if os_release('nova-common') <= 'icehouse':
|
||||
|
@ -396,6 +400,9 @@ def postgresql_nova_db_changed():
|
|||
CONFIGS.write_all()
|
||||
leader_init_db_if_ready(skip_acl_check=True, skip_cells_restarts=True)
|
||||
|
||||
for r_id in relation_ids('nova-api'):
|
||||
nova_api_relation_joined(rid=r_id)
|
||||
|
||||
|
||||
@hooks.hook('pgsql-neutron-db-relation-changed')
|
||||
@service_guard(guard_map(), CONFIGS,
|
||||
|
@ -419,6 +426,12 @@ def image_service_changed():
|
|||
CONFIGS.write(NOVA_CONF)
|
||||
# TODO: special case config flag for essex (strip protocol)
|
||||
|
||||
for r_id in relation_ids('nova-api'):
|
||||
nova_api_relation_joined(rid=r_id)
|
||||
|
||||
for r_id in relation_ids('nova-api'):
|
||||
nova_api_relation_joined(rid=r_id)
|
||||
|
||||
|
||||
@hooks.hook('identity-service-relation-joined')
|
||||
def identity_joined(rid=None):
|
||||
|
@ -453,6 +466,9 @@ def identity_changed():
|
|||
[neutron_api_relation_joined(rid) for rid in relation_ids('neutron-api')]
|
||||
configure_https()
|
||||
|
||||
for r_id in relation_ids('nova-api'):
|
||||
nova_api_relation_joined(rid=r_id)
|
||||
|
||||
|
||||
@hooks.hook('nova-volume-service-relation-joined',
|
||||
'cinder-volume-service-relation-joined')
|
||||
|
@ -610,6 +626,9 @@ def compute_joined(rid=None, remote_restart=False):
|
|||
|
||||
@hooks.hook('cloud-compute-relation-changed')
|
||||
def compute_changed(rid=None, unit=None):
|
||||
for r_id in relation_ids('nova-api'):
|
||||
nova_api_relation_joined(rid=r_id)
|
||||
|
||||
rel_settings = relation_get(rid=rid, unit=unit)
|
||||
if 'migration_auth_type' not in rel_settings:
|
||||
return
|
||||
|
@ -1083,6 +1102,13 @@ def update_nova_consoleauth_config():
|
|||
log(str(e), level='DEBUG')
|
||||
|
||||
|
||||
def nova_api_relation_joined(rid=None):
|
||||
rel_data = {
|
||||
'nova-api-ready': 'yes' if is_api_ready(CONFIGS) else 'no'
|
||||
}
|
||||
relation_set(rid, **rel_data)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
hooks.execute(sys.argv)
|
||||
|
|
|
@ -35,6 +35,7 @@ from charmhelpers.contrib.openstack.utils import (
|
|||
git_src_dir,
|
||||
git_pip_venv_dir,
|
||||
git_yaml_value,
|
||||
incomplete_relation_data,
|
||||
is_ip,
|
||||
os_release,
|
||||
save_script_rc as _save_script_rc,
|
||||
|
@ -1385,3 +1386,7 @@ def check_optional_relations(configs):
|
|||
return status_get()
|
||||
else:
|
||||
return 'unknown', 'No optional relations'
|
||||
|
||||
|
||||
def is_api_ready(configs):
|
||||
return (not incomplete_relation_data(configs, REQUIRED_INTERFACES))
|
||||
|
|
|
@ -202,6 +202,12 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
self.assertTrue(self.save_script_rc.called)
|
||||
mock_filter_packages.assert_called_with([])
|
||||
|
||||
@patch.object(hooks, 'nova_api_relation_joined')
|
||||
def test_compute_changed_nova_api_trigger(self, api_joined):
|
||||
self.relation_ids.return_value = ['nova-api/0']
|
||||
hooks.compute_changed()
|
||||
api_joined.assert_called_with(rid='nova-api/0')
|
||||
|
||||
def test_compute_changed_ssh_migration(self):
|
||||
self.test_relation.set({
|
||||
'migration_auth_type': 'ssh', 'ssh_public_key': 'fookey',
|
||||
|
@ -441,17 +447,20 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
configs.write = MagicMock()
|
||||
hooks.postgresql_nova_db_changed()
|
||||
|
||||
@patch.object(hooks, 'nova_api_relation_joined')
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'conditional_neutron_migration')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_db_changed(self, configs, cond_neutron_mig,
|
||||
mock_is_db_initialised):
|
||||
mock_is_db_initialised, api_joined):
|
||||
self.relation_ids.return_value = ['nova-api/0']
|
||||
mock_is_db_initialised.return_value = False
|
||||
'No database migration is attempted when ACL list is not present'
|
||||
self._shared_db_test(configs)
|
||||
self.assertTrue(configs.write_all.called)
|
||||
self.assertFalse(self.migrate_nova_database.called)
|
||||
self.assertFalse(cond_neutron_mig.called)
|
||||
api_joined.asert_called_with(rid='nova-api/0')
|
||||
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
|
@ -479,13 +488,19 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
self.assertTrue(configs.write_all.called)
|
||||
self.assertFalse(self.migrate_nova_database.called)
|
||||
|
||||
@patch.object(hooks, 'nova_api_relation_joined')
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_postgresql_db_changed(self, configs, mock_is_db_initialised):
|
||||
def test_postgresql_db_changed(self, configs, mock_is_db_initialised,
|
||||
api_joined):
|
||||
self.relation_ids.side_effect = [
|
||||
[],
|
||||
['nova-api/0']]
|
||||
mock_is_db_initialised.return_value = False
|
||||
self._postgresql_db_test(configs)
|
||||
self.assertTrue(configs.write_all.called)
|
||||
self.migrate_nova_database.assert_called_with()
|
||||
api_joined.assert_called_with(rid='nova-api/0')
|
||||
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'nova_cell_relation_joined')
|
||||
|
@ -524,9 +539,11 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
self.assertTrue(configs.write_all.called)
|
||||
cell_joined.assert_called_with(rid='nova-cell-api/0')
|
||||
|
||||
@patch.object(hooks, 'nova_api_relation_joined')
|
||||
@patch.object(hooks, 'nova_cell_relation_joined')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_amqp_changed_api_rel(self, configs, cell_joined):
|
||||
def test_amqp_changed_api_rel(self, configs, cell_joined, api_joined):
|
||||
self.relation_ids.return_value = ['nova-api/0']
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = ['amqp']
|
||||
configs.write = MagicMock()
|
||||
|
@ -534,14 +551,19 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
hooks.amqp_changed()
|
||||
self.assertEquals(configs.write.call_args_list,
|
||||
[call('/etc/nova/nova.conf')])
|
||||
api_joined.assert_called_with(rid='nova-api/0')
|
||||
|
||||
@patch.object(hooks, 'nova_api_relation_joined')
|
||||
@patch.object(hooks, 'nova_cell_relation_joined')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_amqp_changed_noapi_rel(self, configs, cell_joined):
|
||||
def test_amqp_changed_noapi_rel(self, configs, cell_joined, api_joined):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = ['amqp']
|
||||
configs.write = MagicMock()
|
||||
self.relation_ids.return_value = ['nova-cell-api/0']
|
||||
self.relation_ids.side_effect = [
|
||||
['nova-cell-api/0'],
|
||||
['nova-api/0'],
|
||||
]
|
||||
self.is_relation_made.return_value = False
|
||||
self.network_manager.return_value = 'neutron'
|
||||
hooks.amqp_changed()
|
||||
|
@ -549,6 +571,7 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
[call('/etc/nova/nova.conf'),
|
||||
call('/etc/neutron/neutron.conf')])
|
||||
cell_joined.assert_called_with(rid='nova-cell-api/0')
|
||||
api_joined.assert_called_with(rid='nova-api/0')
|
||||
|
||||
@patch.object(hooks, 'canonical_url')
|
||||
def test_nova_cell_relation_joined(self, _canonical_url):
|
||||
|
@ -886,3 +909,17 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
])
|
||||
|
||||
mock_filter_packages.assert_called_with([])
|
||||
|
||||
@patch.object(hooks, 'is_api_ready')
|
||||
def _test_nova_api_relation_joined(self, tgt, is_api_ready):
|
||||
is_api_ready.return_value = tgt
|
||||
exp = 'yes' if tgt else 'no'
|
||||
hooks.nova_api_relation_joined(rid='foo')
|
||||
self.relation_set.assert_called_with(
|
||||
'foo', **{'nova-api-ready': exp})
|
||||
|
||||
def test_nova_api_relation_joined_ready(self):
|
||||
self._test_nova_api_relation_joined(True)
|
||||
|
||||
def test_nova_api_relation_joined_not_ready(self):
|
||||
self._test_nova_api_relation_joined(False)
|
||||
|
|
|
@ -1140,3 +1140,17 @@ class NovaCCUtilsTests(CharmTestCase):
|
|||
self.assertTrue(self.apt_update.called)
|
||||
self.apt_install.assert_called_with(['novnc', 'spice-html5',
|
||||
'websockify'], fatal=True)
|
||||
|
||||
def _test_is_api_ready(self, tgt):
|
||||
fake_config = MagicMock()
|
||||
with patch.object(utils, 'incomplete_relation_data') as ird:
|
||||
ird.return_value = (not tgt)
|
||||
self.assertEqual(utils.is_api_ready(fake_config), tgt)
|
||||
ird.assert_called_with(
|
||||
fake_config, utils.REQUIRED_INTERFACES)
|
||||
|
||||
def test_is_api_ready_true(self):
|
||||
self._test_is_api_ready(True)
|
||||
|
||||
def test_is_api_ready_false(self):
|
||||
self._test_is_api_ready(False)
|
||||
|
|
Loading…
Reference in New Issue