前言
本次主要分享是如何基于Python模拟实现ansible的主要功能
ansible功能分析与代码实现
连接远程主机
ansible连接远程主机是通过SSH实现的,因此我们可以通过Python的SSH模块来实现连接远程主机。
Python中SSH模块主要是三方的paramiko模块,这个模块也是ansible内部实现SSH所用的模块。
由于paramiko属于第三方库,所以需要使用如下命令先行安装
pip install paramiko
下面是使用paramiko进行SSH连接和SFTP连接的相关代码
获取一个SSH连接
def get_ssh_conn(hostname, port, username, password):
try:
# 实例化SSHClient
ssh_client = paramiko.SSHClient()
# 当远程服务器没有本地主机的密钥时自动添加到本地,这样不用在建立连接的时候输入yes或no进行确认
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接SSH服务器,这里以账号密码的方式进行认证,也可以用key认证
ssh_client.connect(
hostname=hostname, port=port, username=username, password=password, timeout=5
)
return ssh_client
except Exception as e:
logger.info(e)
return None
获取一个SFTP连接
def get_sftp_conn(hostname, port, username, password):
try:
# paramiko sftp功能需要先初始化一个Transport,有点类似打开一个文件传输通道
t = paramiko.Transport((hostname, port))
t.banner_timeout = 10
t.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(t)
return sftp
except Exception as e:
return None
执行命令
paramiko既然能连接主机,当然也能执行命令
基于SSH连接执行命令
def exec_ssh_command(ssh_client, cmd):
# 这个类似Popen执行命令,返回三个byte类型值,需要解码
stdin, stdout, stderr = ssh_client.exec_command(cmd, timeout=30)
return stderr.read().decode(), stdout.read().decode()
上传下载文件
当我们初始化好后SFTP连接后,就可以对远程服务器进行文件上传下载了
基于SFTP连接进行文件上传下载
# put上传文件
def upload_file(sftp, src, dest):
sftp.put(src, dest)
# get下载文件
def download_file(sftp, src, dest):
sftp.get(src, dest)
ansible的ping功能
其实我们可以通过paramiko是否能ssh连接远程主机作为ping功能实现的原理,当ssh能连接成功时,会返回一个sshclient,否则返回None,参考获取一个SSH连接的代码
相关系列文章同步发布于个人博客 Jackless
模拟 saltstack/ansible 系列二(实现 ansible 主要功能)