func是个很好用的运维工具,但很久没对知识做总结。前段时间写了个小工具方便自己及身边同事使用。


主要目的是方便使用,将常用的func功能集中起来;二是返回日志比较靠谱,比如说运行一个'date'命令,返回结果为:

"主机名" ##  "0" "Thu Sep 12 16:41:50 CST 2013"

主机名  ## “命令状态” “命令内容”

并且在出错时也不会大量返回python错误信息:)


fun的python modulelist地址在:https://fedorahosted.org/func/wiki/ModulesList


51cto插入代码换行不正常


#!/usr/bin/env python
#-*- coding: utf-8 -*-
# potaski@qq.com
# 通过func模块连接LINUX服务器,运行指定命令
# ver-0.98
# 2013-09-09
"""
修改日志:
    ver-0.95
        1.调整运行参数
        2.新增推送文件功能
        3.修改日志格式
    ver-0.98
        1.首个靠谱版本
        2.新增修改umask为系统默认"0022"
"""
"""
必须在func master中运行
3种运行方式
    运行命令行
        python FuncExec.py -c "命令"
    运行程序(shell/python or other)
        python FuncExec.py -r 文件名
    传送文件到目标服务器
        python FuncExec.py -s 本地文件路径 远端文件路径
"""
import func.overlord.client as func
import getopt
import sys
import os
hostfile = 'server.csv'
#服务器主机信息文件格式: hostname
worklogfile = 'work.log'
def func_chk(hostname):
    """
        import func.overlord.client as func
        Usage: func_chk(hostname)
        Des: 输入(主机名) --> 输出(主机的func状态func_status,检查信息chkfunclog)
    """
    global func_status
    global chkfunclog
    func_status = ''
    chkfunclog = '"%s" ## "func service ok"' % (hostname)
    chkfunc_dict = {}
    chk_host_cmd = 'grep '+ hostname + ' /etc/hosts' + '|wc -l'
    chk_result = os.popen(chk_host_cmd).read().strip('\n')
    if chk_result == '1':
        try:
            client = func.Client(hostname)
            chk_sys_cmd = 'hostname'
            chkfunc_dict = client.command.run(chk_sys_cmd)
            chkfunc_dict_list = chkfunc_dict[hostname]
            # 列表去空值
            while '' in chkfunc_dict_list:
                chkfunc_dict_list.remove('')
            chkfunc_result = chkfunc_dict_list[1].strip('\n')
            if chkfunc_result == hostname.upper():
                func_status = 'ok'
                chkfunclog = '"%s" ## "%s" "%s"' % (hostname,chkfunc_dict_list[0],chkfunc_dict_list[1].strip('\n'))
            elif len(chkfunc_dict_list) >= 3:
                func_status = 'fail'
                m = 3
                chkfunclog = '"%s" ## ' % (hostname)
                for i in range(0,m):
                    chkfunclog = chkfunclog + ' "%s"' % chkfunc_dict_list[i]
            else:
                func_status = 'fail'
                chkfunclog = '"%s" ## "%s" "%s"' % (hostname,chkfunc_dict_list[0],chkfunc_dict_list[1].strip('\n'))
                #chkfunclog = '"%s" ## "serv hostname isn`t matching"' % (hostname)
        except:
            func_status = 'fail'
            chkfunclog = '"%s" ## "certificate not found"' % (hostname)
    else:
        func_status = 'fail'
        chkfunclog = '"%s" ## "serv info error in /etc/hosts"' % (hostname)
def output_log(logfile, log_content):
    """
        Usage: output_log(日志文件,日志内容)
        Des: 输入(日志文件,日志内容) --> 输出(日志内容追加写入到日志文件)
    """
    log = open(logfile,'a')
    txt_content = log_content + '\n'
    log.write(txt_content)
    log.close()
def usage():
    howto = '''
    Usage: ./FuncExec.py -argument
        -c $your_command   # Execute a command line
        -r $your_script_name    # Execute a script (shell, python or other, running as './$your_script_name')
        -s $local_file $remote_file   # Send a file to target server
        -h    # Print how to
    '''
    print(howto)
"""
MAIN: 开始运行
"""
notice = 'null'
#-- 确认主机名列表文件
pwd = os.getcwd()
hostfile = pwd+'/server.csv'
if os.path.isfile(hostfile):
    print('## hostfiile exist ......')
else:
    print('Unable to find hostfile: '+ hostfile + '.  Quit ......')
    sys.exit()
#-- 确认运行参数&运行种类
try:
    opts,args = getopt.getopt(sys.argv[1:], 'c:r:s');
    len_opts = str(len(opts))
    if len_opts == '0':
        print('## getopt error!')
        usage()
        sys.exit()
    for o,a in opts:
        if o in ('-c'):
            cmd = a
            run_module = 'cmd'
            notice = 'Your command is: '+ cmd
        elif o in ('-r'):
            script_file = a
            run_module = 'script'
            notice = 'Your script file is: '+ script_file
        elif o in ('-s'):
            local_path = args[0]
            remote_path = args[1]
            run_module = 'file'
            notice = 'Local file is: '+ local_path + '\n' + 'Remote file is: '+ remote_path
except getopt.GetoptError:
    print('## getopt error!')
    usage()
    sys.exit()
#-- 用户确认运行内容
running = True
print(notice)
while running:
    run_flag = raw_input('Enter "yes" to continue or Enter "exit" to quit ...... ')
    if run_flag == 'yes':
        print('Command had confirm, start running ...... ')
        running = False
    elif run_flag == 'exit':
        print('Ok , program will be stop ...... ')
        sys.exit()
#-- 打开hostfile,逐台操作主机
f = open(hostfile)
line = f.readline()
while line:
    hostname = 'null'
    hostname = line.strip('\n')
    # 验证主机func状态
    func_chk(hostname)
    if func_status == 'ok':
        client = func.Client(hostname)
        run_dict = {}
        if run_module in ('cmd'):
            # 跑命令
            run_dict = client.command.run('umask 0022;'+ cmd)
        elif run_module in ('script'):
            # 跑脚本
            remote_path = '/tmp/func_tmp_script'
            client.local.copyfile.send(script_file, remote_path)
            client.command.run('chmod u+x '+ remote_path)
            run_dict = client.command.run('umask 0022; ./'+ remote_path)
        elif run_module in ('file'):
            # 抛文件
            run_dict = client.local.copyfile.send(local_path, remote_path)
        # 调整输出
        try:
            run_dict_list = run_dict[hostname]
            while '' in run_dict_list:
                run_dict_list.remove('')
            run_log = '"%s" ## ' % (hostname)
            for i in run_dict_list:
                log_info = str(i).strip('\n')
                run_log = '%s "%s"' % (run_log,log_info)
        except:
            # type(run_dict) = bool; run_dict = True
            if run_dict == True:
                run_log = '"%s" ## "file transfer ok"' % (hostname)
            else:
                run_log = '"%s" ## "file transfer fail"' % (hostname)
        # 输出信息
        output_log(worklogfile,run_log)
    elif func_status == 'fail':
        output_log(worklogfile, chkfunclog)
    print '%s run finished.' % (hostname)
    # 结束
    line = f.readline()
# 关循环
f.close()