首页 > 代码库 > python业务更新程序

python业务更新程序

开发动机:

    作为一名专业的运维人员,面对业务系统更新是再正常不过得了,但是面对每周两次以上,并且都要在晚上才可以做到的更新,作为一名有远大理想并时刻想变技术方面的“糕富帅”的男人,怎么可以容忍这样的单一重复毫无技术含量的工作占用我过多的时间,一直秉承机器的事情让机器去处理的原则,说白了就是秉承偷懒的基础想法,我还是决定搞个小工具来帮助我处理这样些烦人的东西。

开发语言:

    毫无疑问的用了python,别问我为什么。

开发时间:

    断断续续3-4周,其中还要兼顾其他的工作,如果专心写估计就2周左右。

开发框架:

    C/S模式,tkinter+fabric+paramiko++mysql+shell,现在很多都用B/S模式,事实上这样直接操作服务器东西,个人觉得直接放网上的话实在是不安全。

开发IDE:

    pycharm,个人喜好,不行可以直接文本写j_0062.gif

开发内容与过程:

    其实这里我想写编程思想,语言是思想的承载,没有思想管你什么语言你都做不了什么事情。

    1、tkhinter做界面

    2、fabric解决透过堡垒机的情况

    3、paramiko解决上传问题

    4、各种内部服务器处理shell

    5、mysql里面导入了当前的服务器的用户与密码

    6、做好ssh-key信任关系,当前升级机器要在堡垒机跟目标服务器都添加ssh私匙,不做就无法通过


no code no bb,贴上代码:

updategui.py

__author__ = ‘samfeng‘
#coding=utf-8
import tkFileDialog, tkMessageBox, os, uploadfile
from fabric.api import local
from Tkinter import Label, Entry, Button, Text, Tk, END, INSERT, W, E
root = Tk()
root.title("-----------交易系统业务更新程序-----------")
root.geometry(‘750x680‘)

class Dilog_window_init():
    def __init__(self, *args, **kwargs):
        self.label_blank = Label(root, text=‘‘)
        self.label_step1 = Label(root, text=‘Step 1:‘)
        self.label_step2 = Label(root, text=‘Step 2:‘)
        self.label_step3 = Label(root, text=‘Step 3:‘)
        self.label_step4 = Label(root, text=‘update file:‘)
        self.label_baoleiji = Label(root, text=‘堡垒机(hostname/ip):‘)
        self.label_targethost = Label(root, text=‘目标主机(hostname/ip):‘)
        self.lock_lable = Label(root, width=20)
        self.hostname_or_ip1 = Entry(root, width=60)
        self.hostname_or_ip2 = Entry(root, width=60)
        self.select_file = Entry(root, width=60)
        self.select_command_file = Entry(root, width=60)
        self.select_overload_file = Entry(root, width=60)
        self.select_overload_remote_file = Entry(root, width=60)
        self.label_upload = Label(root, text=‘上传文件:‘)
        self.label_command_lujin = Label(root, text=‘选择执行脚本路径:‘)
        self.label_overload_lujin = Label(root, text=‘选择本地要更新的文件:‘)
        self.label_overload__remote_lujin = Label(root, text=‘填充远端更新文件路径:‘)
        self.label_overload = Label(root, text=‘选择执行脚本路径:‘)
        self.lock1 = Button(root, text=‘锁定‘, command=lambda: self.check_button(1, self.hostname_or_ip1), bg=‘red‘, fg=‘white‘)
        self.unlock1 = Button(root, text=‘不锁定‘, command=lambda: self.check_button(0, self.hostname_or_ip1), bg=‘red‘, fg=‘white‘)
        self.select_button = Button(root, text=‘选择文件‘, command=lambda: self.selectfile(self.select_file), bg=‘red‘, fg=‘white‘)
        self.select_button1 = Button(root, text=‘选择文件‘, command=lambda: self.selectfile(self.select_command_file), bg=‘red‘, fg=‘white‘)
        self.select_button2 = Button(root, text=‘选择文件‘, command=lambda: self.selec_update_file(self.select_overload_file), bg=‘red‘, fg=‘white‘)
        self.upload_button = Button(root, text=‘==上           传==‘, command=self.upload_to_server, bg=‘red‘, fg=‘white‘)
        self.cancel_button = Button(root, text=‘==取           消==‘, command=self.cancel_file, bg=‘red‘, fg=‘white‘)
        self.lock2 = Button(root, text=‘锁定‘, command=lambda: self.check_button(1, self.hostname_or_ip2), bg=‘red‘, fg=‘white‘)
        self.unlock2 = Button(root, text=‘不锁定‘, command=lambda: self.check_button(0, self.hostname_or_ip2), bg=‘red‘, fg=‘white‘)
        self.start_button = Button(root, text=‘===启动业务===‘, command=self.start_host, bg=‘red‘, fg=‘white‘)
        self.stop_button = Button(root, text=‘===停止业务===‘, command=self.stop_host, bg=‘red‘, fg=‘white‘)
        self.update_button = Button(root, text=‘===更新文件===‘, command=self.update_file,  bg=‘red‘, fg=‘white‘)
        self.restart_button = Button(root, text=‘===重启业务===‘, command=self.restart_host, bg=‘red‘, fg=‘white‘)
        self.help_button = Button(root, text=‘使用前说明,请点我‘, command=self.help_t, bg=‘red‘, fg=‘white‘)
        self.help_text = Text(root, bg="Beige", width=50, height=15)
        self.close_button = Button(root, text=‘===关     闭===‘, command=root.quit, bg=‘red‘, fg=‘white‘)
        self.label_blank.grid(row=0, column=0)
        self.label_step1.grid(row=1, column=0)
        self.label_baoleiji.grid(row=2, column=1)
        self.hostname_or_ip1.grid(row=2, column=2)
        self.label_blank.grid(row=2, column=3)
        self.lock1.grid(row=2, column=4)
        self.label_blank.grid(row=2, column=5)
        self.unlock1.grid(row=2, column=6)
        self.label_blank.grid(row=3, column=0)
        self.label_targethost.grid(row=3, column=1)
        self.hostname_or_ip2.grid(row=3, column=2)
        self.label_blank.grid(row=3, column=3)
        self.lock2.grid(row=3, column=4)
        self.label_blank.grid(row=3, column=5)
        self.unlock2.grid(row=3, column=6)
        self.label_blank.grid(row=4, column=0)
        self.label_step2.grid(row=5, column=0)
        self.label_upload.grid(row=6, column=1, sticky=E)
        self.select_file.grid(row=6, column=2)
        self.label_blank.grid(row=6, column=3)
        self.select_button.grid(row=6, column=4)
        self.upload_button.grid(row=7, column=2, sticky=W)
        self.cancel_button.grid(row=7, column=2, sticky=E)
        self.label_blank.grid(row=8, column=0)
        self.label_step3.grid(row=9, column=0)
        self.label_command_lujin.grid(row=10, column=1, sticky=E)
        self.select_command_file.grid(row=10, column=2)
        self.label_blank.grid(row=10, column=3)
        self.select_button1.grid(row=10, column=4)
        self.start_button.grid(row=12, column=2, sticky=W)
        self.stop_button.grid(row=12, column=2, sticky=E)
        self.label_step4.grid(row=14, sticky=W)
        self.label_overload_lujin.grid(row=15, column=1, sticky=E)
        self.select_overload_file.grid(row=15, column=2)
        self.label_blank.grid(row=15, column=3)
        self.select_button2.grid(row=15, column=4)
        self.label_overload__remote_lujin.grid(row=16, column=1, sticky=E)
        self.select_overload_remote_file.grid(row=16, column=2)
        self.update_button.grid(row=17, column=2, sticky=W)
        self.restart_button.grid(row=17, column=2, sticky=E)
        self.label_blank.grid(row=18, column=3)
        self.label_blank.grid(row=19, column=3)
        self.help_button.grid(row=20, column=2, sticky=W)
        self.close_button.grid(row=20, column=2, sticky=E)
        self.help_text.grid(row=21, column=2, sticky=W)


    def check_button(self, item, hi):
        if item == 1:
            text_cont = hi.get()
            hi.configure(state="disabled")
        else:
            hi.configure(state="normal")

    def selectfile(self, file_path):
        self.filename = tkFileDialog.askopenfilename(parent=root)
        file_path.delete(0, END)
        file_path.insert(0, self.filename)

    def selec_update_file(self, file_path):
        self.update_filename = tkFileDialog.askopenfilename(parent=root)
        file_path.delete(0, END)
        file_path.insert(0, self.update_filename)

    def cancel_file(self):
        self.select_file.delete(0, END)

    def upload_to_server(self):
        text_ip1 = self.hostname_or_ip1.get()
        text_ip2 = self.hostname_or_ip2.get()
        if text_ip1 == ‘‘ or text_ip2 == ‘‘:
            tkMessageBox.showwarning(title="警告", message="请先完成Step1,输入主机名或者IP")
        else:
            targetfile = os.path.split(self.filename)
            lastword_file = targetfile[-1]
            upload_value = uploadfile.upload_ssh(text_ip1, self.filename, lastword_file)
            if upload_value != "":
                self.help_text.insert(INSERT, upload_value)
                uploadfile.remote_scp(text_ip1, text_ip2, lastword_file)

    def start_host(self):
        text_ip1 = self.hostname_or_ip1.get()
        text_ip2 = self.hostname_or_ip2.get()
        if text_ip1 == ‘‘ or text_ip2 == ‘‘:
            tkMessageBox.showwarning(title="警告", message="请先完成Step1,输入主机名或者IP")
        else:
            host1 = ‘qhiex@‘+text_ip1
            host2 = ‘qhiex@‘+text_ip2
            fabpath = self.select_command_file.get()
            if fabpath == ‘‘:
                tkMessageBox.showwarning(title="警告", message="请选择执行脚步路径!")
            else:
                m=local(‘fab -f ‘+fabpath+‘ -g ‘+host1+‘ -H ‘+host2+‘ update_remotehost‘)
                self.help_text.insert(INSERT, m+"\n")

    def stop_host(self):
        text_ip1 = self.hostname_or_ip1.get()
        text_ip2 = self.hostname_or_ip2.get()
        if text_ip1 == ‘‘ or text_ip2 == ‘‘:
            tkMessageBox.showwarning(title="警告", message="请先完成Step1,输入主机名或者IP")
        else:
            host1 = ‘qhiex@‘+text_ip1
            host2 = ‘qhiex@‘+text_ip2
            fabpath = self.select_command_file.get()
            if fabpath == ‘‘:
                tkMessageBox.showwarning(title="警告", message="请选择执行脚步路径!")
            else:
                m=local(‘fab -f ‘+fabpath+‘ -g ‘+host1+‘ -H ‘+host2+‘ stop_remotehost‘)
                self.help_text.insert(INSERT, m+"\n")

    def update_file(self):
        text_ip1 = self.hostname_or_ip1.get()
        text_ip2 = self.hostname_or_ip2.get()
        update_file_lujing = self.select_overload_file.get()
        fabpath = self.select_command_file.get()
        if text_ip1 == ‘‘ or text_ip2 == ‘‘ or update_file_lujing == ‘‘ or fabpath == ‘‘:
            tkMessageBox.showwarning(title="警告", message="请输入主机名或者IP,并确保是否选择了脚本文件以及更新文件!")
        else:
            targetfile = os.path.split(self.update_filename)
            lastword_file = targetfile[-1]
            upload_value = uploadfile.upload_ssh(text_ip1, self.update_filename, lastword_file)
            if upload_value != "":
                uploadfile.remote_scp(text_ip1, text_ip2, lastword_file)
                host1 = ‘qhiex@‘+text_ip1
                host2 = ‘qhiex@‘+text_ip2
                remote_path = self.select_overload_remote_file.get()
                m=local(‘fab -f ‘+fabpath+‘ -g ‘+host1+‘ -H ‘+host2+‘ update_file:‘+lastword_file+‘,‘+remote_path, capture=True)
                self.help_text.insert(INSERT, m)


    def restart_host(self):
        text_ip1 = self.hostname_or_ip1.get()
        text_ip2 = self.hostname_or_ip2.get()
        if text_ip1 == ‘‘ or text_ip2 == ‘‘:
            tkMessageBox.showwarning(title="警告", message="请先完成Step1,输入主机名或者IP")
        else:
            host1 = ‘qhiex@‘+text_ip1
            host2 = ‘qhiex@‘+text_ip2
            fabpath = self.select_command_file.get()
            if fabpath == ‘‘:
                tkMessageBox.showwarning(title="警告", message="请选择执行脚步路径!")
            else:
                local(‘fab -f ‘+fabpath+‘ -g ‘+host1+‘ -H ‘+host2+‘ restart_host‘)


    def help_t(self):
        self.help_text.insert(INSERT, "1.环境设定:本程序使用了python2.7,fabric,不具备的话,麻烦在百度或者google下载安装\n")
        self.help_text.insert(INSERT, "2.该程序client端与server端已经打通了ssh通道,如果不知道怎么建立本机的ssh-key,"
                                      "可以下载个git客户端生成,并上传到相关服务器\n")
        self.help_text.insert(END, "3.有问题可以联系QQ:649081773,tel:13715165238")

if __name__ == "__main__":
    app = Dilog_window_init()
    root.mainloop()

uploadfile.py

__author__ = ‘samfeng‘
#coding=utf-8
import paramiko
from os import path
from sys import exit
import getpass
import mysql.connector, ConfigParser
from mysql.connector import errorcode
def con_mysql(host):
    configFeed = ConfigParser.ConfigParser()
    configFeed.read(‘conn.conf‘)
    connectuser = configFeed.get(‘user‘, ‘user‘)
    connectp = configFeed.get(‘pa‘, ‘password‘)
    connecthost = configFeed.get(‘host‘, ‘host‘)
    connetdatabase = configFeed.get(‘database‘, ‘database‘)
    try:
        cnx = mysql.connector.connect(
            user=connectuser,
            passwd=connectp,
            host=connecthost,
            database=connetdatabase
        )
    except mysql.connector.Error as err:
        if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
            print("Something is wrong with your user name or password")
        elif err.errno == errorcode.ER_BAD_DB_ERROR:
            print("Database does not exists")
        else:
            print(err)

    c = cnx.cursor()
    c.execute("select passwd from hosta where inter_ip=%s", (host, ))
    p = c.fetchall()
    c.close()
    return p

def upload_ssh(gatewayhost, localpath, remotefile):
    p = con_mysql(gatewayhost)
    p = ‘‘.join(p[0])
    t = paramiko.Transport((gatewayhost, 22))
    t.connect(username="qhiex", password=p)
    sftp = paramiko.SFTPClient.from_transport(t)
    remotepath = ‘/xxx/xxx/xx/‘+remotefile
    if path.exists(localpath):
        sftp.put(localpath, remotepath)
        return "upload success!"
    else:
        print("could not find local file!")
    t.close()

def remote_scp(gatewayhost, targethost, remotefile):
    try:
        user_name = getpass.getuser()
        h = paramiko.SSHClient()
        h.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        h.connect(gatewayhost, username=‘qhiex‘, key_filename=‘C:\\Users\\‘+user_name+‘\\.ssh\\id_rsa‘)
        h.exec_command("scp /xxx/xxx/xx/"+remotefile+" qhiex@"+targethost+":/xxx/xxx/xxx/"+remotefile)
        h.close()
    except paramiko.AuthenticationException:
        print(‘Authentication failed!‘)
        print "could not ssh to remotehost!"
        exit(1)

在贴上丑陋的界面:

wKioL1R9kGGwjypjAAH_eow02Xo557.jpg



本文出自 “fengyunsen” 博客,请务必保留此出处http://samfeng.blog.51cto.com/52272/1585664

python业务更新程序