Saturday 3 September 2016

Getting started with Parameko

First a short disclaimer. I a system administrator write this article with very little python programming experience taking the risk of sounding like an amateur to a seasoned python programming pro. But I felt this is something interesting & felt the need to share.

Parameko is a python module that can be used to automate the work we do with ssh to some extent.
It's available in the EPEL repository & can be installed by running the command 'yum install python-parameko'.

In my centOS 7 system the rpm installed was python2-paramiko-1.16.1-1.el7.noarch.rpm.

[root@devbox epel]# rpm -qi python2-paramiko
Name        : python2-paramiko
Version     : 1.16.1
Release     : 1.el7
Architecture: noarch
Install Date: Fri 02 Sep 2016 05:47:37 AM PDT
Group       : Development/Libraries
Size        : 1262230
License     : LGPLv2+
Signature   : RSA/SHA256, Mon 16 May 2016 08:38:58 PM PDT, Key ID 6a2faea2352c64e5
Source RPM  : python-paramiko-1.16.1-1.el7.src.rpm
Build Date  : Mon 16 May 2016 09:02:33 AM PDT
Build Host  : buildvm-07.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : https://github.com/paramiko/paramiko/
Summary     : SSH2 protocol library for python
Description :

Paramiko (a combination of the esperanto words for "paranoid" and "friend") is
a module for python 2.3 or greater that implements the SSH2 protocol for secure
(encrypted and authenticated) connections to remote machines. Unlike SSL (aka
TLS), the SSH2 protocol does not require heirarchical certificates signed by a
powerful central authority. You may know SSH2 as the protocol that replaced
telnet and rsh for secure access to remote shells, but the protocol also
includes the ability to open arbitrary channels to remote services across an
encrypted tunnel. (This is how sftp works, for example.)
Python 2 version.


Obviously we'll start things with the 'Hello World' example. So here it is:

#!/usr/bin/python

import paramiko
import sys
import os

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('127.0.0.1', username='james', password='123')

stdin, stdout, stderr = ssh.exec_command('echo "hello world"' )

a = stdout.read().strip()

print a

Code breakdown:

The primary class of the Paramiko API is ''paramiko.SSHClient''. It provides the basic interface for instantiating ssh connections. This creates a new SSHClient object, and then calls ''connect()'' to connect us to the local SSH server.
Whenever we make an ssh connection to a remote machine, that host's key is stored automatically in a file in your home directory called ''.ssh/known_hosts''.
Passing paramiko.AutoAddPolicy() to the set_missing_host_key_policy client object will auto accept unknown host keys.
Within ssh.connect() object we specify the host/IP address we need to connect to & the credentials to use.
ssh.exec_command() object contains the command we need to execute.


In the next example, we run multiple commands on host 192.168.44.135:

[root@devbox ~]# cat test.py
#!/usr/bin/python

import paramiko
import sys
import os

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.44.135', username='james', password='123')

stdin, stdout, stderr = ssh.exec_command('uname -a ; uptime')

a = stdout.read().strip()

print a


This outputs to:

[root@devbox ~]# ./test.py
Linux rheldb 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
 06:12:04 up 2 min,  1 user,  load average: 0.90, 0.74, 0.30


In the final example, we run commands across multiple hosts:

[root@devbox ~]# cat mul.py
#!/usr/bin/python
import sys, os, string, threading
import paramiko

cmd = "uname -a; who -r"

outlock = threading.Lock()

def workon(host):

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(host, username='james', password='123')
    stdin, stdout, stderr = ssh.exec_command(cmd)
    stdin.flush()

    with outlock:
        print stdout.readlines()

def main():
    hosts = ['192.168.44.137', '192.168.44.135' ]
    threads = []
    for h in hosts:
        t = threading.Thread(target=workon, args=(h,))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()

main()

The above code outputs to:

[root@devbox ~]# ./mul.py
[u'Linux devbox 3.10.0-123.el7.x86_64 #1 SMP Mon Jun 30 12:09:22 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux\n', u'         run-level 5  2016-09-02 12:24\n']
[u'Linux rheldb 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux\n', u'         run-level 3  2016-09-03 11:40\n']


The examples in this article are intended to be a very basic quick start to using parameko to help automate some of the repetitive tasks involving logging in to remote systems. 
I will definitely update this article as my python & parameko understanding matures over time.

No comments:

Post a Comment

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...