Python 自动化办公系列(04)批量配置 SSH 单向互信
# -*- coding: utf-8 -*-
__author__ = "HaoJun"
__doc__ = "批量配置 SSH 单向互信,master 对 多个 client;目的:为 ansible 工具打通 SSH 通路!"
'''
安装了 ansible 工具的主服务器 169 上部署了 ansible 组件,作用是为学员正在使用的节点批量安装多个开发组件,
以顺利安装 8a 8s 8c 数据库。前提:需要 169 和学员节点做 SSH 互信,才能执行 ansible 批处理。每期开班前,
我都要将 50 个节点重做操作系统,原来的互信将失效,程序没有开发出来之前,我使用《自动化办公 03》程序,
安装一个组件需要执行 50 次程序。本程序开发完毕之后,执行一次,然后 169 上的 ansible 批处理一次搞定!
'''
# [2024.11.29] 调试通过。全程使用 root 账户
from fabric2 import Connection
import pandas as pd
from enum import Enum
MasterID = 169 # 安装了 ansible 工具的主服务器 ID
excelFile = r"D:\6_生态发展部\云服务器管理\阿里云\阿里云云服务器_Python.xlsx"
excelData = pd.DataFrame(pd.read_excel(excelFile,keep_default_na=False)) # Need install module named 'xlrd'
class KEYS(Enum):
COLUMN_ID = "ID" # 示例唯一标识
COLUMN_NAME = "instName" # 示例名称
COLUMN_PIP = "Public IP" # 公网 IP
COLUMN_IIP = "内网 IP" # 内网 IP
COLUMN_PORT = "SSH Port" # SSH 协议外部映射端口
COLUMN_PWD = "root password" # root 账户密码
def chkExcelHead():
excelColumns = excelData.columns.to_list() # 从 Excel 文件读出来的表头,转换成列表
bExit = True
for oKey in KEYS:
if oKey.value not in excelColumns:
print('在"{0}"中找不到表头"{1}"!'.format(excelFile,oKey.value))
bExit = False
break
return bExit
def getMasterConn(ip, port, user, password):
conSSH = None
try:
conSSH = Connection(ip, user, port=port, connect_kwargs={'password': password})
except BaseException as e:
print("The host of ip {} : {}".format(ip, e))
finally:
pass
#if conSSH is not None:
# conSSH.close()
return conSSH
def main():
if not chkExcelHead():
exit(1)
masConn = None
masterHostName = 'peixun{}'.format(MasterID)
dfMaster = excelData[excelData['instName'] == masterHostName] # 找到 master 服务器 DataFrame
ip = dfMaster['Public IP'].values[0]
port = dfMaster['SSH Port'].values[0]
password = dfMaster['root password'].values[0]
masConn = getMasterConn(ip, int(port), "root", password)
if masConn is None:exit(1)
# 主服务器生成秘钥
result = masConn.run("if [ ! -f ~/.ssh/authorized_keys ]; then ssh-keygen; fi")
dfValid = excelData[excelData['ID']!=''] # 找到 ID 非空的、有效的 Client 服务器
for i in range(len(dfValid)):
id = dfValid[KEYS.COLUMN_ID.value].values[i]
if id == '': continue
iip = dfValid[KEYS.COLUMN_IIP.value].values[i] # 得到 client 服务器内网 IP
iport = 22 #内网 SSH 缺省端口
password = dfValid[KEYS.COLUMN_PWD.value].values[i]
hostname = dfValid[KEYS.COLUMN_NAME.value].values[i]
cmdStr = "sshpass -p '{passwd}' ssh-copy-id -f -i ~/.ssh/id_rsa.pub -p {port} root@{ip}".\
format(passwd=password,ip=iip,port=iport)
try:
result = masConn.run(cmdStr) # 将秘钥拷贝到指定服务器。命令中的单引号是必须的,解决密码中存在特殊字符问题
except BaseException as e:
#print(result.stdout)
print(e)
if masConn is not None:
masConn.close()
if __name__ == "__main__":
main()
''' 秘钥拷贝到指定服务器后,ansible ping 模组校验通过,即实现了 master 向 client 服务器的单向 SSH 互信
[root@peixun169 .ssh]# ansible servers -m ping
172.27.237.163 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
172.27.237.168 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
'''
评论
热门帖子
- 12025-12-01浏览数:182759
- 22023-05-09浏览数:25044
- 42023-09-25浏览数:18519
- 52020-05-11浏览数:17526