Stephen Finucane 2481c543f9 Re-home project
Move project into a directory matching its name.

Change-Id: I26934edd049909482ccc078d88b581fa369326b4
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
2018-01-10 11:57:05 +00:00

134 lines
4.4 KiB
Python

# Copyright 2016
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from contextlib import contextmanager
try:
from shlex import quote
except ImportError:
from pipes import quote
import urlparse
from tempest import config
from tempest.lib.common import ssh
CONF = config.CONF
class SSHClient(object):
"""A client to execute remote commands, based on tempest.lib.common.ssh."""
_prefix_command = '/bin/bash -c'
def __init__(self):
self.ssh_key = CONF.compute_private_config.target_private_key_path
self.ssh_user = CONF.compute_private_config.target_ssh_user
def execute(self, hostname=None, cmd=None):
ssh_client = ssh.Client(hostname, self.ssh_user,
key_filename=self.ssh_key)
cmd = self._prefix_command + ' ' + quote(cmd)
return ssh_client.exec_command(cmd)
@contextmanager
def prefix_command(self, prefix_command=None):
saved_prefix = self._prefix_command
self._prefix_command = prefix_command
yield self
self._prefix_command = saved_prefix
@contextmanager
def sudo_command(self, user=None):
if user is not None:
user_arg = '-u {}'.format(user)
else:
user_arg = ''
cmd = 'sudo {} /bin/bash -c'.format(user_arg)
with self.prefix_command(cmd) as p:
yield p
@contextmanager
def container_command(self, container_name, user=None):
if user is not None:
user_arg = '-u {}'.format(user)
else:
user_arg = ''
cmd = 'sudo docker exec {} -i {} /bin/bash -c'.format(
user_arg, container_name)
with self.prefix_command(cmd) as p:
yield p
class VirshXMLClient(SSHClient):
def __init__(self, hostname=None):
super(VirshXMLClient, self).__init__()
self.host = hostname
def dumpxml(self, domain):
if CONF.compute_private_config.containers:
ctx = self.container_command('nova_compute', user='root')
else:
ctx = self.sudo_command()
with ctx:
command = "virsh dumpxml {}".format(domain)
return self.execute(self.host, command)
class MySQLClient(SSHClient):
def __init__(self):
super(MySQLClient, self).__init__()
# the nova conf file may contain a private IP.
# let's just assume the db is available on the same node.
self.host = CONF.compute_private_config.target_controller
# discover db connection params by accessing nova.conf remotely
ssh_client = SSHClient()
if CONF.compute_private_config.containers:
ctx = ssh_client.container_command('nova_api')
else:
ctx = ssh_client.sudo_command()
with ctx:
cmd = 'grep "connection=mysql+pymysql://nova:" /etc/nova/nova.conf'
connection = ssh_client.execute(self.host, cmd)
connection_url = "=".join(connection.split("=")[1:])
p = urlparse.urlparse(connection_url)
self.username = p.username
self.password = p.password
self.database = p.path[1:]
self.database_host = p.hostname
def execute_command(self, command):
sql_cmd = "mysql -u{} -p{} -h{} -e '{}' {}".format(
self.username,
self.password,
self.database_host,
command,
self.database)
return self.execute(self.host, sql_cmd)
class NovaManageClient(SSHClient):
def __init__(self):
super(NovaManageClient, self).__init__()
self.hostname = CONF.compute_private_config.target_controller
def execute_command(self, command):
if CONF.compute_private_config.containers:
ctx = self.container_command('nova_api')
else:
ctx = self.sudo_command()
with ctx:
nova_cmd = "nova-manage {}".format(command)
return self.execute(self.hostname, nova_cmd)