Ap版本升级工具

Zss 发表于:

在之前的批量上传 Firmware想到每次AP的升级挺麻烦的,经常性的要找固件,有时候下载的bin文件不同一个地方,所以又重新要找文件再次下载

索性将其做成一个升级的脚本,每次选择来升级就好了,升级时分为三种模式,仅保存网络配置,不保存所有配置,保存所有配置

其中重点还是在于模拟表单的提交,和之前的上传固件类似,没有做成批量升级的ap,因为我没这么多ap要一次性来升级

输入ip来确定升级哪个ap,输入关键字在服务器上来搜索对应的版本,列出所有对应版本,用户再次选择使用正确的来升级

若此固件存在则不下载,若不存在则下载,来升级,最后使用ping来判断升级是否成功了

—————> Ap升级工具 <—————
1.输入需要升级AP的IP地址:
192.168.99.252
2.输入Firmware版本关键字来搜索:
1711
升级方式:0.保存所有配置,1.不保存所有配置,2.仅保存网络配置
3.输入升级方式:
1
—–> 关键字为:1711 正在搜索Firmware: <—–

—————> 搜索到的Firmware如下: <—————

<1> A2c_2.2.0.1711.AC00_2018-08-30
<2> A2n_2.2.0.1711.AC00_2018-08-30
<3> A3c_A2ac_2.2.0.1711.AC00_2018-08-30
<4> A3x_2.2.0.1711.AC00_2018-08-30
<5> C1n_2.2.0.1711.AC00_2018-08-30
<6> C2_2.2.0.1711.AC00_2018-08-30
——————————————————-

请选择你需要升级的固件:
6
——————————————————-

正在下载中… 文件名:C2_2.2.0.1711.AC00_2018-08-30

–> C2_2.2.0.1711.AC00_2018-08-30.bin 下载成功! p( ^ O ^ )q

–> 正在上传固件到AP,请稍后。。。
–> 固件上传成功!
–> 正在升级中,请稍后。。。
–> 正在检测升级是否完成,请稍后。。。
–> Ap升级成功!!!

–>回车结束

#coding:utf-8
import os,requests,time
from lxml import etree
from subprocess import *

class Update():
    def __init__(self):
        """
        设置以当前文件夹下的各个文件为公共路径
        """
        self.fw_bin_path = os.getcwd()+'\\Bin\\'
        self.fw_down_list = []  #需要下载的bin文件

    def vs_choicc(self):
        print('-' * 15 + '>  Ap升级工具  <' + '-' * 15)
        ip_chioce = raw_input('1.输入需要升级AP的IP地址:\n')
        vs_choice = raw_input('2.输入Firmware版本关键字来搜索:\n')
        print('升级方式:0.保存所有配置,1.不保存所有配置,2.仅保存网络配置')
        choice = raw_input('3.输入升级方式:\n')
        return (ip_chioce,vs_choice,choice)

    def check_folder(self):
        if not os.path.exists(self.fw_bin_path):
            os.makedirs(self.fw_bin_path)

    def check_fw(self,vs_choice):
        print('-' * 5 + '>  关键字为:%s 正在搜索Firmware:   <'%vs_choice + '-' * 5 + '\n')
        ac_url = 'http://10.6.127.6/redmine/projects/altaicare/files'
        cm_url = 'http://10.6.127.6/redmine/projects/a8n-openwrt/files'
        try:
            ac_rsp = requests.get(ac_url).content
            ac_xml = etree.HTML(ac_rsp)
            cm_rsp = requests.get(cm_url).content
            cm_xml = etree.HTML(cm_rsp)
            fw_name_list = ac_xml.xpath('//*[@id="content"]/table/tbody/tr/td[1]/a/text()')+cm_xml.xpath('//*[@id="content"]/table/tbody/tr/td[1]/a/text()')
            fw_url_list = ac_xml.xpath('//*[@id="content"]/table/tbody/tr/td[1]/a/@href')+cm_xml.xpath('//*[@id="content"]/table/tbody/tr/td[1]/a/@href')
            fw_info_list = zip(fw_name_list,fw_url_list)
        except Exception as e:
            print '错误:%s'%e
        index = 1
        for i in fw_info_list:
            if vs_choice in i[0]:
                fw_url = 'http://10.6.127.6' + i[1]
                self.fw_down_list.append((index,i[0],fw_url))
                index += 1
        if len(self.fw_down_list)==0:
            print('关键字:%s,暂时没有搜索到相对应的Firmware,请重新搜索...'%(vs_choice))
            raw_input('回车结束')
            exit()
        else:
            print('-' * 15 + '>  搜索到的Firmware如下:   <' + '-' * 15 + '\n')
            for i in self.fw_down_list:
                print '<%d> %s'%(i[0],i[1].strip('.bin'))
        print('-' * 55 + '\n')

    def user_choice(self):
        update_fw = raw_input('请选择你需要升级的固件:\n')
        for i in self.fw_down_list:
            if update_fw == str(i[0]):
                return i

    def down_fw(self,fw_info):
        print('-' * 55 + '\n')
        bin_list = os.listdir(self.fw_bin_path)
        if fw_info[1] not in bin_list:
            print('正在下载中... 文件名:%s\n' % (fw_info[1].strip('.bin')))
            rsp = requests.get(fw_info[2]).content
            try:
                with open(self.fw_bin_path + fw_info[1],'wb') as f:
                    f.write(rsp)
                print('--> %s 下载成功! p( ^ O ^ )q\n' % fw_info[1])
            except Exception as e:
                print '--> 文件下载失败,错误信息:%s'%e
        else:
            print('--> Firmware文件夹中已存在此bin文件\n')

    def login(self,ap_ip):
        url = 'http://%s/cgi-bin/luci' % (ap_ip)
        data = {
            'username': 'admin',
            'password': 'admin'
        }
        rsp = requests.post(url=url, data=data, allow_redirects=False)
        cookie1 = rsp.headers['Set-Cookie']
        cookie = cookie1.split(';')
        sysauth = cookie[0] + ';' + cookie[2].split(',')[1]
        path = (cookie[1] + ';' + cookie[2].split(',')[0])[6:]
        return (sysauth, path)

    def up_fw(self,ap_ip,info,bin):
        headers = {
            'Connection':'keep-alive',
            'Host':'%s'%ap_ip[0],
            'Origin':'http://%s'%ap_ip[0],
            'Referer':'http://%s%s/admin/administration/firmware_update/'%(ap_ip[0],info[1]),
            'Cookie':'%s'%info[0]}
        file_data = open(self.fw_bin_path + '%s'%bin, 'rb')
        url = 'http://%s%s/admin/administration/firmware_update'%(ap_ip[0],info[1])
        print('--> 正在上传固件到AP,请稍后。。。')
        file_list = {"step": (None, "2"), "image": ('%s'%bin, file_data.read())}
        rsp = requests.post(url,headers=headers,files=file_list)
        print('--> 固件上传成功!')
        headers2 = {'Referer':'http://%s%s/admin/administration/firmware_update?step=3&keepcfg=%s&nolink=1'%(ap_ip[0],info[1],ap_ip[2]),
                    'Host':'%s'%ap_ip[0],
                    'Cookie':'%s'%info[0]}
        url = 'http://%s%s/admin/administration/firmware_update?step=4&keepcfg=%s&_=0.297191314660294'%(ap_ip[0],info[1],ap_ip[2])
        rsp2 = requests.get(url,headers=headers2)
        print('--> 正在升级中,请稍后。。。')

    def check_ping(self,ap_ip):
        cmd = 'ping %s -n 2'%ap_ip
        time.sleep(20)
        print('--> 正在检测升级是否完成,请稍后。。。')
        while 1:
            result = Popen(cmd,shell=True,stdout=PIPE)
            if len(result.stdout.readlines()) == 9:
                print '--> Ap升级成功!!!'
                break
        raw_input('\n-->回车结束')


if __name__ == '__main__':
    update = Update()
    choiceinfo = update.vs_choicc()
    update.check_folder()
    update.check_fw(choiceinfo[1])
    down_info = update.user_choice()
    update.down_fw(down_info)
    info = update.login(choiceinfo[0])
    update.up_fw(choiceinfo,info,down_info[1])
    update.check_ping(choiceinfo[0])