How to run this script in a more sophisticated way?

-2

Good morning.

I am using this code to update the firmware of my company's servers.

However, I wanted to use this same code to update a list of servers, not just one.

Follow the original code:

#!/usr/bin/python

from paramiko import SSHClient
import paramiko

    class SSH:
            def __init__(self):
                self.ssh = SSHClient()
                self.ssh.load_system_host_keys()
                self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                self.ssh.connect(hostname='blhp0032.locaweb.com.br',username='Administrator',password='SenhaServidor')

            def exec_cmd(self,cmd):
                stdin,stdout,stderr = self.ssh.exec_command(cmd)
                if stderr.channel.recv_exit_status() != 0:
                    print stderr.read()
                else:
                    print stdout.read()

    if __name__ == '__main__':
        ssh = SSH()
        ssh.exec_cmd("update image force http://firmware.tecnologia.ws/firmware/hpoa485.bin")

My question is this: I tried to adapt the code to update a list, using Ubuntu commands, but it did not succeed. Here is modified code:

#!/usr/bin/python

from paramiko import SSHClient
import paramiko
import sys

    class SSH:
        def processar(ip):

            def __init__(self):
                self.ssh = SSHClient()
                self.ssh.load_system_host_keys()
                self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                self.ssh.connect(hostname=ip,username='Administrator',password='SenhaServidor')

            def exec_cmd(self,cmd):
                stdin,stdout,stderr = self.ssh.exec_command(cmd)
                if stderr.channel.recv_exit_status() != 0:
                    print stderr.read()
                else:
                    print stdout.read()

    if __name__ == '__main__':
        ssh = SSH()
        ssh.exec_cmd("update image force http://firmware.tecnologia.ws/firmware/hpoa485.bin")


        if __name__ == "__main__":
            for ip in sys.argv[1:]: 
                processar(ip)

However, when the squeeze command on the terminal cat lista.txt | xargs script.py it returns me the following error:

    Traceback (most recent call last):
  File "update_oa_teste.py", line 24, in <module>
    ssh.exec_cmd("update image force http://firmware.tecnologia.ws/firmware/hpoa485.bin")
AttributeError: SSH instance has no attribute 'exec_cmd'

Remembering that I created a .txt file in the same directory as the script, which contains the list of servers on which I want to run the script's SSH command.

Help me, please.

Thank you !!

    
asked by anonymous 06.09.2018 / 11:23

1 answer

0

You do not have to complicate it so much, just put ip as a parameter of __init__ of your original class even without creating subnables:

#!/usr/bin/python

from paramiko import SSHClient
import paramiko
import sys

class SSH:
    def __init__(self, ip):
        self.ssh = SSHClient()
        self.ssh.load_system_host_keys()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh.connect(hostname=ip, username='Administrator',password='SenhaServidor')

    def exec_cmd(self,cmd):
        stdin,stdout,stderr = self.ssh.exec_command(cmd)
        #if stderr.channel.recv_exit_status() != 0:
        #    print stderr.read()
        #else:
        #    print stdout.read()
        return stdin, stdout, stderr

if __name__ == '__main__':
    results = []

    for ip in sys.argv[1:]:
        ssh = SSH(ip)
        result = ssh.exec_cmd("update image force http://firmware.tecnologia.ws/firmware/hpoa485.bin")
        results.append(result)

    for stdin, stdout, stderr in results:
        if stderr.channel.recv_exit_status() != 0:
            print stderr.read()
        else:
            print stdout.read()

In addition, another modification was to get results recovery from exec_cmd , to prevent the method from waiting for results from one of the servers. The way I did, it will send the command to all the servers first, and then wait for the results, so the command runs simultaneously on all servers.

    
06.09.2018 / 20:11