? 2011?07?27? 14:58, Guannan Ren ??:
---
repos/remoteAccess/tls_setup.py | 374 +++++++++++++++++++++++++++++++++++++++
1 files changed, 374 insertions(+), 0 deletions(-)
create mode 100644 repos/remoteAccess/__init__.py
create mode 100644 repos/remoteAccess/tls_setup.py
diff --git a/repos/remoteAccess/__init__.py b/repos/remoteAccess/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/repos/remoteAccess/tls_setup.py b/repos/remoteAccess/tls_setup.py
new file mode 100644
index 0000000..f703ee3
--- /dev/null
+++ b/repos/remoteAccess/tls_setup.py
@@ -0,0 +1,374 @@
+#!/usr/bin/env python
+""" Setup tls authentication between two hosts and configure libvirt
+ to use it for connection.
+ remoteAccess:tls_setup
+ target_machine
+ xx.xx.xx.xx
+ username
+ root
+ password
+ xxxxxx
+"""
+
+__author__ = 'Guannan Ren: gren(a)redhat.com'
+__date__ = 'Mon July 25, 2011'
+__version__ = '0.1.0'
+__credits__ = 'Copyright (C) 2011 Red Hat, Inc.'
+__all__ = ['usage']
+
+import os
+import re
+import sys
+import pexpect
+import string
+import commands
+import shutil
+
+def append_path(path):
+ """Append root path of package"""
+ if path in sys.path:
+ pass
+ else:
+ sys.path.append(path)
+
+pwd = os.getcwd()
+result = re.search('(.*)libvirt-test-API', pwd)
+append_path(result.group(0))
+
+from lib import connectAPI
+from utils.Python import utils
+from exception import LibvirtAPI
+
+CERTTOOL = "/usr/bin/certtool"
+CP = "/bin/cp"
+MKDIR = "/bin/mkdir"
+CA_FOLDER = "/etc/pki/CA"
+PRIVATE_KEY_FOLDER = "/etc/pki/libvirt/private"
+CERTIFICATE_FOLDER = "/etc/pki/libvirt"
Hardcode these paths might not be good idea, there is new parameter
for libvirt connection URI to define where the keys and CA locates. See
http://libvirt.org/remote.html [pkipath] <
http://libvirt.org/remote.html>
+
+TEMP_TLS_FOLDER = "/tmp/libvirt_test_API_tls"
+CAKEY = os.path.join(TEMP_TLS_FOLDER, 'cakey.pem')
+CACERT = os.path.join(TEMP_TLS_FOLDER, 'cacert.pem')
+SERVERKEY = os.path.join(TEMP_TLS_FOLDER, 'serverkey.pem')
+SERVERCERT = os.path.join(TEMP_TLS_FOLDER, 'servercert.pem')
+CLIENTKEY = os.path.join(TEMP_TLS_FOLDER, 'clientkey.pem')
+CLIENTCERT = os.path.join(TEMP_TLS_FOLDER, 'clientcert.pem')
+
+def check_params(params):
+ """check out the arguments requried for migration"""
+ logger = params['logger']
+ keys = ['target_machine', 'username', 'password']
+ for key in keys:
+ if key not in params:
+ logger.error("Argument %s is required" % key)
+ return 1
+ return 0
+
+def CA_setting_up(util, logger):
+ """ setting up a Certificate Authority """
+ # Create a private key for CA
+ logger.info("generate CA certificates")
+
+ cakey_fd = open(CAKEY, 'w')
+ ret, out = util.exec_cmd([CERTTOOL, '--generate-privkey'],
outfile=cakey_fd)
+ cakey_fd.close()
+ if ret != 0:
+ logger.error("failed to create CA private key")
+ return 1
+
+
+ # ca.info file
+ cainfo = os.path.join(TEMP_TLS_FOLDER, 'ca.info')
+ cainfo_fd = open(cainfo, 'w')
+ cainfo_str = "cn = Libvirt_test_API\n" + \
+ "ca\n" + \
+ "cert_signing_key\n"
+
+ cainfo_fd.write(cainfo_str)
+ cainfo_fd.close()
+
+ # Generate cacert.pem
+ cacert_args = [CERTTOOL, '--generate-self-signed', '--load-privkey',
CAKEY, '--template', cainfo]
+ cacert_fd = open(CACERT, 'w')
+ ret, out = util.exec_cmd(cacert_args, outfile=cacert_fd)
+ cacert_fd.close()
+ if ret != 0:
+ logger.error("failed to create cacert.pem")
+ return 1
+
+ logger.info("done the CA certificates job")
+ return 0
+
+def tls_server_cert(target_machine, util, logger):
+ """ generating server certificates """
+ # Create tls server key
+ logger.info("generate server certificates")
+
+ serverkey_fd = open(SERVERKEY, 'w')
+ ret, out = util.exec_cmd([CERTTOOL, '--generate-privkey'],
outfile=serverkey_fd)
+ serverkey_fd.close()
+ if ret != 0:
+ logger.error("failed to create server key")
+ return 1
+
+ # server.info
+ serverinfo = os.path.join(TEMP_TLS_FOLDER, 'server.info')
+ serverinfo_fd = open(serverinfo, 'w')
+ serverinfo_str = "organization = Libvirt_test_API\n" + \
+ "cn = %s\n" % target_machine + \
+ "tls_www_server\n" + \
+ "encryption_key\n" + \
+ "signing_key\n"
+
+ serverinfo_fd.write(serverinfo_str)
+ serverinfo_fd.close()
+
+ # Generate servercert.pem
+ servercert_args = [CERTTOOL,
+ '--generate-certificate',
+ '--load-privkey', SERVERKEY,
+ '--load-ca-certificate', CACERT,
+ '--load-ca-privkey', CAKEY,
+ '--template', serverinfo
+ ]
+ servercert_fd = open(SERVERCERT, 'w')
+ ret, out = util.exec_cmd(servercert_args, outfile=servercert_fd)
+ servercert_fd.close()
+ if ret != 0:
+ logger.error("failed to create servercert.pem")
+ return 1
+
+ logger.info("done the server certificates job")
+ return 0
+
+def tls_client_cert(local_machine, util, logger):
+ """ generating client certificates """
+ # Create tls client key
+ logger.info("generate client certificates")
+
+ clientkey_fd = open(CLIENTKEY, 'w')
+ ret, out = util.exec_cmd([CERTTOOL, '--generate-privkey'],
outfile=clientkey_fd)
+ clientkey_fd.close()
+ if ret != 0:
+ logger.error("failed to create client key")
+ return 1
+
+ # client.info
+ clientinfo = os.path.join(TEMP_TLS_FOLDER, 'client.info')
+ clientinfo_fd = open(clientinfo, 'w')
+ clientinfo_str = "country = xxx\n" + \
+ "state = xxx\n" + \
+ "locality = xxx\n" + \
+ "organization = Libvirt_test_API\n" + \
+ "cn = %s\n" % local_machine + \
+ "tls_www_client\n" + \
+ "encryption_key\n" + \
+ "signing_key\n"
+
+ clientinfo_fd.write(clientinfo_str)
+ clientinfo_fd.close()
+
+ # Generate clientcert.pem
+ clientcert_args = [CERTTOOL,
+ '--generate-certificate',
+ '--load-privkey', CLIENTKEY,
+ '--load-ca-certificate', CACERT,
+ '--load-ca-privkey', CAKEY,
+ '--template', clientinfo,
+ ]
+
+ clientcert_fd = open(CLIENTCERT, 'w')
+ ret, out = util.exec_cmd(clientcert_args, outfile=clientcert_fd)
+ clientcert_fd.close()
+ if ret != 0:
+ logger.error("failed to create client certificates")
+ return 1
+
+ logger.info("done the client certificates job")
+ return 0
+
+def deliver_cert(target_machine, username, password, util, logger):
+ """ deliver CA, server and client certificates """
+ # transmit cacert.pem to remote host
+ logger.info("deliver CA, server and client certificates to both local and
remote server")
+ ret = util.scp_file(target_machine, username, password, CA_FOLDER, CACERT)
+ if ret:
+ logger.error("scp cacert.pem to %s error" % target_machine)
+ return 1
+
+ # copy cacert.pem to local CA folder
+ cacert_cp = [CP, '-f', CACERT, CA_FOLDER]
+ ret, out = util.exec_cmd(cacert_cp)
+ if ret:
+ logger.error("copying cacert.pem to %s error" % CA_FOLDER)
+ return 1
+
+ # mkdir /etc/pki/libvirt/private on remote host
+ libvirt_priv_cmd = "mkdir -p %s" % PRIVATE_KEY_FOLDER
+ ret = util.remote_exec_pexpect(target_machine, username, password,
libvirt_priv_cmd)
+ if ret:
+ logger.error("failed to make /etc/pki/libvirt/private on %s" %
target_machine)
+ return 1
+
+ # transmit serverkey.pem to remote host
+ ret = util.scp_file(target_machine, username, password, PRIVATE_KEY_FOLDER,
SERVERKEY)
+ if ret:
+ logger.error("failed to scp serverkey.pem to %s" % target_machine)
+ return 1
+
+ # transmit servercert.pem to remote host
+ ret = util.scp_file(target_machine, username, password, CERTIFICATE_FOLDER,
SERVERCERT)
+ if ret:
+ logger.error("failed to scp servercert.pem to %s" % target_machine)
+ return 1
+
+ libvirt_priv_cmd_local = [MKDIR, '-p', PRIVATE_KEY_FOLDER]
+ ret, out = util.exec_cmd(libvirt_priv_cmd_local)
+ if ret:
+ logger.error("failed to make %s on local" % PRIVATE_KEY_FOLDER)
+ return 1
+
+ # copy clientkey.pem to local folder
+ clientkey_cp = [CP, '-f', CLIENTKEY, PRIVATE_KEY_FOLDER]
+ ret, out = util.exec_cmd(clientkey_cp)
+ if ret:
+ logger.error("failed to copy clientkey.pem to %s" %
PRIVATE_KEY_FOLDER)
+ return 1
+
+ # copy clientcert.pem to local folder
+ clientcert_cp = [CP, '-f', CLIENTCERT, CERTIFICATE_FOLDER]
+ ret, out = util.exec_cmd(clientcert_cp)
+ if ret:
+ logger.error("failed to copy clientcert.pem to %s" %
CERTIFICATE_FOLDER)
+ return 1
+
+ logger.info("done to delivery")
+ return 0
+
+def tls_libvirtd_set(target_machine, username, password, util, logger):
+ """ configure libvirtd.conf on tls server """
+ logger.info("setting libvirtd.conf on tls server")
+ # open libvirtd --listen option
+ listen_open_cmd = "echo 'LIBVIRTD_ARGS=\"--listen\"'>>
/etc/sysconfig/libvirtd"
+ ret = util.remote_exec_pexpect(target_machine, username, password, listen_open_cmd)
+ if ret:
+ logger.error("failed to uncomment --listen in
/etc/sysconfig/libvirtd")
+ return 1
+
+ listen_tcp_cmd = "echo \"listen_tcp = 1\">>
/etc/libvirt/libvirtd.conf"
+ ret = util.remote_exec_pexpect(target_machine, username, password, listen_tcp_cmd)
+ if ret:
+ logger.error("failed to uncomment listen_tcp in
/etc/libvirt/libvirtd.conf")
+ return 1
+
+ # restart remote libvirtd service
+ libvirtd_restart_cmd = "service libvirtd restart"
+ ret = util.remote_exec_pexpect(target_machine, username, password,
libvirtd_restart_cmd)
+ if ret:
+ logger.error("failed to restart libvirtd service")
+ return 1
+
+ logger.info("done to libvirtd configuration")
+ return 0
+
+def iptables_stop(target_machine, username, password, util, logger):
+ """ This is a temprory method in favor of migration
"""
+ logger.info("stop local and remote iptables temprorily")
+ iptables_stop_cmd = "service iptables stop"
+ ret = util.remote_exec_pexpect(target_machine, username, password,
iptables_stop_cmd)
+ if ret:
+ logger.error("failed to stop remote iptables service")
+ return 1
+
+ iptables_stop = ["service", "iptables", "stop"]
+ ret, out = util.exec_cmd(iptables_stop)
+ if ret:
+ logger.error("failed to stop local iptables service")
+ return 1
+
+ logger.info("done the iptables stop job")
+ return 0
+
+def tls_setup(params):
+ """ generate tls certificates and configure libvirt
"""
+ logger = params['logger']
+ params_check_result = check_params(params)
+ if params_check_result:
+ return 1
+
+ target_machine = params['target_machine']
+ username = params['username']
+ password = params['password']
+
+ util = utils.Utils()
+ local_machine = util.get_local_hostname()
+
+ logger.info("the hostname of server is %s" % target_machine)
+ logger.info("the hostname of local machine is %s" % local_machine)
+
+ if not util.do_ping(target_machine, 0):
+ logger.error("failed to ping host %s" % target_machine)
+ return 1
+
+ if os.path.exists(TEMP_TLS_FOLDER):
+ shutil.rmtree(TEMP_TLS_FOLDER)
+
+ os.mkdir(TEMP_TLS_FOLDER)
+
+ if iptables_stop(target_machine, username, password, util, logger):
+ return 1
+
+ if CA_setting_up(util, logger):
+ return 1
+
+ if tls_server_cert(target_machine, util, logger):
+ return 1
+
+ if tls_client_cert(local_machine, util, logger):
+ return 1
+
+ if deliver_cert(target_machine, username, password, util, logger):
+ return 1
+
+ if tls_libvirtd_set(target_machine, username, password, util, logger):
+ return 1
+
+ uri = "qemu://%s/system" % target_machine
+
+ try:
+ conn = connectAPI.ConnectAPI()
+ virconn = conn.open(uri)
+ virconn.close()
+ logger.info("tls authentication success")
+ except LibvirtAPI, e:
+ logger.error("API error message: %s, error code is %s" % \
+ (e.response()['message'], e.response()['code']))
+ logger.error("tls authentication failed")
+ return 1
+
+ return 0
+
+def tls_setup_clean(params):
+ """ cleanup testing enviroment """
+ if os.path.exists(TEMP_TLS_FOLDER):
+ shutil.rmtree(TEMP_TLS_FOLDER)
+
+ logger = params['logger']
+ target_machine = params['target_machine']
+ username = params['username']
+ password = params['password']
+
+ util = utils.Utils()
+ cacert_rm = "rm -f %s/cacert.pem" % CA_FOLDER
+ ret = util.remote_exec_pexpect(target_machine, username, password, cacert_rm)
+ if ret:
+ logger.error("failed to remove cacert.pem on remote machine")
+
+ ca_libvirt_rm = "rm -rf %s" % CERTIFICATE_FOLDER
+ ret = util.remote_exec_pexpect(target_machine, username, password, ca_libvirt_rm)
+ if ret:
+ logger.error("failed to remove libvirt folder")
+
+ os.remove("%s/cacert.pem" % CA_FOLDER)
+ shutil.rmtree(CERTIFICATE_FOLDER)
+