[yolanda,r=james-page] Add postgresql support
This commit is contained in:
commit
2acf85568d
@ -147,7 +147,8 @@ class SharedDBContext(OSContextGenerator):
|
|||||||
'database_host': rdata.get('db_host'),
|
'database_host': rdata.get('db_host'),
|
||||||
'database': self.database,
|
'database': self.database,
|
||||||
'database_user': self.user,
|
'database_user': self.user,
|
||||||
'database_password': rdata.get(password_setting)
|
'database_password': rdata.get(password_setting),
|
||||||
|
'database_type': 'mysql'
|
||||||
}
|
}
|
||||||
if context_complete(ctxt):
|
if context_complete(ctxt):
|
||||||
db_ssl(rdata, ctxt, self.ssl_dir)
|
db_ssl(rdata, ctxt, self.ssl_dir)
|
||||||
@ -155,6 +156,35 @@ class SharedDBContext(OSContextGenerator):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
class PostgresqlDBContext(OSContextGenerator):
|
||||||
|
interfaces = ['pgsql-db']
|
||||||
|
|
||||||
|
def __init__(self, database=None):
|
||||||
|
self.database = database
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
self.database = self.database or config('database')
|
||||||
|
if self.database is None:
|
||||||
|
log('Could not generate postgresql_db context. '
|
||||||
|
'Missing required charm config options. '
|
||||||
|
'(database name)')
|
||||||
|
raise OSContextError
|
||||||
|
ctxt = {}
|
||||||
|
|
||||||
|
for rid in relation_ids(self.interfaces[0]):
|
||||||
|
for unit in related_units(rid):
|
||||||
|
ctxt = {
|
||||||
|
'database_host': relation_get('host', rid=rid, unit=unit),
|
||||||
|
'database': self.database,
|
||||||
|
'database_user': relation_get('user', rid=rid, unit=unit),
|
||||||
|
'database_password': relation_get('password', rid=rid, unit=unit),
|
||||||
|
'database_type': 'postgresql',
|
||||||
|
}
|
||||||
|
if context_complete(ctxt):
|
||||||
|
return ctxt
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def db_ssl(rdata, ctxt, ssl_dir):
|
def db_ssl(rdata, ctxt, ssl_dir):
|
||||||
if 'ssl_ca' in rdata and ssl_dir:
|
if 'ssl_ca' in rdata and ssl_dir:
|
||||||
ca_path = os.path.join(ssl_dir, 'db-client.ca')
|
ca_path = os.path.join(ssl_dir, 'db-client.ca')
|
||||||
|
1
hooks/pgsql-db-relation-changed
Symbolic link
1
hooks/pgsql-db-relation-changed
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
quantum_hooks.py
|
1
hooks/pgsql-db-relation-joined
Symbolic link
1
hooks/pgsql-db-relation-joined
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
quantum_hooks.py
|
@ -5,6 +5,7 @@ from base64 import b64decode
|
|||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
log, ERROR, WARNING,
|
log, ERROR, WARNING,
|
||||||
config,
|
config,
|
||||||
|
is_relation_made,
|
||||||
relation_get,
|
relation_get,
|
||||||
relation_set,
|
relation_set,
|
||||||
relation_ids,
|
relation_ids,
|
||||||
@ -77,6 +78,8 @@ def config_changed():
|
|||||||
# Re-run joined hooks as config might have changed
|
# Re-run joined hooks as config might have changed
|
||||||
for r_id in relation_ids('shared-db'):
|
for r_id in relation_ids('shared-db'):
|
||||||
db_joined(relation_id=r_id)
|
db_joined(relation_id=r_id)
|
||||||
|
for r_id in relation_ids('pgsql-db'):
|
||||||
|
pgsql_db_joined(relation_id=r_id)
|
||||||
for r_id in relation_ids('amqp'):
|
for r_id in relation_ids('amqp'):
|
||||||
amqp_joined(relation_id=r_id)
|
amqp_joined(relation_id=r_id)
|
||||||
if valid_plugin():
|
if valid_plugin():
|
||||||
@ -95,12 +98,29 @@ def upgrade_charm():
|
|||||||
|
|
||||||
@hooks.hook('shared-db-relation-joined')
|
@hooks.hook('shared-db-relation-joined')
|
||||||
def db_joined(relation_id=None):
|
def db_joined(relation_id=None):
|
||||||
|
if is_relation_made('pgsql-db'):
|
||||||
|
# raise error
|
||||||
|
e = ('Attempting to associate a mysql database when there is already '
|
||||||
|
'associated a postgresql one')
|
||||||
|
log(e, level=ERROR)
|
||||||
|
raise Exception(e)
|
||||||
relation_set(username=config('database-user'),
|
relation_set(username=config('database-user'),
|
||||||
database=config('database'),
|
database=config('database'),
|
||||||
hostname=unit_get('private-address'),
|
hostname=unit_get('private-address'),
|
||||||
relation_id=relation_id)
|
relation_id=relation_id)
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.hook('pgsql-db-relation-joined')
|
||||||
|
def pgsql_db_joined():
|
||||||
|
if is_relation_made('shared-db'):
|
||||||
|
# raise error
|
||||||
|
e = ('Attempting to associate a postgresql database when there is already '
|
||||||
|
'associated a mysql one')
|
||||||
|
log(e, level=ERROR)
|
||||||
|
raise Exception(e)
|
||||||
|
relation_set(database=config('database'))
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('amqp-relation-joined')
|
@hooks.hook('amqp-relation-joined')
|
||||||
def amqp_joined(relation_id=None):
|
def amqp_joined(relation_id=None):
|
||||||
relation_set(relation_id=relation_id,
|
relation_set(relation_id=relation_id,
|
||||||
@ -118,6 +138,7 @@ def amqp_departed():
|
|||||||
|
|
||||||
|
|
||||||
@hooks.hook('shared-db-relation-changed',
|
@hooks.hook('shared-db-relation-changed',
|
||||||
|
'pgsql-db-relation-changed',
|
||||||
'amqp-relation-changed',
|
'amqp-relation-changed',
|
||||||
'cluster-relation-changed',
|
'cluster-relation-changed',
|
||||||
'cluster-relation-joined')
|
'cluster-relation-joined')
|
||||||
|
@ -77,12 +77,14 @@ QUANTUM_GATEWAY_PKGS = {
|
|||||||
"quantum-l3-agent",
|
"quantum-l3-agent",
|
||||||
"quantum-dhcp-agent",
|
"quantum-dhcp-agent",
|
||||||
'python-mysqldb',
|
'python-mysqldb',
|
||||||
|
'python-psycopg2',
|
||||||
"nova-api-metadata"
|
"nova-api-metadata"
|
||||||
],
|
],
|
||||||
NVP: [
|
NVP: [
|
||||||
"openvswitch-switch",
|
"openvswitch-switch",
|
||||||
"quantum-dhcp-agent",
|
"quantum-dhcp-agent",
|
||||||
'python-mysqldb',
|
'python-mysqldb',
|
||||||
|
'python-psycopg2',
|
||||||
"nova-api-metadata"
|
"nova-api-metadata"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -94,6 +96,7 @@ NEUTRON_GATEWAY_PKGS = {
|
|||||||
"neutron-l3-agent",
|
"neutron-l3-agent",
|
||||||
"neutron-dhcp-agent",
|
"neutron-dhcp-agent",
|
||||||
'python-mysqldb',
|
'python-mysqldb',
|
||||||
|
'python-psycopg2',
|
||||||
'python-oslo.config', # Force upgrade
|
'python-oslo.config', # Force upgrade
|
||||||
"nova-api-metadata",
|
"nova-api-metadata",
|
||||||
"neutron-plugin-metering-agent",
|
"neutron-plugin-metering-agent",
|
||||||
@ -103,6 +106,7 @@ NEUTRON_GATEWAY_PKGS = {
|
|||||||
NVP: [
|
NVP: [
|
||||||
"neutron-dhcp-agent",
|
"neutron-dhcp-agent",
|
||||||
'python-mysqldb',
|
'python-mysqldb',
|
||||||
|
'python-psycopg2',
|
||||||
'python-oslo.config', # Force upgrade
|
'python-oslo.config', # Force upgrade
|
||||||
"nova-api-metadata"
|
"nova-api-metadata"
|
||||||
]
|
]
|
||||||
@ -163,6 +167,7 @@ NOVA_CONFIG_FILES = {
|
|||||||
NOVA_CONF: {
|
NOVA_CONF: {
|
||||||
'hook_contexts': [context.AMQPContext(ssl_dir=NOVA_CONF_DIR),
|
'hook_contexts': [context.AMQPContext(ssl_dir=NOVA_CONF_DIR),
|
||||||
context.SharedDBContext(ssl_dir=NOVA_CONF_DIR),
|
context.SharedDBContext(ssl_dir=NOVA_CONF_DIR),
|
||||||
|
context.PostgresqlDBContext(),
|
||||||
NetworkServiceContext(),
|
NetworkServiceContext(),
|
||||||
QuantumGatewayContext()],
|
QuantumGatewayContext()],
|
||||||
'services': ['nova-api-metadata']
|
'services': ['nova-api-metadata']
|
||||||
|
@ -21,6 +21,8 @@ provides:
|
|||||||
requires:
|
requires:
|
||||||
shared-db:
|
shared-db:
|
||||||
interface: mysql-shared
|
interface: mysql-shared
|
||||||
|
pgsql-db:
|
||||||
|
interface: pgsql
|
||||||
amqp:
|
amqp:
|
||||||
interface: rabbitmq
|
interface: rabbitmq
|
||||||
peers:
|
peers:
|
||||||
|
@ -7,7 +7,7 @@ verbose=True
|
|||||||
api_paste_config=/etc/nova/api-paste.ini
|
api_paste_config=/etc/nova/api-paste.ini
|
||||||
enabled_apis=metadata
|
enabled_apis=metadata
|
||||||
multi_host=True
|
multi_host=True
|
||||||
sql_connection = mysql://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }}{% if database_ssl_ca %}?ssl_ca={{ database_ssl_ca }}{% if database_ssl_cert %}&ssl_cert={{ database_ssl_cert }}&ssl_key={{ database_ssl_key }}{% endif %}{% endif %}
|
{% include "parts/database" %}
|
||||||
quantum_metadata_proxy_shared_secret={{ shared_secret }}
|
quantum_metadata_proxy_shared_secret={{ shared_secret }}
|
||||||
service_quantum_metadata_proxy=True
|
service_quantum_metadata_proxy=True
|
||||||
# Access to message bus
|
# Access to message bus
|
||||||
|
@ -7,7 +7,7 @@ verbose=True
|
|||||||
api_paste_config=/etc/nova/api-paste.ini
|
api_paste_config=/etc/nova/api-paste.ini
|
||||||
enabled_apis=metadata
|
enabled_apis=metadata
|
||||||
multi_host=True
|
multi_host=True
|
||||||
sql_connection = mysql://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }}{% if database_ssl_ca %}?ssl_ca={{ database_ssl_ca }}{% if database_ssl_cert %}&ssl_cert={{ database_ssl_cert }}&ssl_key={{ database_ssl_key }}{% endif %}{% endif %}
|
{% include "parts/database" %}
|
||||||
quantum_metadata_proxy_shared_secret={{ shared_secret }}
|
quantum_metadata_proxy_shared_secret={{ shared_secret }}
|
||||||
service_quantum_metadata_proxy=True
|
service_quantum_metadata_proxy=True
|
||||||
# Access to message bus
|
# Access to message bus
|
||||||
|
@ -7,7 +7,7 @@ verbose= {{ verbose }}
|
|||||||
api_paste_config=/etc/nova/api-paste.ini
|
api_paste_config=/etc/nova/api-paste.ini
|
||||||
enabled_apis=metadata
|
enabled_apis=metadata
|
||||||
multi_host=True
|
multi_host=True
|
||||||
sql_connection = mysql://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }}{% if database_ssl_ca %}?ssl_ca={{ database_ssl_ca }}{% if database_ssl_cert %}&ssl_cert={{ database_ssl_cert }}&ssl_key={{ database_ssl_key }}{% endif %}{% endif %}
|
{% include "parts/database" %}
|
||||||
neutron_metadata_proxy_shared_secret={{ shared_secret }}
|
neutron_metadata_proxy_shared_secret={{ shared_secret }}
|
||||||
service_neutron_metadata_proxy=True
|
service_neutron_metadata_proxy=True
|
||||||
# Access to message bus
|
# Access to message bus
|
||||||
|
1
templates/parts/database
Normal file
1
templates/parts/database
Normal file
@ -0,0 +1 @@
|
|||||||
|
sql_connection = {{ database_type }}://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }}{% if database_ssl_ca %}?ssl_ca={{ database_ssl_ca }}{% if database_ssl_cert %}&ssl_cert={{ database_ssl_cert }}&ssl_key={{ database_ssl_key }}{% endif %}{% endif %}
|
@ -39,6 +39,7 @@ TO_PATCH = [
|
|||||||
'lsb_release',
|
'lsb_release',
|
||||||
'stop_services',
|
'stop_services',
|
||||||
'b64decode',
|
'b64decode',
|
||||||
|
'is_relation_made'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -115,6 +116,7 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
self.assertTrue(_config_changed.called)
|
self.assertTrue(_config_changed.called)
|
||||||
|
|
||||||
def test_db_joined(self):
|
def test_db_joined(self):
|
||||||
|
self.is_relation_made.return_value = False
|
||||||
self.unit_get.return_value = 'myhostname'
|
self.unit_get.return_value = 'myhostname'
|
||||||
self._call_hook('shared-db-relation-joined')
|
self._call_hook('shared-db-relation-joined')
|
||||||
self.relation_set.assert_called_with(
|
self.relation_set.assert_called_with(
|
||||||
@ -124,6 +126,32 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
relation_id=None
|
relation_id=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_db_joined_with_postgresql(self):
|
||||||
|
self.is_relation_made.return_value = True
|
||||||
|
|
||||||
|
with self.assertRaises(Exception) as context:
|
||||||
|
hooks.db_joined()
|
||||||
|
self.assertEqual(context.exception.message,
|
||||||
|
'Attempting to associate a mysql database when there '
|
||||||
|
'is already associated a postgresql one')
|
||||||
|
|
||||||
|
def test_postgresql_db_joined(self):
|
||||||
|
self.unit_get.return_value = 'myhostname'
|
||||||
|
self.is_relation_made.return_value = False
|
||||||
|
self._call_hook('pgsql-db-relation-joined')
|
||||||
|
self.relation_set.assert_called_with(
|
||||||
|
database='nova'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_postgresql_joined_with_db(self):
|
||||||
|
self.is_relation_made.return_value = True
|
||||||
|
|
||||||
|
with self.assertRaises(Exception) as context:
|
||||||
|
hooks.pgsql_db_joined()
|
||||||
|
self.assertEqual(context.exception.message,
|
||||||
|
'Attempting to associate a postgresql database when there '
|
||||||
|
'is already associated a mysql one')
|
||||||
|
|
||||||
def test_amqp_joined(self):
|
def test_amqp_joined(self):
|
||||||
self._call_hook('amqp-relation-joined')
|
self._call_hook('amqp-relation-joined')
|
||||||
self.relation_set.assert_called_with(
|
self.relation_set.assert_called_with(
|
||||||
@ -140,6 +168,10 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
self._call_hook('shared-db-relation-changed')
|
self._call_hook('shared-db-relation-changed')
|
||||||
self.CONFIGS.write_all.assert_called()
|
self.CONFIGS.write_all.assert_called()
|
||||||
|
|
||||||
|
def test_pgsql_db_changed(self):
|
||||||
|
self._call_hook('pgsql-db-relation-changed')
|
||||||
|
self.CONFIGS.write_all.assert_called()
|
||||||
|
|
||||||
def test_nm_changed(self):
|
def test_nm_changed(self):
|
||||||
self.relation_get.return_value = "cert"
|
self.relation_get.return_value = "cert"
|
||||||
self._call_hook('quantum-network-service-relation-changed')
|
self._call_hook('quantum-network-service-relation-changed')
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from mock import MagicMock, call, patch
|
from mock import MagicMock, call, patch
|
||||||
|
import collections
|
||||||
|
|
||||||
import charmhelpers.contrib.openstack.templating as templating
|
import charmhelpers.contrib.openstack.templating as templating
|
||||||
|
|
||||||
@ -46,6 +47,16 @@ TO_PATCH = [
|
|||||||
|
|
||||||
class TestQuantumUtils(CharmTestCase):
|
class TestQuantumUtils(CharmTestCase):
|
||||||
|
|
||||||
|
def assertDictEqual(self, d1, d2, msg=None): # assertEqual uses for dicts
|
||||||
|
for k,v1 in d1.iteritems():
|
||||||
|
self.assertIn(k, d2, msg)
|
||||||
|
v2 = d2[k]
|
||||||
|
if(isinstance(v1, collections.Iterable) and
|
||||||
|
not isinstance(v1, basestring)):
|
||||||
|
self.assertItemsEqual(v1, v2, msg)
|
||||||
|
else:
|
||||||
|
self.assertEqual(v1, v2, msg)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestQuantumUtils, self).setUp(quantum_utils, TO_PATCH)
|
super(TestQuantumUtils, self).setUp(quantum_utils, TO_PATCH)
|
||||||
self.networking_name.return_value = 'neutron'
|
self.networking_name.return_value = 'neutron'
|
||||||
@ -144,7 +155,6 @@ class TestQuantumUtils(CharmTestCase):
|
|||||||
quantum_utils.NEUTRON_L3_AGENT_CONF,
|
quantum_utils.NEUTRON_L3_AGENT_CONF,
|
||||||
quantum_utils.NEUTRON_OVS_PLUGIN_CONF,
|
quantum_utils.NEUTRON_OVS_PLUGIN_CONF,
|
||||||
quantum_utils.EXT_PORT_CONF]
|
quantum_utils.EXT_PORT_CONF]
|
||||||
print configs.register.calls()
|
|
||||||
for conf in confs:
|
for conf in confs:
|
||||||
configs.register.assert_any_call(
|
configs.register.assert_any_call(
|
||||||
conf,
|
conf,
|
||||||
@ -155,26 +165,33 @@ class TestQuantumUtils(CharmTestCase):
|
|||||||
def test_restart_map_ovs(self):
|
def test_restart_map_ovs(self):
|
||||||
self.config.return_value = 'ovs'
|
self.config.return_value = 'ovs'
|
||||||
ex_map = {
|
ex_map = {
|
||||||
quantum_utils.NEUTRON_L3_AGENT_CONF: ['neutron-l3-agent'],
|
|
||||||
quantum_utils.NEUTRON_METERING_AGENT_CONF:
|
|
||||||
['neutron-metering-agent'],
|
|
||||||
quantum_utils.NEUTRON_LBAAS_AGENT_CONF:
|
|
||||||
['neutron-lbaas-agent'],
|
|
||||||
quantum_utils.NEUTRON_OVS_PLUGIN_CONF:
|
|
||||||
['neutron-plugin-openvswitch-agent'],
|
|
||||||
quantum_utils.NOVA_CONF: ['nova-api-metadata'],
|
|
||||||
quantum_utils.NEUTRON_METADATA_AGENT_CONF:
|
|
||||||
['neutron-metadata-agent'],
|
|
||||||
quantum_utils.NEUTRON_DHCP_AGENT_CONF: ['neutron-dhcp-agent'],
|
|
||||||
quantum_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
|
||||||
quantum_utils.NEUTRON_CONF: ['neutron-l3-agent',
|
quantum_utils.NEUTRON_CONF: ['neutron-l3-agent',
|
||||||
'neutron-dhcp-agent',
|
'neutron-dhcp-agent',
|
||||||
'neutron-metadata-agent',
|
'neutron-metadata-agent',
|
||||||
'neutron-plugin-openvswitch-agent',
|
'neutron-plugin-openvswitch-agent',
|
||||||
|
'neutron-plugin-metering-agent',
|
||||||
'neutron-metering-agent',
|
'neutron-metering-agent',
|
||||||
'neutron-lbaas-agent']
|
'neutron-lbaas-agent',
|
||||||
|
'neutron-plugin-vpn-agent',
|
||||||
|
'neutron-vpn-agent'],
|
||||||
|
quantum_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
||||||
|
quantum_utils.NEUTRON_LBAAS_AGENT_CONF:
|
||||||
|
['neutron-lbaas-agent'],
|
||||||
|
quantum_utils.NEUTRON_OVS_PLUGIN_CONF:
|
||||||
|
['neutron-plugin-openvswitch-agent'],
|
||||||
|
quantum_utils.NEUTRON_METADATA_AGENT_CONF:
|
||||||
|
['neutron-metadata-agent'],
|
||||||
|
quantum_utils.NEUTRON_VPNAAS_AGENT_CONF: ['neutron-plugin-vpn-agent',
|
||||||
|
'neutron-vpn-agent'],
|
||||||
|
quantum_utils.NEUTRON_L3_AGENT_CONF: ['neutron-l3-agent'],
|
||||||
|
quantum_utils.NEUTRON_DHCP_AGENT_CONF: ['neutron-dhcp-agent'],
|
||||||
|
quantum_utils.NEUTRON_FWAAS_CONF: ['neutron-l3-agent'],
|
||||||
|
quantum_utils.NEUTRON_METERING_AGENT_CONF:
|
||||||
|
['neutron-metering-agent', 'neutron-plugin-metering-agent'],
|
||||||
|
quantum_utils.NOVA_CONF: ['nova-api-metadata'],
|
||||||
}
|
}
|
||||||
self.assertEquals(quantum_utils.restart_map(), ex_map)
|
|
||||||
|
self.assertDictEqual(quantum_utils.restart_map(), ex_map)
|
||||||
|
|
||||||
def test_register_configs_nvp(self):
|
def test_register_configs_nvp(self):
|
||||||
self.config.return_value = 'nvp'
|
self.config.return_value = 'nvp'
|
||||||
|
Loading…
Reference in New Issue
Block a user