阅读文档系统说明文档,发现精读效果太差,建立的系统的信息基点不足。快速阅读,先看目录,然后看每篇文章的头和尾,主要关注概念与定义,不关注实现与功能细节。阅读完,在大脑中生成两张图,一张是文档结构图,一张是系统架构图
实践操作。操作过程主要包括:
1、把原目录A下的文件AAA,远程传输到主机S1和S2的目录B下,并备份目录B下的原文件。
2、继续传输,连续传输6个文件,使用File Zilla工具。
总耗时2个小时。主要工作是:
1、检查原目录下的文件是否存在
2、ssh到远端检查远程目录是否存在,远程目录文件是否存在,备份远程目录文件。6次检查,每次两台主机,总共检查12次
3、使用ftp工具上传文件,上传时设定本机目录,设定远端目录,点击上传。完全手工操作,容易出错。
4、文件上传之后,ssh到远程检查文件是否是最新。相当于重复步骤2
5、ssh远程主机,在各个目录下分别执行kill和start命令,kill前检查进程是否存在,start后检查是否启动完成,又是12次操作。
自动化分析:
功能操作分解:本机检查文件存在以及最新,远程检查目录是否存在,远程备份文件,上传文件,确认远端文件正确上传,确认进程是否存在,停止进程,启动进程
编码功能:
由于python丰富的运维库,采用python语言来实现。采用paramiko实现
文件格式:
caltest.war,d:\pkg\version,/app/bjmbill/user,username,password,192.168.1.1
代码如下:
import paramiko
import os
import time
import logging
date = time.strftime("%Y%m%d")
file_name ="oper_log_%s.log"%date
print(file_name)
logging.basicConfig(filename=file_name,
level=logging.DEBUG,filemode='w' ,
datefmt='%Y-%m-%d %H:%M:%S',
format ='%(asctime)s %(filename)s : %(levelname)s %(message)s',
)
logger = logging.getLogger(__name__)
# 从文件中读取文件名,本地目录,远程目录,用户名
# caltest.war , d:\pkg\version\ , /home/emer/toma/, emer
def get_file_info(file_name):
result = {}
with open(file_name) as f:
for (num, value) in enumerate(f):
# value = value.strip()
if not len(value):
continue
result[num] = {'file_name': value.split(',')[0],'local_dir': value.split(',')[1],
'remote_dir': value.split(',')[2],'user_name': value.split(',')[3],
'password': value.split(',')[4],'ip': value.split(',')[5]
}
f.close()
logger.info("打印文件内容%s"%result)
return result
# 远程操作类,在远程主机上的动作
class RemoteOper(object):
# 根据协议选择不同的连接方式,返回连接本身
# def 登录远端(协议方法,用户名,密码,端口号,密钥串)
def loginRomote(self, protocol_method, host_info):
ip,user_name,password,port,remote_file = host_info[0], host_info[1], host_info[2], host_info[3], host_info[
4]
if protocol_method =="SSH":
paramiko.util.log_to_file('sysLogin.txt')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="IP",username="user_name",password="password",key_filename="key_filename")
return ssh
if protocol_method =="FTP":
t = paramiko.Transport("IP")
t.connect(user_name="",password="")
sftp = paramiko.SFTPClient.from_transport(t)
return sftp
# def 执行命令,exec_command(command),由于本机与远程执行方法一样,不单独列出
# def 检查文件是否存在(文件名),返回最新日期和属性
def checkFile(self, loginRomote, file_name):
file_info = loginRomote.exec_command("ls -l %s"%file_name)
logger.info(file_info)
# def 备份文件,返回备份后的文件属性
def backFile(self, host_info, file_name):
ip, user_name, password, port, remote_file = host_info[0], host_info[1], host_info[2], host_info[3], host_info[
4]
logger.info('待备份文件%s'%file_name)
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=ip,username=user_name,password=password)
time_bak = time.strftime("%m%d")
command1 ="cp -p -r %s %s" %(file_name, file_name +'_' + time_bak)
logger.info("准备开始执行命令%s" % command1)
stdin, stdout, stderr = ssh.exec_command(command1)
logger.info(stdout.read())
command2 ="ls -l %s" %(file_name +'*')
logger.info("准备开始执行命令%s" % command2)
stdin, stdout, stderr = ssh.exec_command(command2)
logger.info(stdout.read())
ssh.close()
return 0
except Exception as e:
ssh.close()
logger.info("文件备份失败失败username=%s,password=%s,ip=%s,port=%s,file_name=%s,remote_dir=%s",
user_name, password, ip, port, file_name, remote_dir)
return -1
# def 检查进程存在(进程名,数量)
def checkProcess(self, loginRemote, process_name, num):
pro_num = loginRemote.exec_command("ps -ef|grep %s |wc -l"%process_name)
if pro_num == num:
logger.info("进程%s数量正常,为%s"%(process_name, pro_num))
else:
logger.info("进程%s数量异常,应为%s,为%s"%(process_name, num, pro_num))
# 本地操作类,主要是检查本地文件,与上传
class LocalOper(object):
def listAllFile(self, dir_name):
def processDir(self, dir_name, file_names):
logger.info('Director', dir_name)
for file_namein file_names:
logger.info("FIle", file_name)
os.walk(dir_name, processDir,None)
# def 检查本地文件(文件名)
def isFile(self, file_name):
if os.path.isfile(file_name):
logger.info("%s文件存在"%file_name)
else:
logger.info("%s文件不存在"%file_name)
# def 文件上传
def upFile(self, host_info, file_name):
ip,user_name,password,port,remote_file = host_info[0],host_info[1],host_info[2],host_info[3],host_info[4]
try:
t = paramiko.Transport(ip,port)
t.connect(username=user_name,password=password)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put(file_name,remote_file)
logger.info("文件上传成功username=%s,password=%s,ip=%s,port=%s,file_name=%s,remote_dir=%s",
user_name, password, ip, port, file_name, remote_dir)
logger.info(sftp.stat(remote_file))
t.close()
return 0
except Exception as e:
t.close()
logger.info("文件上传失败username=%s,password=%s,ip=%s,port=%s,file_name=%s,remote_dir=%s",
user_name, password, ip, port, file_name, remote_dir)
return -1
# 返回最新日期和属性
if __name__ =='__main__':
#生成日志文件
date = time.strftime("%Y%M%D")
log_file_name ="oper_log_%s.log"%date
logging.basicConfig(filename=log_file_name,level=logging.DEBUG)
fileInfo = get_file_info("testdeploy.txt")
#文件格式内容:caltest.war , d:\pkg\version\ , /home/emer/toma/, emer,192.168.1.1
# file_name local_dir remote_dir user_name ip
#单文件调试
#文件上传
localOper = LocalOper();
key =0
local_file_name = os.path.join(fileInfo[key]['local_dir'], fileInfo[key]['file_name']).strip(' ')
file_name = fileInfo[key]['file_name']
local_dir = fileInfo[key]['local_dir']
remote_dir = fileInfo[key]['remote_dir']
user_name = fileInfo[key]['user_name']
password = fileInfo[key]['password']
ip = fileInfo[key]['ip'].strip()
remote_file_name = remote_dir +'/' + file_name
logger.debug("列出当前目录下本地文件%s" %(fileInfo[key]['local_dir']))
localOper.listAllFile(local_dir)
logger.debug("检查本地文件%s" % local_file_name)
localOper.isFile(local_file_name)
#ip, user_name, password, port, remote_dir,用户名和密码信息从文件中读取
host_info =[ip,user_name,password,22,remote_file_name]
#备份文件
remoteOper = RemoteOper()
if remoteOper.backFile(host_info,remote_file_name) !=0:
logger.error("文件备份失败")
#上传文件
if localOper.upFile(host_info, local_file_name) !=0:
logger.error("文件上传失败")
# 读取文件,文件名,本地目录,上传目录,上传用户名(考虑自动获取啊)
# for 循环
# 检查本地文件
# 登录远端
# 检查远端文件
# 备份文件
# 上传文件
# 比对文件
#
# 读取文件,获取进程名
# 检查进程,停进程,启动进程,检查进程