Automate ssh commands with python [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So everyday, I need to login to a couple different hosts via ssh and run some maintenance commands there in order for the QA team to be able to test my features.
I want to use a python script to automate such boring tasks. It would be something like:
ssh host1
deploy stuff
logout from host1
ssh host2
restart stuff
logout from host2
ssh host3
check health on stuff
logout from host3
...
It's killing my productivity, and I would like to know if there is something nice, ergonomic and easy to implement that can handle and run commands on ssh sessions programmatically and output a report for me.
Of course I will do the code, I just wanted some suggestions that are not bash scripts (because those are not meant for humans to be read).

You can use the following things programmatically:
For low-level SSH automation - Paramiko
For somewhat higher-level automation - Fabric
Alternatively, if your activities are all around automation of typical sysadmin tasks - have a look at orchestration tools:
Ansible
Saltstack
To give an example in Fabric, define a task to login to a host and run uname -a:
from fabric import *
from fabric.api import *
env.hosts = ['localhost']
def login_to_host_and_run_uname():
run('uname -a')
You can run it as a standalone fabric command:
[none][20:03:32] vlazarenko#alluminium (~/tests)$ fab -f fab.py login_to_host_and_run_uname
[localhost] Executing task 'login_to_host_and_run_uname'
[localhost] run: uname -a
[localhost] Passphrase for private key:
[localhost] out: Darwin alluminium 16.5.0 Darwin Kernel Version 16.5.0: Tue Jan 31 18:57:20 PST 2017; root:xnu-3789.50.195.1.1~1/RELEASE_X86_64 x86_64
[localhost] out:
Done.
Disconnecting from localhost... done.
Fabric also supports easy wrappers for sudo(), caches and works with SSH keys, etc, etc. Allows for easy task parallelisation over multiple hosts and so on.

Could you set up a Cron job or similar on those hosts? That would probably be ideal.
If you don't have the permission to set up Cron jobs, I use a library called paramiko. The code goes like this:
ssh = paramiko.SSHClient()
ssh.connect(host, port=p, timeout=2)
cmd = "ls"
stdin, stdout, stderr = ssh.exec_command(cmd)
for line in stdout.readlines():
print(line)
ssh.close()

If these manual stuffs is too many, then I may look into some server configuration managements like Ansible.
I have done this kinda automation using:
Ansible
Python Fabric
Rake

Related

How to stub out and test ssh commands

I am a developer on a system that sends out ssh commands, roughly in the format 'ssh -o 'BatchMode yes' hostname command'. I am working on our end to end testing and am tasked with mocking out the remote servers during testing. I need to prevent the ssh command running on the remote server, and instead capture the ssh command in some way, check it matches what I expect for that test and return a response specified specifically for that test to control the test flow. My system is in python and runs in RHEL7 docker containers, a solution that can be created within those technologies would be preferable. Does anyone have any suggestions of the best way to do this?
I have considered alias'ing ssh but i don't think that's ideal as i'm restricting the scope of the test more than if the ssh command is carried out. My best idea is creating a mock ssh server that captures the command but i have yet to find the technology to easily capture a non-interactive ssh command and respond.

python ssh script to deal with secondary shell

I want to write a python script to ssh into a server and print some output. But I have some problem here when coding, here is what I basically want to achieve:
[zz#bts01 ~]$ cd /opt/cdma-msc/
[zz#bts01 cdma-msc]$ ./sccli
SoftCore for CDMA CLI (c) Quortus 2010
RAN> show system
System Configuration
Software version: V1.31
System name: RAN
System location:
Shutdown code:
Emergency call dest:
Current date/time: Tue Feb 27 14:27:41 2018
System uptime: 20h 33m
Auto-provisioning: Enabled
RAN> exit
Bye.
[zz#bts01 cdma-msc]$
Please see above I only want the show system output.
But problem is I use python paramiko ssh package, looks like it is not recognize the second shell after I execute the ./sccli command.
what can I do to allow python ssh script interactive with the second shell (above 'RAN>')?
Thanks!!
There exists a python library that was built for running SSH commands from Python. It is pretty powerful and robust. You can run commands across many machines in parallel, it has error handling, can execute as root.. etc. etc.
Check it out: https://github.com/dwighthubbard/sshmap
Learning how to use this library is very valuable if you have to do SSH commands from python frequently.

Python script to connect via ssh, run process and disconnect without waiting

I have a problem with running non finishing process via ssh from python script. What I need to do:
Connect to remote server via ssh
Run mongod on this server
Finish script execution without killing mongod process
For now, I'm using subprocess.Popen in this way:
subprocess.Popen(['ssh', 'user#' + host, 'mongod', '-f', '/temp-mongo.conf', '&'])
Problem is that script ends before I'm asked about user password, so it finishes with Too many authentication failures for root.
I tried to use p = subprocess.Popen(...).communicate() and it'a almost ok, but then script waits for mongod command to be finished, what obviously won't happen.
What is proper way to do this? Can I do something to pass password automatically?
I agree with e4c5 that you should use a tool like Fabric for that. If you want to stay with the dirty way something like this should work:
subprocess.call('ssh user#%s "mongod -f /temp-mongo.conf &>/dev/null &"' % host,
shell=True)
Note that you need to do:
quotes around the remote call
add &>/dev/null which routes all output of mongod to /dev/null (without this it will block, not 100% sure why. Probably since the stdout of the shell is attached to the command)
use shell=True so the shell builds up the command for you (so you don't need to put a ", " instead of each space)
This also works with auth over public key (instead of writing the password by hand)
The proper way for SSH without having to enter passwords is to use public key authentication.
I would also look at Fabric for running commands via SSH.
And you aren't running the command in a shell environment on the server. If you run
ssh host ls &
the & will actually put ssh in the background, not ls on the host. Instead try doing
ssh host sh -c 'ls &'

Pythonic way to work with multiple linux machines?

I am trying to write a framework which has capability to entaract with multiple linux machines.
For example my test case which is going to use that framework can be able to start a server in a linux machine, start a client in another linux machine and then should be able to make some configuration changes in a different linux machine without waiting for any command to complete.
I have tried using pexpect to do my job but didn't find it more useful.
Can anyone suggest me any Python module which i can use to do my task ?
My Testcase steps are like:
1. Login to SIP Server -> su -> start SIP server
2. Login to Voice Server -> su -> make some configuration changes
3. Login to SIP client -> su -> start SIP client
4. Collect logs and perform validations
In my environment I can't login into my machines directly as su.
You should look into using something like python-fabric It allows you to use higher level language constructs such as context managers and makes the shell more usable with python in general.
Example usage:
fabfile.py
from fabric.api import run
def host_type():
run('uname -s')
Then you can use host_type from the commandline in the directory of fabfile.py:
$ fab -H localhost,linuxbox host_type
[localhost] run: uname -s
[localhost] out: Darwin
[linuxbox] run: uname -s
[linuxbox] out: Linux

Script to Shutdown Ubuntu [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I want to write a script which can Shutdown remote Ubuntu system. Actually i want my VM to shutdown safely when i shutdown my main machine on which my VM is installed .
Is there is any of doing this with the help of Sh scripts or script written in any language like Python.
You can run the following command from a remote Linux machine (VM Host):
ssh root#<vm-client-ip> "shutdown -h now"
You will have to input your root password for the remote machine. You can prevent this by adding ssh certificates (good if you are writing a script):
SSH login without password
If you make a script out of this, don't forget to add a delay after the shutdown (e.g. sleep 10) so that the VM will have time to die peacefully.
A complete bash script (untested):
#!/bin/bash
ssh root#<vm-client-ip> "shutdown -h now"
sleep 10
You can use the hypervisor, i.e. the qm script in case of qemu/KVM
qm shutdown 300 && qm wait 300
It shuts down the VM with ID 300, and wait for the VM to stop. See the qm manual for more options.
There are very many ways to turn off a Linux system. The preferred way is to call your window manager's shutdown sequence. If you're using gdm (which you probably are if you're using Ubuntu you want to use:
gnome-session-quit --power-off
If you're using kdm the command is:
kdmctl shutdown
Other ways of shutting down the computer (which may or may not be mostly or completely equivalent, but all require superuser rights) include:
/sbin/init 0
/sbin/halt
/sbin/shutdown -h now
/sbin/poweroff
etc, etc.
The actual command with shuts a system down is shutdown, specifically
$ shutdown -h now
shuts it down now. This needs to be run with superuser privileges on the machine you want to stop.
You can call poweroff from a script, as long as it's running with superuser privileges.
Depending on which virtualization product you are using (e.g. KVM, VirtualBox, VMWare, etc.), there should be a suitable interface you can use.
I suggest you search Google for the name of your chosen virtualisation software + "API". All of the above examples have relevant results that can be called from e.g. Python.
For VirtualBox, check out this link: https://blogs.oracle.com/nike/entry/python_api_to_the_virtualbox
That should give you a SOAP interface which should allow you remote control via e.g. cURL.
Alternatively for the remote aspect, you could setup private key authentication on the server and save your key's passphrase locally (with e.g. Seahorse), which would allow you secure ssh access without the need to enter your password each time.

Categories