2020-12-16 17:25:24 +08:00

948 lines
41 KiB
Python

# -*- coding:utf-8 -*-
#############################################################################
# Copyright (c) 2020 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms
# and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# ----------------------------------------------------------------------------
# Description : gs_om is a utility to manage a Gauss200 cluster.
#############################################################################
import subprocess
import os
import sys
import pwd
from datetime import datetime
sys.path.append(sys.path[0] + "/../../../")
from gspylib.common.DbClusterInfo import dbClusterInfo, queryCmd
from gspylib.threads.SshTool import SshTool
from gspylib.common.DbClusterStatus import DbClusterStatus
from gspylib.common.ErrorCode import ErrorCode
from gspylib.common.Common import DefaultValue, ClusterCommand
from gspylib.common.OMCommand import OMCommand
from gspylib.os.gsOSlib import g_OSlib
from gspylib.os.gsfile import g_file
from gspylib.os.gsplatform import g_Platform
# Cert
EMPTY_CERT = "emptyCert"
EMPTY_FLAG = "emptyflag"
# tmp file that storage change io information
CHANGEIP_BACKUP_DIR = "%s/change_ip_bak" % DefaultValue.getTmpDirFromEnv()
# EC odbc files
ODBC_INI = "odbc.ini"
ODBC_SYS_INI = "odbcsys"
FC_CONF = "fc_conf/"
# postgis lib file
POSTGIS_FILE_LIST = ["lib/postgresql/postgis-[0-9]+.[0-9]+.so",
"lib/libgeos_c.so.[0-9]+", "lib/libproj.so.[0-9]+",
"lib/libjson-c.so.[0-9]+",
"lib/libgeos-[0-9]+.[0-9]+.[0-9]+so",
"lib/libgcc_s.so.[0-9]+",
"lib/libstdc\+\+.so.[0-9]+",
"share/postgresql/extension/postgis--[0-9]"
"+.[0-9]+.[0-9]+.sql",
"share/postgresql/extension/postgis.control",
"bin/pgsql2shp", "bin/shp2pgsql"]
# elastic group with node group name
ELASTIC_GROUP = "elastic_group"
# lib of sparkodbc
LIB_SPARK = ["/usr/lib64/libboost_filesystem.so.1.55.0",
"/usr/lib64/libboost_system.so.1.55.0",
"/usr/lib64/libfb303.so", "/usr/lib64/libhiveclient.so",
"/usr/lib64/libhiveclient.so.1.0.0",
"/usr/lib64/libodbchive.so", "/usr/lib64/libodbchive.so.1.0.0",
"/usr/lib64/libsasl2.so.2",
"/usr/lib64/libsasl2.so.2.0.23", "/usr/lib64/libthrift-0.9.3.so",
"/usr/lib64/libsasl2.so.2.0.22"]
###########################################
class OmImpl:
"""
init the command options
save command line parameter values
"""
def __init__(self, OperationManager):
"""
function: constructor
"""
# global
self.context = OperationManager
self.logger = OperationManager.logger
self.user = OperationManager.user
self.newClusterInfo = None
self.oldClusterInfo = None
self.utilsPath = None
self.mpprcFile = ""
self.nodeId = OperationManager.g_opts.nodeId
self.time_out = OperationManager.g_opts.time_out
self.mode = OperationManager.g_opts.mode
self.clusterInfo = OperationManager.clusterInfo
self.dataDir = OperationManager.g_opts.dataDir
self.sshTool = None
def doStopCluster(self):
"""
function: do stop cluster
input: NA
output: NA
"""
pass
def doClusterStatus(self):
"""
function: get cluster
input: NA
output: NA
"""
pass
def doStart(self):
"""
function:Start cluster or node
input:NA
output:NA
"""
self.doStartCluster()
def doStop(self):
"""
function:Stop cluster or node
input:NA
output:NA
"""
self.logger.debug("Operating: Stopping.")
self.doStopCluster()
def getNodeStatus(self, nodename):
"""
function: get node status
input: nodename
output: NA
"""
try:
# Create a temporary file to save cluster status
tmpDir = DefaultValue.getTmpDirFromEnv()
tmpFile = os.path.join(tmpDir, "gauss_cluster_status.dat_" + \
str(datetime.now().strftime(
'%Y%m%d%H%M%S')) + "_" + str(
os.getpid()))
# Perform the start operation
# Writes the execution result to a temporary file
cmd = ClusterCommand.getQueryStatusCmd(self.context.g_opts.user,
"", tmpFile, True)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
self.logger.debug("The cmd is %s " % cmd)
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % \
cmd + "Error: \n%s" % output)
# Initialize cluster status information for the temporary file
clusterStatus = DbClusterStatus()
clusterStatus.initFromFile(tmpFile)
# Get node status
nodeStatusInfo = None
for dbNode in clusterStatus.dbNodes:
if (dbNode.name == nodename):
nodeStatusInfo = dbNode
if (nodeStatusInfo and nodeStatusInfo.isNodeHealthy()):
nodeStatus = clusterStatus.OM_NODE_STATUS_NORMAL
else:
nodeStatus = clusterStatus.OM_NODE_STATUS_ABNORMAL
DefaultValue.cleanTmpFile(tmpFile)
return nodeStatus
except Exception as e:
DefaultValue.cleanTmpFile(tmpFile)
self.logger.debug(
"Failed to get node status. Error: \n%s." % str(e))
return "Abnormal"
def doStatus(self):
"""
function:Get the status of cluster or node
input:NA
output:NA
"""
hostName = DefaultValue.GetHostIpOrName()
sshtool = SshTool(self.context.clusterInfo.getClusterNodeNames())
nodeId = 0
if (self.context.g_opts.nodeName != ""):
for dbnode in self.context.clusterInfo.dbNodes:
if dbnode.name == self.context.g_opts.nodeName:
nodeId = dbnode.id
if (nodeId == 0):
raise Exception(
ErrorCode.GAUSS_516["GAUSS_51619"]
% self.context.g_opts.nodeName)
cmd = queryCmd()
if (self.context.g_opts.outFile != ""):
cmd.outputFile = self.context.g_opts.outFile
if (self.context.g_opts.show_detail):
if (
self.context.clusterInfo.clusterType
== DefaultValue.CLUSTER_TYPE_SINGLE_PRIMARY_MULTI_STANDBY):
cmd.dataPathQuery = True
cmd.azNameQuery = True
else:
cmd.dataPathQuery = True
else:
if (nodeId > 0):
self.context.clusterInfo.queryNodeInfo(sshtool, hostName,
nodeId, cmd.outputFile)
return
if (self.context.g_opts.showAll):
self.context.clusterInfo.queryNodeInfo(sshtool, hostName,
nodeId, cmd.outputFile)
return
cmd.clusterStateQuery = True
self.context.clusterInfo.queryClsInfo(hostName, sshtool,
self.context.mpprcFile, cmd)
def doRebuildConf(self):
"""
generating static configuration files for all nodes
input:NA
output:NA
"""
try:
self.logger.log(
"Generating static configuration files for all nodes.")
# Initialize the cluster information according to the XML file
self.context.clusterInfo = dbClusterInfo()
self.context.clusterInfo.initFromXml(self.context.g_opts.confFile)
# 1.create a tmp dir
self.logger.log(
"Creating temp directory to store static configuration files.")
dirName = os.path.dirname(os.path.realpath(__file__))
tmpDirName = os.path.realpath(
"%s/../../static_config_files" % dirName)
cmd = "mkdir -p -m %s '%s'" % (
DefaultValue.KEY_DIRECTORY_MODE, tmpDirName)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
raise Exception(
ErrorCode.GAUSS_502["GAUSS_50208"]
% "temporary directory" + "\nCommand:%s\nError: %s"
% (cmd, output))
self.logger.log("Successfully created the temp directory.")
# create static files
self.logger.log("Generating static configuration files.")
for dbNode in self.context.clusterInfo.dbNodes:
staticConfigPath = "%s/cluster_static_config_%s" % (
tmpDirName, dbNode.name)
self.context.clusterInfo.saveToStaticConfig(staticConfigPath,
dbNode.id)
self.logger.log(
"Successfully generated static configuration files.")
self.logger.log(
"Static configuration files for all nodes are saved in %s."
% tmpDirName)
# check if need send static config files
if not self.context.g_opts.distribute:
self.logger.debug(
"No need to distribute static configuration files "
"to installation directory.")
return
# distribute static config file
self.logger.log(
"Distributing static configuration files to all nodes.")
for dbNode in self.context.clusterInfo.dbNodes:
if (dbNode.name != DefaultValue.GetHostIpOrName()):
cmd = \
"pscp -H %s '%s'/cluster_static_config_%s '%s'" \
"/bin/cluster_static_config" % (
dbNode.name, tmpDirName,
dbNode.name, self.context.clusterInfo.appPath)
else:
cmd = \
"cp '%s'/cluster_static_config_%s '%s'" \
"/bin/cluster_static_config" % (
tmpDirName,
dbNode.name, self.context.clusterInfo.appPath)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
raise Exception(
ErrorCode.GAUSS_502["GAUSS_50216"]
% "static configuration file"
+ "Node: %s.\nCommand: \n%s\nError: \n%s"
% (dbNode.name, cmd, output))
self.logger.log(
"Successfully distributed static configuration files.")
except Exception as e:
g_file.removeDirectory(tmpDirName)
raise Exception(str(e))
##########################################################################
# doReplaceSSLCert start
##########################################################################
def doReplaceSSLCert(self):
"""
function: replace ssl cert files
input: NA
output: NA
"""
try:
# Initialize the cluster information according to the xml file
self.context.clusterInfo = dbClusterInfo()
self.context.clusterInfo.initFromStaticConfig(
g_OSlib.getPathOwner(self.context.g_opts.certFile)[0])
self.sshTool = SshTool(
self.context.clusterInfo.getClusterNodeNames(),
self.logger.logFile)
except Exception as e:
raise Exception(str(e))
try:
self.logger.log("Starting ssl cert files replace.", "addStep")
tempDir = os.path.join(DefaultValue.getTmpDirFromEnv(),
"tempCertDir")
# unzip files to temp directory
if (os.path.exists(tempDir)):
g_file.removeDirectory(tempDir)
g_file.createDirectory(tempDir, True,
DefaultValue.KEY_DIRECTORY_MODE)
g_file.decompressZipFiles(self.context.g_opts.certFile, tempDir)
realCertList = DefaultValue.CERT_FILES_LIST
clientCertList = DefaultValue.CLIENT_CERT_LIST
# check file exists
for clientCert in clientCertList:
sslFile = os.path.join(tempDir, clientCert)
if (not os.path.isfile(sslFile)):
raise Exception(
(ErrorCode.GAUSS_502["GAUSS_50201"] % sslFile) + \
"Missing SSL client cert file in ZIP file.")
certList = []
dnDict = self.getDnNodeDict()
for cert in realCertList:
sslFile = os.path.join(tempDir, cert)
if (not os.path.isfile(
sslFile) and cert != DefaultValue.SSL_CRL_FILE):
raise Exception(
(ErrorCode.GAUSS_502["GAUSS_50201"] % sslFile) + \
"Missing SSL server cert file in ZIP file.")
if (os.path.isfile(sslFile)):
certList.append(cert)
# distribute cert files to datanodes
self.doDNBackup()
self.distributeDNCert(certList, dnDict)
# clear temp directory
g_file.removeDirectory(tempDir)
if (not self.context.g_opts.localMode):
self.logger.log(
"Successfully distributed cert files on all nodes.")
except Exception as e:
g_file.removeDirectory(tempDir)
raise Exception(str(e))
def isDnEmpty(self, nodeName=""):
"""
function: Is there exists empty file in dbnodes directory.
input: node name
output: True/False
"""
allDnNodeDict = self.getDnNodeDict()
nodeDnDir = allDnNodeDict[nodeName]
emptyCert = os.path.join(nodeDnDir, EMPTY_CERT)
status = self.sshTool.checkRemoteFileExist(
nodeName, emptyCert,
self.context.g_opts.mpprcFile)
return status
def doDNBackup(self):
"""
function: backup SSL cert files on single_inst cluster.
input: backupFlag is a flag of exist DB in node
output: NA
"""
self.logger.log("Backing up old ssl cert files.")
backupList = DefaultValue.CERT_FILES_LIST[:]
allDnNodeDict = self.getDnNodeDict()
normalNodeList = []
tarBackupList = []
if (self.context.g_opts.localMode):
self.logger.debug("Backing up database node SSL cert files.")
nodeDnDir = allDnNodeDict[DefaultValue.GetHostIpOrName()]
backupFlagFile = os.path.join(nodeDnDir, "certFlag")
if (os.path.isfile(backupFlagFile)):
self.logger.log("There is no need to backup ssl cert files.")
return
os.mknod(backupFlagFile, DefaultValue.KEY_FILE_PERMISSION)
for certFile in backupList:
realCertFile = os.path.join(nodeDnDir, certFile)
if (os.path.isfile(realCertFile)):
tarBackupList.append(certFile)
if (len(tarBackupList) == 0):
os.mknod(os.path.join(nodeDnDir, EMPTY_CERT))
cmd = " %s && " % g_Platform.getCdCmd(nodeDnDir)
cmd += g_Platform.getCompressFilesCmd(
DefaultValue.CERT_BACKUP_FILE, EMPTY_CERT)
else:
cmd = " %s && " % g_Platform.getCdCmd(nodeDnDir)
cmd += "tar -zcvf %s" % (DefaultValue.CERT_BACKUP_FILE)
for certFile in tarBackupList:
cmd += " %s" % certFile
(status, output) = DefaultValue.retryGetstatusoutput(cmd)
if (status != 0):
raise Exception(
ErrorCode.GAUSS_514["GAUSS_51400"]
% cmd + "Failed backup gds cert files on local node."
+ "Error: \n%s" % output)
# Clear empty file
if (os.path.isfile(os.path.join(nodeDnDir, EMPTY_CERT))):
os.remove(os.path.join(nodeDnDir, EMPTY_CERT))
self.logger.log("Successfully executed local backup.")
return
# 1 check backup flag file on all dbnodes.
for node in allDnNodeDict.keys():
nodeDnDir = allDnNodeDict[node]
backupFlagFile = os.path.join(nodeDnDir, "certFlag")
status = self.sshTool.checkRemoteFileExist(
node, backupFlagFile,
self.context.g_opts.mpprcFile)
if not status:
normalNodeList.append(node)
# 2 if exists flag file on anyone node, there will be return.
if (len(normalNodeList) != len(allDnNodeDict.keys())):
self.logger.log("There is no need to backup on all dbnodes.")
return
# 3 backup cert files on all dbnodes.
for node in allDnNodeDict.keys():
nodeDnDir = allDnNodeDict[node]
backupFlagFile = os.path.join(nodeDnDir, "certFlag")
backupTar = os.path.join(nodeDnDir, DefaultValue.CERT_BACKUP_FILE)
sshcmd = g_file.SHELL_CMD_DICT["overWriteFile"] % (
"backupflagfile", backupFlagFile)
sshcmd += " && " + g_file.SHELL_CMD_DICT["changeMode"] % (
DefaultValue.KEY_FILE_MODE, backupFlagFile)
self.sshTool.executeCommand(sshcmd, "Make a flag file of backup.",
DefaultValue.SUCCESS, [node],
self.context.g_opts.mpprcFile)
for certFile in backupList:
realCertFile = os.path.join(nodeDnDir, certFile)
status = self.sshTool.checkRemoteFileExist(
node, realCertFile,
self.context.g_opts.mpprcFile)
if status:
tarBackupList.append(certFile)
# if no cert files,
# there will be create a file for '.tar' file.
if (len(tarBackupList) == 0):
sshcmd = g_Platform.getCreateFileCmd(
os.path.join(nodeDnDir, EMPTY_CERT))
self.sshTool.executeCommand(sshcmd,
"Backup empty cert file.",
DefaultValue.SUCCESS, [node],
self.context.g_opts.mpprcFile)
sshcmd = " %s && " % g_Platform.getCdCmd(nodeDnDir)
sshcmd += g_Platform.getCompressFilesCmd(
DefaultValue.CERT_BACKUP_FILE, EMPTY_CERT)
else:
sshcmd = " %s && " % g_Platform.getCdCmd(nodeDnDir)
sshcmd += "tar -zcvf %s" % (DefaultValue.CERT_BACKUP_FILE)
for certDir in tarBackupList:
sshcmd += " %s" % certDir
self.sshTool.executeCommand(sshcmd, "Backup cert file.",
DefaultValue.SUCCESS, [node],
self.context.g_opts.mpprcFile)
# Clear empty file
if (self.isDnEmpty(node)):
sshcmd = g_file.SHELL_CMD_DICT["deleteFile"] % (
os.path.join(nodeDnDir, EMPTY_CERT),
os.path.join(nodeDnDir, EMPTY_CERT))
self.sshTool.executeCommand(sshcmd, "Clear empty file.",
DefaultValue.SUCCESS, [node],
self.context.g_opts.mpprcFile)
self.logger.log(
"Successfully backup SSL cert files on [%s]." % node)
sshcmd = g_file.SHELL_CMD_DICT["changeMode"] % (
DefaultValue.KEY_FILE_MODE, backupTar)
self.sshTool.executeCommand(sshcmd, "Chmod back up cert",
DefaultValue.SUCCESS, [node],
self.context.g_opts.mpprcFile)
def doDNSSLCertRollback(self):
"""
function: rollback SSL cert file in DN instance directory
input: NA
output: NA
"""
self.context.clusterInfo = dbClusterInfo()
self.context.clusterInfo.initFromStaticConfig(
pwd.getpwuid(os.getuid()).pw_name)
self.sshTool = SshTool(self.context.clusterInfo.getClusterNodeNames(),
self.logger.logFile)
backupList = DefaultValue.CERT_FILES_LIST[:]
allDnNodeDict = self.getDnNodeDict()
noBackupList = []
temp = "tempDir"
if self.context.g_opts.localMode:
if ((DefaultValue.GetHostIpOrName() in allDnNodeDict.keys()) and
os.path.isfile(os.path.join(
allDnNodeDict[DefaultValue.GetHostIpOrName()],
DefaultValue.CERT_BACKUP_FILE))):
localDnDir = allDnNodeDict[DefaultValue.GetHostIpOrName()]
tempDir = os.path.join(localDnDir, temp)
if (os.path.exists(tempDir)):
g_file.removeDirectory(tempDir)
os.mkdir(tempDir, DefaultValue.KEY_DIRECTORY_PERMISSION)
for certFile in backupList:
realCertFile = os.path.join(localDnDir, certFile)
if (os.path.exists(realCertFile)):
g_file.moveFile(realCertFile, tempDir)
cmd = "cd '%s' && if [ -f '%s' ];then tar -zxvf %s;fi" % \
(localDnDir, DefaultValue.CERT_BACKUP_FILE,
DefaultValue.CERT_BACKUP_FILE)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
cmd = "cp '%s'/* '%s' && rm -rf '%s'" % (
tempDir, localDnDir, tempDir)
(status, output) = subprocess.getstatusoutput(cmd)
raise Exception(
(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd)
+ "Failed uncompression SSL backup file."
+ "Error: \n%s" % output)
# remove temp directory
if (os.path.exists(tempDir)):
g_file.removeDirectory(tempDir)
# set guc option
if (os.path.isfile(
os.path.join(localDnDir, DefaultValue.SSL_CRL_FILE))):
cmd = \
"gs_guc set -D %s " \
"-c \"ssl_crl_file=\'%s\'\"" \
% (localDnDir, DefaultValue.SSL_CRL_FILE)
else:
cmd = \
"gs_guc set -D %s " \
"-c \"ssl_crl_file=\'\'\"" % localDnDir
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
raise Exception(
ErrorCode.GAUSS_514["GAUSS_51400"]
% cmd + "Error: \n%s" % output)
if (os.path.isfile(os.path.join(localDnDir, EMPTY_CERT))):
os.remove(os.path.join(localDnDir, EMPTY_CERT))
self.logger.log(
"Successfully rollback SSL cert files with local mode.")
return
else:
self.logger.log("There is not exists backup files.")
return
# 1.check backup file "gsql_cert_backup.tar.gz" on all dbnodes.
for node in allDnNodeDict.keys():
backupGzFile = os.path.join(allDnNodeDict[node],
DefaultValue.CERT_BACKUP_FILE)
status = self.sshTool.checkRemoteFileExist(
node, backupGzFile,
self.context.g_opts.mpprcFile)
if not status:
noBackupList.append(node)
if (len(noBackupList) > 0):
raise Exception(
(ErrorCode.GAUSS_502["GAUSS_50201"]
% DefaultValue.CERT_BACKUP_FILE)
+ "Can't rollback SSL cert files on %s." % noBackupList)
# 2.perform rollback on all dbnodes.
for node in allDnNodeDict.keys():
backupGzFile = os.path.join(
allDnNodeDict[node], DefaultValue.CERT_BACKUP_FILE)
# 2-1.move SSL cert files in dn directory to temp directory.
sshcmd = "cd '%s' && if [ -d '%s' ];then rm -rf '%s'" \
" && mkdir '%s';else mkdir '%s';fi" % \
(allDnNodeDict[node], temp, temp, temp, temp)
self.sshTool.executeCommand(sshcmd, "Make temp directory.",
DefaultValue.SUCCESS, \
[node], self.context.g_opts.mpprcFile)
for certFile in backupList:
realCertFile = os.path.join(allDnNodeDict[node], certFile)
sshcmd = " %s && " % g_Platform.getCdCmd(
os.path.join(allDnNodeDict[node], temp))
sshcmd += g_file.SHELL_CMD_DICT["renameFile"] % (
realCertFile, realCertFile, "./")
self.sshTool.executeCommand(
sshcmd,
"Backup cert files to temp directory.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
# 2-2.uncompression "gsql_cert_backup.tar.gz" file
sshcmd = "cd '%s' && if [ -f '%s' ];then tar -zxvf %s;fi" % \
(allDnNodeDict[node], DefaultValue.CERT_BACKUP_FILE,
DefaultValue.CERT_BACKUP_FILE)
self.sshTool.executeCommand(sshcmd,
"Unzip backup file.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
# 2-3.clear temp directory
sshcmd = " %s && " % g_Platform.getCdCmd(allDnNodeDict[node])
sshcmd += g_file.SHELL_CMD_DICT["deleteDir"] % (temp, temp)
self.sshTool.executeCommand(sshcmd,
"Clear backup cert files.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
# 2-4.is have "sslcrl-file.crl",config 'ssl_crl_file' option
status = self.sshTool.checkRemoteFileExist(
node, os.path.join(
allDnNodeDict[node],
DefaultValue.SSL_CRL_FILE),
self.context.g_opts.mpprcFile)
# exists 'sslcrl-file.crl' file ,config option of 'postgresql.conf'
if (status):
if node == DefaultValue.GetHostIpOrName():
sshcmd = \
"gs_guc set -D %s " \
"-c \"ssl_crl_file='%s'\"" \
% (allDnNodeDict[node], DefaultValue.SSL_CRL_FILE)
else:
sshcmd = "gs_guc set -D %s " \
"-c \"ssl_crl_file=\\\\\\'%s\\\\\\'\"" \
% (allDnNodeDict[node], DefaultValue.SSL_CRL_FILE)
self.sshTool.executeCommand(sshcmd,
"Exist 'ssl_crl_file'",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
else:
if (node == DefaultValue.GetHostIpOrName()):
sshcmd = "gs_guc set " \
"-D %s -c \"ssl_crl_file=''\"" % (
allDnNodeDict[node])
else:
sshcmd = "gs_guc set " \
"-D %s -c \"ssl_crl_file=\\\\\\'\\\\\\'\"" \
% (allDnNodeDict[node])
self.sshTool.executeCommand(sshcmd,
"No exist 'ssl_crl_file'",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
# Clear empty file.
if (self.isDnEmpty(node)):
sshcmd = g_file.SHELL_CMD_DICT["deleteFile"] % (
os.path.join(allDnNodeDict[node], EMPTY_CERT),
os.path.join(allDnNodeDict[node], EMPTY_CERT))
self.sshTool.executeCommand(sshcmd,
"Clear empty file.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
self.logger.log(
"Successfully rollback SSL cert files on [%s]." % node)
def getDnNodeDict(self):
"""
function: get dbnodes information
input: NA
output: dictionary
"""
clusterDnNodes = {}
if (not self.context.clusterInfo.isSingleInstCluster()):
return clusterDnNodes
for node in self.context.clusterInfo.dbNodes:
if (len(node.datanodes) > 0):
clusterDnNodes[node.datanodes[0].hostname] = node.datanodes[
0].datadir
self.logger.debug("Successfully get database node dict.")
return clusterDnNodes
def distributeDNCert(self, certList, dnDict=None):
"""
function: distribute ssl cert files on single_inst cluster
input: certList: cert files list
dnDict: dictionary
output: NA
"""
tempDir = "tempCertDir"
gphost = DefaultValue.getTmpDirFromEnv()
if dnDict is None:
dnDict = {}
dnName = dnDict.keys()
certPathList = []
self.logger.debug(certList)
for num in iter(certList):
sslPath = os.path.join(os.path.join(gphost, tempDir), num)
certPathList.append(sslPath)
# local mode
if self.context.g_opts.localMode:
localDnDir = dnDict[DefaultValue.GetHostIpOrName()]
for num in range(len(certList)):
# distribute gsql SSL cert
if (os.path.isfile(os.path.join(localDnDir, certList[num]))):
os.remove(os.path.join(localDnDir, certList[num]))
if (os.path.isfile(certPathList[num])):
g_file.cpFile(certPathList[num],
os.path.join(localDnDir, certList[num]))
g_file.changeMode(DefaultValue.KEY_FILE_MODE,
os.path.join(localDnDir, certList[num]))
# remove 'sslcrl-file.crl' file
if (DefaultValue.SSL_CRL_FILE not in certList and
os.path.isfile(
os.path.join(localDnDir, DefaultValue.SSL_CRL_FILE))):
os.remove(os.path.join(localDnDir, DefaultValue.SSL_CRL_FILE))
# config 'sslcrl-file.crl' option in 'postgresql.conf'
if (os.path.isfile(
os.path.join(localDnDir, DefaultValue.SSL_CRL_FILE))):
cmd = "gs_guc set " \
"-D %s -c \"ssl_crl_file=\'%s\'\"" % \
(localDnDir, DefaultValue.SSL_CRL_FILE)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
raise Exception(
(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd)
+ "Failed set 'ssl_crl_file' option."
+ "Error: \n%s" % output)
else:
cmd = "gs_guc set -D %s -c \"ssl_crl_file=\'\'\"" \
% localDnDir
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
raise Exception(
(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd)
+ "Failed set 'ssl_crl_file' option."
+ "Error: \n%s" % output)
# remove backup flag file 'certFlag'
if (os.path.isfile(os.path.join(localDnDir, 'certFlag'))):
os.remove(os.path.join(localDnDir, 'certFlag'))
self.logger.log(
"Replace SSL cert files with local mode successfully.")
return
# not local mode
for node in dnName:
for num in range(len(certList)):
sshcmd = g_file.SHELL_CMD_DICT["deleteFile"] % (
os.path.join(dnDict[node], certList[num]),
os.path.join(dnDict[node], certList[num]))
self.sshTool.executeCommand(sshcmd,
"Delete read only cert file.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
if (os.path.exists(certPathList[num])):
self.sshTool.scpFiles(certPathList[num], dnDict[node],
[node])
# change permission of cert file 600,
# there no need to is exists file,
# because the files must be exist.
sshcmd = g_file.SHELL_CMD_DICT["changeMode"] % (
DefaultValue.KEY_FILE_MODE,
os.path.join(dnDict[node], certList[num]))
self.sshTool.executeCommand(sshcmd,
"Change file permisstion.'",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
if (DefaultValue.SSL_CRL_FILE in certList):
if (node == DefaultValue.GetHostIpOrName()):
sshcmd = "gs_guc set " \
"-D %s -c \"ssl_crl_file='%s'\"" \
% (dnDict[node], DefaultValue.SSL_CRL_FILE)
else:
sshcmd = "gs_guc set " \
" -D %s -c \"ssl_crl_file=\\\\\\'%s\\\\\\'\"" \
% (dnDict[node], DefaultValue.SSL_CRL_FILE)
self.sshTool.executeCommand(sshcmd,
"Find 'ssl_crl_file'",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
else:
# no ssl cert file there will delete old cert file,
# and config option ssl_crl_file = ''
sshcmd = g_file.SHELL_CMD_DICT["deleteFile"] % (
os.path.join(dnDict[node], DefaultValue.SSL_CRL_FILE),
os.path.join(dnDict[node], DefaultValue.SSL_CRL_FILE))
self.sshTool.executeCommand(sshcmd,
"Find 'ssl_crl_file'",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
if (node == DefaultValue.GetHostIpOrName()):
sshcmd = "gs_guc set " \
"-D %s -c \"ssl_crl_file=\'\'\"" % (dnDict[node])
else:
sshcmd = \
"gs_guc set " \
"-D %s " \
"-c \"ssl_crl_file=\\\\\\'\\\\\\'\"" % (dnDict[node])
self.sshTool.executeCommand(sshcmd,
"Find 'ssl_crl_file'",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
# remove file 'sslcrl-file.crl'
sshcmd = g_file.SHELL_CMD_DICT["deleteFile"] % (
os.path.join(dnDict[node], DefaultValue.SSL_CRL_FILE),
os.path.join(dnDict[node], DefaultValue.SSL_CRL_FILE))
self.sshTool.executeCommand(sshcmd,
"Delete read only cert file.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
# remove backup flag file 'certFlag'
sshcmd = g_file.SHELL_CMD_DICT["deleteFile"] % (
os.path.join(dnDict[node], "certFlag"),
os.path.join(dnDict[node], "certFlag"))
self.sshTool.executeCommand(sshcmd,
"Delete backup flag file.",
DefaultValue.SUCCESS,
[node],
self.context.g_opts.mpprcFile)
self.logger.log("%s replace SSL cert files successfully." % node)
###########################################################################
# Kerberos Flow
###########################################################################
def doKerberos(self):
"""
function: operation kerberos
input: NA
output: NA
"""
try:
if self.context.g_opts.kerberosMode == "install":
self.logger.log("Starting install Kerberos.", "addStep")
cmd = "%s -m %s -U %s --%s" % \
(OMCommand.getLocalScript("Local_Kerberos"),
"install",
self.context.g_opts.clusterUser,
self.context.g_opts.kerberosType)
# local mode
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] %
"Command: %s. Error:\n%s" % (cmd, output))
self.logger.log("Successfully install Kerberos.")
elif self.context.g_opts.kerberosMode == "uninstall":
self.logger.log("Starting uninstall Kerberos.", "addStep")
cmd = "%s -m %s -U %s" % \
(OMCommand.getLocalScript("Local_Kerberos"),
"uninstall",
self.context.g_opts.clusterUser)
# local mode
(status, output) = subprocess.getstatusoutput(cmd)
if status != 0:
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] %
"Command: %s. Error:\n%s" % (cmd, output))
self.logger.log("Successfully uninstall Kerberos.")
except Exception as e:
raise Exception(str(e))
def checkRemoteFileExist(self, filepath):
"""
funciton:check file exist on remote node
input:filepath
output:dictionary
"""
existNodes = []
for nodeName in self.context.clusterInfo.getClusterNodeNames():
if (nodeName == DefaultValue.GetHostIpOrName()):
continue
if (self.sshTool.checkRemoteFileExist(nodeName, filepath, "")):
existNodes.append(nodeName)
return existNodes
def recursivePath(self, filepath):
"""
function: recursive path
input: filepath
output: NA
"""
fileList = os.listdir(filepath)
for fileName in fileList:
fileName = os.path.join(filepath, fileName)
# change the owner of files
g_file.changeOwner(self.context.g_opts.user, fileName)
if (os.path.isfile(fileName)):
# change fileName permission
g_file.changeMode(DefaultValue.KEY_FILE_MODE, fileName)
else:
# change directory permission
g_file.changeMode(DefaultValue.KEY_DIRECTORY_MODE, fileName,
True)
self.recursivePath(fileName)
def checkNode(self):
"""
function: check if the current node is to be uninstalled
input : NA
output: NA
"""
pass
def stopCluster(self):
"""
function:Stop cluster
input:NA
output:NA
"""
pass
def startCluster(self):
"""
function:Start cluster
input:NA
output:NA
"""
pass