Python之路【第九篇】堡垒机基础&数据库操作
复习paramiko模块
Python的paramiko模块,是基于SSH用于连接远程服务器并执行相关操作。
SSHClient
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko ''' 第一种方法 ''' ssh = paramiko.SSHClient() #创建SSH对象 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #允许连接不在know_hosts文件中的主机 ssh.connect(hostname='192.168.7.100',port=22,username='root',password='nihao123!') stdin,stdout,stderror = ssh.exec_command('ifconfig,美女,') #执行命令 print stdout.read() #获取命令结果 print stderror.read() #如果执行错误返回错误结果 ssh.close() #关闭连接
''' 第二种方法 ''' transport = paramiko.Transport(('192.168.7.100',22)) #创建一个连接对象 transport.connect(username='root',password='nihao123!')#调用transport对象中的连接方法 ssh = paramiko.SSHClient() #创建SSH对象 ssh._transport = transport #把ssh对象中的_transport 字段进行赋值为transport stdin,stdout,stderr = ssh.exec_command('ifconfig') #执行命令 print stdout.read() print stderr.read() transport.close() ''' 第二种方法和第一种方法的区别! 第一种方法 ssh = paramiko.SSHClient() 他的内部的connect其实内部封装了Transport t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) 在文件操作的时候只能用第二种方法 '''
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa') ssh = paramiko.SSHClient()#创建SSH对象 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #允许连接不在know_host文件中的的主机 ssh.connect(hostname='192.168.7.100',port=22,username='root',pkey=private_key) #连接服务器 stdin,stdout,stderr = ssh.exec_command('ifconfig') #执行命令 print stdout.read() #获取命令执行结果 ssh.close() ''' 如果是运维人员这里不需要看 1、首先创建一个公钥和私钥 ssh-keygen 2、复制id_rsa.pub至要被远程执行命令的机器,并把id_rsa.pub里的内容增加至authorized_keys文件中 如果authorized_keys文件不存在创建即可 '''
SFTPClient
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko transport = paramiko.Transport(('192.168.7.100',22)) transport.connect(username='root',password='nihao123!') #调用transport进行连接 sftp = paramiko.SFTPClient.from_transport(transport)#然后创建SFTPClient并基于transport连接,把他俩做个绑定 sftp.put('testsftpfile.zip','/tmp/sftpfile-luotianshuai.zip') #将sftpfile.zip上传到目标机器的/tmp/sftpfile-luotianshuai.zip sftp.get('/tmp/messages.log','shuaige.log') #下载目标服务器/tmp/messages.log 到本地的shuaige.log文件(程序执行目录中) transport.close()
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa') transport = paramiko.Transport(('192.168.7.100',22)) transport.connect(username='root',pkey=private_key) #调用transport进行连接 sftp = paramiko.SFTPClient.from_transport(transport)#然后创建SFTPClient并基于transport连接,把他俩做个绑定 sftp.put('testsftpfile.zip','/tmp/sftpfile-luotianshuai.zip') #将sftpfile.zip上传到目标机器的/tmp/sftpfile-luotianshuai.zip sftp.get('/tmp/messages.log','shuaige.log') #下载目标服务器/tmp/messages.log 到本地的shuaige.log文件(程序执行目录中) transport.close()
面向对象封装多个远程操作
#看上面的paramiko执行命令的时候有两种方法,传输文件的时候有一种方法!并且这里在执行命令的时候连接下然后关闭,传输文件的时候传输完后关闭,这样不是很好! #那么我们可以连接上,然后把执行命令和上传文件写成两个方法操作。
在远程执行命令的时候其实是很快的但是他们消耗的时间基本上都在建立连接上了,所以我们要写成连接上一次执行命令或上传文件全部都完事之后关闭。
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko import uuid class Haproxy(object): def __init__(self): self.hostname = '192.168.7.100' self.port = 22 self.username = 'root' self.password = 'nihao123!' def create_file(self): file_name = str(uuid.uuid4()) #这个uuid.uuid4()会生成一个文件UUID然后当作文件名 with open(file_name,'wb') as f: f.write('This is test file will send to server') return file_name def run(self): self.connect() self.upload() self.rename() self.close() def connect(self): #设置连接方法 transport = paramiko.Transport(('192.168.7.100',22)) #创建一个连接对象 transport.connect(username='root',password='nihao123!')#调用transport对象中的连接方法 self.__transport = transport #把transport赋值给__transport def close(self): #关闭连接 self.__transport.close() def upload(self): #上传文件方法 file_name = self.create_file() #创建文件 sftp = paramiko.SFTPClient.from_transport(self.__transport) #创建SFTPClient并基于transport连接,把他俩做个绑定 sftp.put(file_name,'/tmp/luotianshuai.txt') #上传文件 def rename(self): #执行命令方法 ssh = paramiko.SSHClient() #建立ssh对象 ssh._transport = self.__transport #替换ssh_transport字段为self.__transport stdin,stdout,stderr = ssh.exec_command('mv /tmp/luotianshuai /tmp/shuaige') #执行命令 print stdout.read() #读取执行命令 if __name__ == '__main__': ha = Haproxy() ha.run() ''' 上面的例子中我们就连接了一次,然后用这一次连接进行命令和上传文件的管理! 不用来回的创建和关闭SSH连接 '''
堡垒机
例子1:LINUX下打开一个终端
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko import os import sys import select import socket tran = paramiko.Transport(('192.168.7.100', 22,)) tran.start_client() ''' #使用密钥认证 default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa') key = paramiko.RSAKey.from_private_key_file(default_path) tran.auth_publickey('root', key) ''' tran.auth_password('root', 'nihao123!') #通过密码认证 chan = tran.open_session()# 打开一个通道 chan.get_pty()# 获取一个终端 chan.invoke_shell()# 激活器 ''' # 利用sys.stdin,肆意妄为执行操作 # 用户在终端输入内容,并将内容发送至远程服务器 # 远程服务器执行命令,并将结果返回 # 用户终端显示内容 ''' while True: # 监视用户输入和服务器返回数据 # sys.stdin 处理用户输入 # chan 是之前创建的通道,用于接收服务器返回信息 readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1) #坚挺chen和终端 #只要发生变化,chan或者stdin或者都变化 if chan in readable: #远端有变化后捕获到 try: x = chan.recv(1024) #ssh连接后他发送接收数据也是通过socket来做的 if len(x) == 0: print '\r\n*** EOF\r\n', break sys.stdout.write(x)#把内容输入到终端上 sys.stdout.flush() except socket.timeout: pass if sys.stdin in readable: #当终端有输入捕获到之后 inp = sys.stdin.readline() #把用户的那一行输入 chan.sendall(inp)#发送命令至远端 chan.close() tran.close()
#上面的例子中在捕获输出的时候我们输入的一行命令(字符串)回车之后,sys.stdin才捕获到,这个是默认的终端是这样的,我们就可以打开一个文件记录用户的所有命令操作
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko import os import sys import select import socket tran = paramiko.Transport(('192.168.7.100', 22,)) tran.start_client() ''' #使用密钥认证 default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa') key = paramiko.RSAKey.from_private_key_file(default_path) tran.auth_publickey('root', key) ''' tran.auth_password('root', 'nihao123!') #通过密码认证 chan = tran.open_session()# 打开一个通道 chan.get_pty()# 获取一个终端 chan.invoke_shell()# 激活器 ''' # 利用sys.stdin,肆意妄为执行操作 # 用户在终端输入内容,并将内容发送至远程服务器 # 远程服务器执行命令,并将结果返回 # 用户终端显示内容 ''' log = open('record','ab') #打开一个文件记录用户的输入 while True: # 监视用户输入和服务器返回数据 # sys.stdin 处理用户输入 # chan 是之前创建的通道,用于接收服务器返回信息 readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1) #坚挺chen和终端 #只要发生变化,chan或者stdin或者都变化 if chan in readable: #远端有变化后捕获到 try: x = chan.recv(1024) #ssh连接后他发送接收数据也是通过socket来做的 if len(x) == 0: log.close() #关闭文件 print '\r\n************************ EOF ************************\r\n', break sys.stdout.write(x)#把内容输入到终端上 sys.stdout.flush() except socket.timeout: pass if sys.stdin in readable: #当终端有输入捕获到之后 inp = sys.stdin.readline() #把用户的那一行输入 log.write(inp) #记录命令 chan.sendall(inp)#发送命令至远端 chan.close() tran.close()
#还有个例子是我们在终端输入命令的时候,经常忘记命令全部的字符。
#默认换行,对于特殊字符特殊处理,比如Ctrl+c
#改变终端默认由行+回车-->stdin,改为一个字符--> stdin
首先我们要做的就是修改终端模式:把原来的默认换行为“回车”,特殊字符特殊处理,改为输入一个字符就捕获并且
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko import os import sys import select import socket import termios import tty tran = paramiko.Transport(('192.168.7.100', 22,)) tran.start_client() ''' #使用密钥认证 default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa') key = paramiko.RSAKey.from_private_key_file(default_path) tran.auth_publickey('root', key) ''' tran.auth_password('root', 'nihao123!') #通过密码认证 chan = tran.open_session()# 打开一个通道 chan.get_pty()# 获取一个终端 chan.invoke_shell()# 激活器 ''' # 利用sys.stdin,肆意妄为执行操作 # 用户在终端输入内容,并将内容发送至远程服务器 # 远程服务器执行命令,并将结果返回 # 用户终端显示内容 ''' # 获取原tty属性 oldtty = termios.tcgetattr(sys.stdin) try: # 为tty设置新属性 # 默认当前tty设备属性: # 输入一行回车,执行 # CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号 # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器 tty.setraw(sys.stdin.fileno()) #把远端更换为LINUX原始模式 chan.settimeout(0.0) while True: # 监视 用户输入 和 远程服务器返回数据(socket) # 阻塞,直到句柄可读 r, w, e = select.select([chan, sys.stdin], [], [], 1) if chan in r: try: x = chan.recv(1024) if len(x) == 0: print '\r\n*** EOF\r\n', break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break chan.send(x) finally: # 重新设置终端属性 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) chan.close() tran.close()
记录日志,并且不记录tab输入
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko import os import sys import select import socket import termios import tty tran = paramiko.Transport(('192.168.7.100', 22,)) tran.start_client() ''' #使用密钥认证 default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa') key = paramiko.RSAKey.from_private_key_file(default_path) tran.auth_publickey('root', key) ''' tran.auth_password('root', 'nihao123!') #通过密码认证 chan = tran.open_session()# 打开一个通道 chan.get_pty()# 获取一个终端 chan.invoke_shell()# 激活器 ''' # 利用sys.stdin,肆意妄为执行操作 # 用户在终端输入内容,并将内容发送至远程服务器 # 远程服务器执行命令,并将结果返回 # 用户终端显示内容 ''' # 获取原tty属性 oldtty = termios.tcgetattr(sys.stdin) #打开文件 try: # 为tty设置新属性 # 默认当前tty设备属性: # 输入一行回车,执行 # CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号 # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器 tty.setraw(sys.stdin.fileno()) #把远端更换为LINUX原始模式 chan.settimeout(0.0) user_log = open('terminalnew_log','ab') while True: # 监视 用户输入 和 远程服务器返回数据(socket) # 阻塞,直到句柄可读 r, w, e = select.select([chan, sys.stdin], [], [], 1) if chan in r: try: x = chan.recv(1024) if len(x) == 0: user_log.close() print '\r\n*** EOF\r\n', break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break if x == '\t': #判断用户的是否为tab如果为tab将不记录 pass else: user_log.write(x)#如果用户输入的命令保存至日志 chan.send(x) finally: # 重新设置终端属性 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) chan.close() tran.close()
例2:Windows下打开终端
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'luo_t' import paramiko import sys import threading tran = paramiko.Transport(('192.168.0.111', 22,)) tran.start_client() ''' #使用密钥认证 default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa') key = paramiko.RSAKey.from_private_key_file(default_path) tran.auth_publickey('root', key) ''' tran.auth_password('root', 'nihao123!') #通过密码认证 chan = tran.open_session()# 打开一个通道 chan.get_pty()# 获取一个终端 chan.invoke_shell()# 激活器 ''' # 利用sys.stdin,肆意妄为执行操作 # 用户在终端输入内容,并将内容发送至远程服务器 # 远程服务器执行命令,并将结果返回 # 用户终端显示内容 ''' sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n") def writeall(sock): while True: data = sock.recv(256) ''' SSH发送数据的也是通过socket进行发送数据的,那么我们就可以使用socket来获取远程机器发送回来的数据。 while循环一直接收数据,sock.recv(256)是阻塞的只有数据过来的时候才会继续走。 ''' if not data: sys.stdout.write('\r\n*** EOF ***\r\n\r\n') sys.stdout.flush() break sys.stdout.write(data) sys.stdout.flush() writer = threading.Thread(target=writeall, args=(chan,)) #创建了一个线程,去执行writeall方法,参数为chan(建立的SSH连接) writer.start() try: while True: #主线程循环 d = sys.stdin.read(1) #一直监听用户的输入,输入一个发送一个 if not d: break chan.send(d) except EOFError: # user hit ^Z or F6 pass chan.close() tran.close()
数据库操作
Python 操作 Mysql 模块的安装
linux: yum install MySQL-python window: http://files.cnblogs.com/files/wupeiqi/py-mysql-win.zip
SQL基本使用
SHOW DATABASES; #查看当前数据库的的库名 USE jumpserver; #使用jumpserver库 SHOW TABLES; #查看当前库名中的表 CREATE DATABASE shuaige; #创建一个数据库名字为shuaige FLUSH PRIVILEGES; #刷新系统权限表
create database jumpserver character set = utf8; use jumpserver create table host_group ( group_id int auto_increment primary key , name char(20) not null, description text ); create table user_info ( user_id int auto_increment primary key, user_name char(20) not null, user_group_id int not null, foreign key(user_group_id) references host_group(group_id) ); create table host_info ( host_id int auto_increment primary key, host_name char(50) not null, host_type char(50) not null, address char(15) not null, cpu_count smallint, cpu_type char(20), disk_count smallint, size_perdisk int, host_description text ); create table host_group_relation ( id int, host_id int not null, group_id int not null, foreign key(host_id) references host_info(host_id), foreign key(group_id) references host_group(group_id), primary key(host_id,group_id) ); insert into host_group values (1,'admin','管理员,可以操作所有机器,执行任何操作'), (2,'developer','程序开发人员,只能操作应用服务器'), (3,'dba','数据库管理员,只能操作数据库服务器'); insert into user_info values (1,'luotianshuai',1),(2,'shuaige',2),(3,'timdba',3); insert into host_info (host_id,host_name,host_type,address) values (1,'host1','web','192.168.137.3'), (2,'host2','application','192.168.137.2'), (3,'host3','db','192.168.137.4'); insert into host_group_relation values (1,1,1), (2,2,1), (3,3,1), (4,2,2), (5,3,3);
数据操作
insert into students(name,sex,age,tel) values('alex','man',18,'151515151') delete from students where id =2; update students set name = 'sb' where id =1; select * from students 主键 外键 左右连接
Python MySQL API
插入数据:
import MySQLdb conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb') cur = conn.cursor() reCount = cur.execute('insert into UserInfo(Name,Address) values(%s,%s)',('tim','china')) # reCount = cur.execute('insert into UserInfo(Name,Address) values(%(id)s, %(name)s)',{'id':12345,'name':'shuaige'}) conn.commit() cur.close() conn.close()
批量插入:
import MySQLdb conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb') cur = conn.cursor() li =[ ('name1','address1'), ('name2','address2'), ] reCount = cur.executemany('insert into UserInfo(Name,Address) values(%s,%s)',li) conn.commit() cur.close() conn.close() print reCount
删除数据:
import MySQLdb conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb') cur = conn.cursor() reCount = cur.execute('delete from UserInfo') conn.commit() cur.close() conn.close() print reCount
修改数据:
import MySQLdb conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb') cur = conn.cursor() reCount = cur.execute('update UserInfo set Name = %s',('alin',)) conn.commit() cur.close() conn.close() print reCount
查数据:
# ############################## fetchone/fetchmany(num) ############################## import MySQLdb conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb') cur = conn.cursor() reCount = cur.execute('select * from UserInfo') print cur.fetchone() print cur.fetchone() cur.scroll(-1,mode='relative') print cur.fetchone() print cur.fetchone() cur.scroll(0,mode='absolute') print cur.fetchone() print cur.fetchone() cur.close() conn.close() print reCount # ############################## fetchall ############################## import MySQLdb conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='mydb') #cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor) cur = conn.cursor() reCount = cur.execute('select Name,Address from UserInfo') nRet = cur.fetchall() cur.close() conn.close() print reCount print nRet for i in nRet: print i[0],i[1]
更多请参考:http://www.cnblogs.com/wupeiqi/articles/5095821.html
Mysql操作更多:http://120662.blog.51cto.com/