Add database client

The client allows us to access any of the deployment's databases. It will be
used in the next patch to test NUMA live migration.

Original-review: https://review.rdoproject.org/r/#/c/21505/
Change-Id: Ie723aee7f12a10dd1766fda96f05987ba52e1397
This commit is contained in:
Artom Lifshitz 2019-07-16 12:55:27 -04:00
parent b11da2eb77
commit 043ceaef6f
4 changed files with 84 additions and 2 deletions

View File

@ -1,6 +1,8 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
oslo.log
tempest
#crudini>=0.9.3
oslo.log
sshtunnel
pymysql

View File

@ -78,3 +78,26 @@ nova_compute_opts = [
help='Command to restart the nova-compute service, without any '
'privilege management (ie, no sudo).'),
]
database_group = cfg.OptGroup(
name='whitebox-database',
title='Config options to access the database.')
database_opts = [
cfg.StrOpt(
'host',
help='Address of the database host. This is normally a controller.'),
cfg.StrOpt(
'internal_ip',
help='If the databse service is listening on separate internal '
'network, this option specifies its IP on that network. It will '
'be used to set up an SSH tunnel through the database host.'),
cfg.StrOpt(
'user',
help='Username to use when connecting to the database server. '
'This should normally be the root user, as it needs to '
'have permissions on all databases.'),
cfg.StrOpt(
'password',
help='The password to use when connecting to the database server.')
]

View File

@ -36,9 +36,13 @@ class WhiteboxTempestPlugin(plugins.TempestPlugin):
whitebox_config.general_opts)
config.register_opt_group(conf, whitebox_config.nova_compute_group,
whitebox_config.nova_compute_opts)
config.register_opt_group(conf, whitebox_config.database_group,
whitebox_config.database_opts)
def get_opt_lists(self):
return [(whitebox_config.general_group.name,
whitebox_config.general_opts),
(whitebox_config.nova_compute_group.name,
whitebox_config.nova_compute_opts)]
whitebox_config.nova_compute_opts),
(whitebox_config.database_group.name,
whitebox_config.database_opts)]

View File

@ -14,7 +14,9 @@
# under the License.
import contextlib
import pymysql
from six import StringIO
import sshtunnel
from oslo_log import log as logging
from tempest import config
@ -182,3 +184,54 @@ class NUMAClient(SSHClient):
free = int(line.split(':')[1].lstrip())
pages[node] = {'total': total, 'free': free}
return pages
class DatabaseClient(object):
def __init__(self):
self.ssh_key = CONF.whitebox.ctlplane_ssh_private_key_path
self.ssh_user = CONF.whitebox.ctlplane_ssh_username
@contextlib.contextmanager
def cursor(self, database_name, commit=False):
"""Yields a PyMySQL cursor, tunneling to the internal subnet if
necessary.
"""
tunnel_local_bind_host = '127.42.42.42'
tunnel_local_bind_port = 4242
if CONF.whitebox_database.internal_ip:
with sshtunnel.SSHTunnelForwarder(
(CONF.whitebox_database.host, 3306),
ssh_username=self.ssh_user,
ssh_pkey=self.ssh_key,
remote_bind_address=(CONF.whitebox_database.internal_ip,
3306),
local_bind_address=(tunnel_local_bind_host,
tunnel_local_bind_port)):
conn = pymysql.connect(
host=tunnel_local_bind_host, port=tunnel_local_bind_port,
user=CONF.whitebox_database.user,
password=CONF.whitebox_database.password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
with conn.cursor() as c:
try:
yield c
finally:
if commit:
conn.commit()
conn.close()
else:
conn = pymysql.connect(
host=CONF.whitebox_database.host, port=3306,
user=CONF.whitebox_database.user,
password=CONF.whitebox_database.password,
database=database_name,
cursorclass=pymysql.cursors.DictCursor)
with conn.cursor() as c:
try:
yield c
finally:
if commit:
conn.commit()
conn.close()