0

I have to login to remote machine using SSH. SSH prompt is diferent in first time login and second time login. First time, I have to type "Yes". Then it will get stored in the known host so that next time logins will not ask this "Yes".

After first time login, I need to execute a command that will do a reboot. Once the device comes up after reboot after 1 minute, I have try to login again to execute remaining 5 commands. Some commands are not generic linux commands.

I'm giving here manual execution for a single remote server. The same thing I have ot do for 7 remote machines.

PS C:\Users\user1> ssh xyz@20.x.x.181
The authenticity of host '20.x.x.181 (20.x.x.181)' can't be established.
ECDSA key fingerprint is SHA256:R++eRV4YRmKsfMUr4BZ+Hx7gQmwW/dXeFsi4O6SybII.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '20.x.x.181' (ECDSA) to the list of known hosts.
viptela 20.9.999-sdwanaas-20.9-305

(xyz@20.x.x.181) Password:
Last login: Wed Aug 23 11:23:09 UTC 2023 from 128.x.x.180 on ssh
Welcome to Viptela CLI
User xyz last logged in 2023-08-23T04:06:20.207088+00:00, to ip-10-0-1-94, from 44.224.28.225 using netconf-ssh
xyz connected from 128.x.x.180 using ssh on vsmart-1
vsmart-1# tools support touch_testbed
File is touched (please login again)
Connection to 20.x.x.181 closed by remote host.
Connection to 20.x.x.181 closed.
PS C:\Users\user1>
PS C:\Users\user1> ssh xyz@20.x.x.181
viptela 20.9.999-sdwanaas-20.9-305

(xyz@20.x.x.181) Password:
Last login: Wed Aug 23 11:26:03 UTC 2023 from 128.x.x.180 on pts/0
Welcome to Viptela CLI
User xyz last logged in 2023-08-23T11:26:04.046308+00:00, to ip-10-0-1-96, from 128.x.x.180 using cli-ssh
xyz connected from 128.x.x.180 using ssh on vsmart-1
vsmart-1# tools internal ip_netns options "exec default bash"
vsmart-1:~# touch /etc/viptela/testbed
vsmart-1:~# touch /boot/testbed
vsmart-1:~# ls -l /etc/viptela/testbed;
-rw------- 1 root root 0 Aug 23 11:29 /etc/viptela/testbed
vsmart-1:~# ls -l /boot/testbed;
-rwx------ 1 root root 0 Aug 23 11:30 /boot/testbed
vsmart-1:~#

What I tried:

import paramiko

hostname = []
list_of_ip = "20.x.x.181, 20.x.x.182, 20.x.x.183, 20.x.x.184, 20.x.x.185, 20.x.x.186, 20.x.x.187"
hostname=list_of_ip.split(",")
username = "xyz"
password = "abcdefghijk123456789"
cmd1="tools support touch_testbed"
cmd2='tools internal ip_netns options "exec default bash"'
cmd3="touch /etc/viptela/testbed"
cmd4="touch /boot/testbed"
cmd5="ls -l /etc/viptela/testbed;"
cmd6="ls -l /boot/testbed;"

#initialize the SSH client
client = paramiko.SSHClient()
#add to known hosts
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Login first time to execute the first command
for ip in hostname:
    print("ssh xyz@"+ip)
    try:
        client.connect(hostname=ip, username=username, password=password)
        #device will go for reboot after this first command
        stdin, stdout, stderr = client.exec_command(cmd1)
        #print the output of the command to check if it is successful
    except:
        print("[!] Cannot connect to the SSH Server")
        exit()
        
        
#Login second time to execute the remaining 5 commands
for ip in hostname:
    print("ssh xyz@"+ip)
    try:
        client.connect(hostname=ip, username=username, password=password)
        stdin, stdout, stderr = client.exec_command(cmd2)
        stdin, stdout, stderr = client.exec_command(cmd3)
        stdin, stdout, stderr = client.exec_command(cmd4)
        stdin, stdout, stderr = client.exec_command(cmd5)
        stdin, stdout, stderr = client.exec_command(cmd6)
        #print the output of the command to check if it is successful
    except:
        print("[!] Cannot connect to the SSH Server")
        exit()

Output with error:

ssh xyz@20.x.x.181
ssh xyz@20.x.x.182
ssh xyz@20.x.x.183
ssh xyz@20.x.x.184
ssh xyz@20.x.x.185
ssh xyz@20.x.x.186
ssh xyz@20.x.x.187

Exception ignored in: <function BufferedFile.__del__ at 0x000001EB18C1ED30>
Traceback (most recent call last):
  File "C:\Users\user1\AppData\Local\Programs\Python\Python39\lib\site-packages\paramiko\file.py", line 67, in __del__
  File "C:\Users\user1\AppData\Local\Programs\Python\Python39\lib\site-packages\paramiko\channel.py", line 1390, in close
  File "C:\Users\user1\AppData\Local\Programs\Python\Python39\lib\site-packages\paramiko\channel.py", line 989, in shutdown_write
  File "C:\Users\user1\AppData\Local\Programs\Python\Python39\lib\site-packages\paramiko\channel.py", line 965, in shutdown
  File "C:\Users\user1\AppData\Local\Programs\Python\Python39\lib\site-packages\paramiko\transport.py", line 1920, in _send_user_message
AttributeError: 'NoneType' object has no attribute 'time'
Dipankar Nalui
  • 1,121
  • 5
  • 18
  • 33
  • What error(s) are you getting? exec_command will only execute once, then the session is disconnected. You need to create a virtual terminal to execute several commands (`invoke_shell()`). See my answer here: https://stackoverflow.com/a/76140994/11355926 – Cow Aug 23 '23 at 11:58
  • added the error message after edit – Dipankar Nalui Aug 23 '23 at 12:06
  • If you're going to be logged into multiple systems at once, don't use the high-level API. Store a Transport for each system explicitly and call `exec_command()` on the Transport object for the individual target machine; don't ask a single Client to magically figure out which Transport you want to use at any given time. – Charles Duffy Aug 23 '23 at 12:11
  • Or if you _do_ want to use the Client API, use a separate Client object for each machine you're connecting to. But you can't use one Client for several concurrent connections like this. – Charles Duffy Aug 23 '23 at 12:13

0 Answers0