利用paramiko模块写一个对linux系统批量巡检的python脚本

1. 代码简介

1.1 代码核心模块

  1. python环境是python3;尽量用最新版本
  2. 用到了paramiko模块来实现对linux服务器的ssh远程及命令执行
  3. 用到了logging模块来实现日志的格式化输出
  4. 用到了collections模块中的OrderedDict来实现有序的字典(python3.6及以后即便是普通字典类型,也可以有序读取),可以按照主机列表及命令列表中的顺序进行各个巡检项
  5. 由于代码量本身较少,因此仅将主机列表和命令列表单独写到一个base_info.py文件中,便于之后的扩展,符合开放封闭原则

1.2 扩展

  1. 此脚本可完成较为简单的linux巡检项的巡检,而且其核心为linux的命令
  2. 脚本可再对各项功能进行函数封装
  3. 如果要完善脚本,还可以增加对返回数据的处理,将返回数据写入excel文件中来生成指定格式的巡检表

2. 代码详情

base_info.py

关注点:通过OrderedDict生成有序的字典,可以按照字典中主机信息的顺序对主机进行链接巡检,同时可以按照命令的排列顺序进行命令执行与结果接收

import time
from collections import OrderedDict
day_time_now = time.strftime('%Y.%m.%d')

# 主机列表及登录信息
host_info = OrderedDict(
    [
        (
            'host01',
            {
     
                'hostname': '192.168.199.26',
                'port': 22,
                'username': 'root',
                'password': 'XXX'
            }
        ),
        (
            'host02',
            {
     
                'hostname': '192.168.199.27',
                'port': 22,
                'username': 'root',
                'password': 'XXX'
            }
        ),
        (
            'host03',
            {
     
                'hostname': '192.168.199.28',
                'port': 22,
                'username': 'root',
                'password': 'XXX'
            }
        ),
    ]
)


# 命令列表
cmd_list = OrderedDict(
    [
        ('sys_time','date'),
        ('disk','df -h'),
        ('memory','free -g'),
        ('top','top -b -n 1 | head -n 5'),
        ('ES','curl -XGET localhost:9200/_cluster/health?pretty'),
        ('ES_index_now','curl -XGET localhost:9200/_cat/indices/*'+day_time_now+'*'),
        ('supervisor_status','supervisorctl status')
    ]
)

sshCheck.py

import time
import logging
import paramiko
from base_info import host_info,cmd_list

file_time = time.strftime('%Y%m%d%H%M%S')

# logging
fh = logging.FileHandler(filename='run.log',mode='a',encoding='utf-8')
logging.basicConfig(level=logging.INFO,
                    handlers=[fh],
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s -%(lineno)d:  %(message)s'
                    )

logging.info('#'*15+'开始执行脚本'+'#'*15)
# 创建SSH对象
# ssh = paramiko.SSHClient()
# # 允许连接不在know_hosts文件中的主机
# ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())


for host in host_info:
    with open('checkResult_' + file_time + '.txt', mode='a+', encoding='utf-8') as f:
        try:
            ssh = paramiko.SSHClient()
            # 允许连接不在know_hosts文件中的主机
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            print('开始连接主机%s' % host_info[host]['hostname'])
            logging.info('开始连接主机%s' % host_info[host]['hostname'])
            ssh.connect(host_info[host]['hostname'], host_info[host]['port'], host_info[host]['username'], host_info[host]['password'])
            time_now = time.strftime('%Y-%m-%d %H:%M:%S')
            # with open('checkResult_'+file_time+'.txt',mode='a+',encoding='utf-8') as f:
            title1 = '#'*10+'IP:'+host_info[host]['hostname']+'时间:'+time_now+'#'*10+'\n'    # 也可用%s格式化
            print(title1)
            f.write(title1)
            for cmd_name in cmd_list:
                logging.info('开始执行%s相关命令' % cmd_name)
                stdin, stdout, stderr = ssh.exec_command(cmd_list[cmd_name])
                ret = stdout.read()
                title2 = '=' * 12+ cmd_name+ '=' * 12+'\n'
                print(title2)
                f.write(title2)
                if len(ret) == 0:
                    result_err = stderr.read().decode('utf-8')
                    logging.info(result_err.strip())
                    print(result_err)
                    f.write(result_err)
                else:
                    resault_out = ret.decode('utf-8')
                    print(resault_out)
                    f.write(resault_out)
            print(host_info[host]['hostname']+' 统计完成\n')
            logging.info('主机%s信息统计完成' % host_info[host]['hostname'])
            ssh.close()
        except:
            print('%s主机连接失败' % host_info[host]['hostname'])
            f.write('\n%s主机连接失败\n\n' % host_info[host]['hostname'])
            logging.warn('%s主机连接失败' % host_info[host]['hostname'])

ipt = input('统计完毕,按任意键结束!\n')
print('再见!')
logging.info('#'*15+'本次统计结束'+'#'*15)

你可能感兴趣的:(python)