# -*- 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. # ---------------------------------------------------------------------------- import os from gspylib.inspection.common.CheckItem import BaseItem from gspylib.inspection.common.CheckResult import ResultStatus from base_utils.os.env_util import EnvUtil from base_utils.os.file_util import FileUtil DIRECTORY_MODE = 750 g_result = [] g_chList = [] class CheckDirPermissions(BaseItem): def __init__(self): super(CheckDirPermissions, self).__init__(self.__class__.__name__) def obtainDataDirLength(self, nodeInfo): """ function: Obtain data dir length input: NA output: int, list """ # Get the longest path DirLength = 0 dataDirList = [] # Get the DB instance and the longest DB path for inst in nodeInfo.datanodes: dataDirList.append(inst.datadir) if (len(inst.datadir) > DirLength): DirLength = len(inst.datadir) # Get the CMserver instance and longest path in the CMserver, DN for inst in nodeInfo.cmservers: dataDirList.append(inst.datadir) if (len(inst.datadir) > DirLength): DirLength = len(inst.datadir) # Get the CMagent instance and longest path in the CM, DN for inst in nodeInfo.cmagents: dataDirList.append(inst.datadir) if (len(inst.datadir) > DirLength): DirLength = len(inst.datadir) # Get the CN instance and longest path in the CM, DN, CN for inst in nodeInfo.coordinators: dataDirList.append(inst.datadir) if (len(inst.datadir) > DirLength): DirLength = len(inst.datadir) # Get the GTM instance and longest path in the CM, DN, CN, GTM for inst in nodeInfo.gtms: dataDirList.append(inst.datadir) if (len(inst.datadir) > DirLength): DirLength = len(inst.datadir) # Get the ETCD instance and longest path in the all instance if (hasattr(nodeInfo, 'etcds')): for inst in nodeInfo.etcds: dataDirList.append(inst.datadir) if (len(inst.datadir) > DirLength): DirLength = len(inst.datadir) return (DirLength, dataDirList) def checkSingleDirectoryPermission(self, singledir, desc, INDENTATION_VALUE_INT): """ function: Check Directory Permissions input: String, String, int output: int """ # The directory must be a folder if (not os.path.isdir(singledir)): g_result.append( "%s: Abnormal reason: Directory does not exist." % ( "%s directory(%s)" % (desc, singledir)).ljust( INDENTATION_VALUE_INT)) return -1 # Gets the folder permissions currentPremission = int(oct(os.stat(singledir).st_mode)[-3:]) # Check the write access and compare the permission size if (FileUtil.checkDirWriteable(singledir) and currentPremission <= DIRECTORY_MODE): g_result.append( "%s: Normal" % ("%s directory(%s) permissions %s" % ( desc, singledir, str(currentPremission))).ljust( INDENTATION_VALUE_INT)) return 0 elif (currentPremission > DIRECTORY_MODE): g_result.append( "%s: Abnormal reason: Directory permission" " can not exceed 750." % (("%s directory(%s) permissions %s" % (desc, singledir, str(currentPremission))).ljust(INDENTATION_VALUE_INT))) return -1 else: g_result.append( "%s: Abnormal reason: Directory is not writable for users." % ("%s directory(%s) permissions %s" % (desc, singledir, str(currentPremission))).ljust(INDENTATION_VALUE_INT)) return -1 def doCheck(self): global g_chList global g_result resultList = [] g_result = [] nodeInfo = self.cluster.getDbNodeByName(self.host) tmpDir = EnvUtil.getEnv("PGHOST") logDir = EnvUtil.getEnv("GAUSSLOG") toolDir = EnvUtil.getEnv("GPHOME") (intervalLen, instList) = self.obtainDataDirLength(nodeInfo) if intervalLen < len(self.cluster.appPath): intervalLen = len(self.cluster.appPath) if intervalLen < len(logDir): intervalLen = len(logDir) INDENTATION_VALUE_INT = intervalLen + 44 # Check the permissions for appPath resultList.append( self.checkSingleDirectoryPermission(self.cluster.appPath, "AppPath", INDENTATION_VALUE_INT)) g_chList.append(self.cluster.appPath) # Check the permissions for tmpPath resultList.append(self.checkSingleDirectoryPermission( tmpDir, "Tmp", INDENTATION_VALUE_INT)) # Check the permissions for logPath g_chList.append(tmpDir) resultList.append(self.checkSingleDirectoryPermission( logDir, "Log", INDENTATION_VALUE_INT)) # Check the permissions for logPath g_chList.append(logDir) resultList.append( self.checkSingleDirectoryPermission(toolDir, "ToolPath", INDENTATION_VALUE_INT)) # Check the permissions for all CMserver g_chList.append(toolDir) # Check the permissions for all DB instance for inst in nodeInfo.datanodes: resultList.append( self.checkSingleDirectoryPermission(inst.datadir, "DN", INDENTATION_VALUE_INT)) # Check the xlog permissions for all DB instance xlogDir = "%s/pg_xlog" % inst.datadir resultList.append( self.checkSingleDirectoryPermission(xlogDir, "DN Xlog", INDENTATION_VALUE_INT)) g_chList.append(inst.datadir) g_chList.append(xlogDir) if (-1 in resultList): self.result.rst = ResultStatus.NG else: self.result.rst = ResultStatus.OK self.result.val = "" for detail in g_result: self.result.val = self.result.val + '%s\n' % detail def doSet(self): for dirName in g_chList: FileUtil.changeOwner(self.user, dirName, True) FileUtil.changeMode(DIRECTORY_MODE, dirName) self.result.val = "Set DirPermissions completely."