完整的代碼已經在github開源:github.com/CTC-maxiao/…linux
Task執行器是根據輸入的執行字典,來完成執行相應的Task的程序,這也是咱們程序的核心部分。咱們設計TaskExecutor類來作Task執行器:git
class TaskExecutor:
def __init__(self): #類的初始化函數
pass
def run_task(self,task_dict): #根據指定執行task的host和action類型來分配任務
if task_dict["task_host"] == "localhost":
ssh=""
else:
ssh = self.get_ssh_session(task_dict)
if task_dict["action_type"] == "shell": #shell類型任務是指運行linux命令及程序相關的任務
self.run_shell_task(ssh,task_dict)
elif task_dict["action_type"] == "slack": #slack類型任務是用來和聊天工具slack進行交互的任務
self.run_slack_task(ssh,task_dict)
else: #能夠靈活的擴展任務類型,只須要將寫好的任務處理函數加進來
return False
def get_ssh_session(self,task_dict): #獲取ssh的session,用來執行須要在遠程主機執行的任務
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=task_dict["task_host"],
port=task_dict["ssh_port"],
username=task_dict["ssh_user"],
password=task_dict["ssh_pwd"])
return ssh
def run_shell_task(self,ssh,task_dict):
command = task_dict["action"]
if task_dict["become"] == "yes": #這裏用管道實現用戶切換,算是一種投機取巧的方式
command = "echo "+task_dict["become_pwd"]+" |sudo -S su - "+task_dict["become_user"]+" -c '"+command+"'"
if ssh == "":
stdin, stdout, stderr = os.popen(command)
else:
stdin, stdout, stderr = ssh.exec_command(command)
ssh.close()
return stdin, stdout, stderr
def run_slack_task(self,ssh,action): #和slack交互的任務處理函數,還沒寫好,後續會完善
pass
複製代碼
程序使用paramiko來ssh到遠程機器,經過管道來實現切換用戶執行任務,和ansible實現方式不一樣。在ansible下切換用戶必須提供要切換用戶的密碼,好比要切換到root用戶就須要提供root的密碼,這是很不實用的。在現實環境中我想大部分用戶都沒有root用戶的密碼。經過管道來實現用戶切換隻須要提供當前用戶的密碼,可以很好的繞開linux服務器的安全限制。github
在使用這種切換方式以前我嘗試了使用pexpect,但切換後沒法返回新的ssh session。若是誰有更好的作法,請務必告訴我。謝謝!shell