diff --git a/charms_openstack/adapters.py b/charms_openstack/adapters.py index f80022b..b0061e4 100644 --- a/charms_openstack/adapters.py +++ b/charms_openstack/adapters.py @@ -392,6 +392,7 @@ class DatabaseRelationAdapter(OpenStackRelationAdapter): def __init__(self, relation): add_accessors = ['password', 'username', 'database'] super(DatabaseRelationAdapter, self).__init__(relation, add_accessors) + self.config = hookenv.config() @property def host(self): @@ -405,15 +406,23 @@ class DatabaseRelationAdapter(OpenStackRelationAdapter): return 'mysql' def get_uri(self, prefix=None): + driver = 'mysql' + release = ch_utils.get_os_codename_install_source( + self.config['openstack-origin']) + if (ch_utils.OPENSTACK_RELEASES.index(release) >= + ch_utils.OPENSTACK_RELEASES.index('stein')): + driver = 'mysql+pymysql' if prefix: - uri = 'mysql://{}:{}@{}/{}'.format( + uri = '{}://{}:{}@{}/{}'.format( + driver, self.relation.username(prefix=prefix), self.relation.password(prefix=prefix), self.host, self.relation.database(prefix=prefix), ) else: - uri = 'mysql://{}:{}@{}/{}'.format( + uri = '{}://{}:{}@{}/{}'.format( + driver, self.username, self.password, self.host, diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py index 89ebd80..54399be 100644 --- a/unit_tests/__init__.py +++ b/unit_tests/__init__.py @@ -67,6 +67,9 @@ charmhelpers.contrib.openstack.utils.OPENSTACK_RELEASES = ( 'newton', 'ocata', 'pike', + 'queens', + 'rocky', + 'stein', ) # charms.reactive uses hookenv.charm_dir which must return a directory diff --git a/unit_tests/test_charms_openstack_adapters.py b/unit_tests/test_charms_openstack_adapters.py index 67b4420..96f1d9f 100644 --- a/unit_tests/test_charms_openstack_adapters.py +++ b/unit_tests/test_charms_openstack_adapters.py @@ -334,22 +334,47 @@ class SSLDatabaseRelationAdapter(adapters.DatabaseRelationAdapter): class TestDatabaseRelationAdapter(unittest.TestCase): def test_class(self): - fake = FakeDatabaseRelation() - db = adapters.DatabaseRelationAdapter(fake) - self.assertEqual(db.host, 'host1') - self.assertEqual(db.type, 'mysql') - self.assertEqual(db.password, 'password1') - self.assertEqual(db.username, 'username1') - self.assertEqual(db.database, 'database1') - self.assertEqual(db.uri, 'mysql://username1:password1@host1/database1') - self.assertEqual(db.get_uri('x'), - 'mysql://username1x:password1x@host1/database1x') - # test the ssl feature of the base class - db = SSLDatabaseRelationAdapter(fake) - self.assertEqual(db.uri, - 'mysql://username1:password1@host1/database1' - '?ssl_ca=my-ca' - '&ssl_cert=my-cert&ssl_key=my-key') + with mock.patch.object(adapters.ch_utils, + 'get_os_codename_install_source', + return_value='rocky'): + fake = FakeDatabaseRelation() + db = adapters.DatabaseRelationAdapter(fake) + self.assertEqual(db.host, 'host1') + self.assertEqual(db.type, 'mysql') + self.assertEqual(db.password, 'password1') + self.assertEqual(db.username, 'username1') + self.assertEqual(db.database, 'database1') + self.assertEqual( + db.uri, + 'mysql://username1:password1@host1/database1') + self.assertEqual( + db.get_uri('x'), + 'mysql://username1x:password1x@host1/database1x') + # test the ssl feature of the base class + db = SSLDatabaseRelationAdapter(fake) + self.assertEqual( + db.uri, + 'mysql://username1:password1@host1/database1' + '?ssl_ca=my-ca' + '&ssl_cert=my-cert&ssl_key=my-key') + with mock.patch.object(adapters.ch_utils, + 'get_os_codename_install_source', + return_value='stein'): + fake = FakeDatabaseRelation() + db = adapters.DatabaseRelationAdapter(fake) + self.assertEqual( + db.uri, + 'mysql+pymysql://username1:password1@host1/database1') + self.assertEqual( + db.get_uri('x'), + 'mysql+pymysql://username1x:password1x@host1/database1x') + # test the ssl feature of the base class + db = SSLDatabaseRelationAdapter(fake) + self.assertEqual( + db.uri, + 'mysql+pymysql://username1:password1@host1/database1' + '?ssl_ca=my-ca' + '&ssl_cert=my-cert&ssl_key=my-key') class TestConfigurationAdapter(unittest.TestCase):