类Fabric主机管理程序开发

一,作业要求

1, 运行程序列出主机组或者主机列表(已完成)

2,选择指定主机或主机组(已完成)

3,选择主机或主机组传送文件(上传/下载)(已完成)

4,充分使用多线程或多进程(已完成)

5,不同主机的用户名,密码,端口可以不同(已完成)

6,可向主机或主机组批量发布命令(已完成)

7,可一次性执行多条操作命令(已完成)

二,程序文件清单

三,程序流程简图

四,程序测试样图

五,程序核心源码

  1. #!usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. # auther:Mr.chen
  4. # 描述:只能运行在MacOS或linux系统下
  5.  
  6. import os,sys,pickle,time
  7. import paramiko,threading
  8.  
  9. sys.path.append('..')
  10. PATH = os.path.dirname(os.path.abspath(__file__))
  11. PUT_PATH = PATH.replace('core','Folder/')
  12. GET_PATH = PATH.replace('core','download/')
  13. CONF_PATH = PATH.replace('core','conf/')
  14. semaphore = threading.BoundedSemaphore(1) # 进程锁
  15.  
  16. def new_Host():
  17. while True:
  18. hostname = raw_input("请输入服务器的主机名(输入n=返回上级):")
  19. if os.path.exists(CONF_PATH+hostname+'_conf'):
  20. print ("主机名已存在,请重新输入!")
  21. continue
  22. if hostname =='n':
  23. return
  24. port = raw_input("请输入服务器的ssh端口号(输入n=返回上级):")
  25. if port == 'n':
  26. return
  27. username = raw_input("请输入登陆的用户名(输入n=返回上级):")
  28. if username == 'n':
  29. return
  30. password = raw_input("请输入用户的密码(输入n=返回上级):")
  31. if password == 'n':
  32. return
  33. dic = {
  34. 'hostname':hostname, # 主机名
  35. 'port':port, # 端口
  36. 'username':username, # 用户名
  37. 'password':password, # 密码
  38. 'status':0 # 状态(0:未激活 1:已激活 2:激活失败)
  39. }
  40. if os.path.isdir(GET_PATH + hostname) == False:
  41. command = 'mkdir ' + GET_PATH + hostname
  42. os.system(command)
  43. re = hostmessage_Write(dic)
  44. if re == True:
  45. return
  46. else:
  47. print ("主机信息存储失败,请检查原因!")
  48.  
  49. def delete_Host():
  50. List = Traverse_folder()
  51. while True:
  52. dic = {}
  53. num = 0
  54. print ("已存在的主机列表如下:")
  55. for i in List:
  56. print ("{0},主机名:{1}".format(str(num+1),i))
  57. dic[str(num+1)] = i
  58. num += 1
  59. choose = raw_input("请输入你想删除的主机索引(输入n=返回上级):")
  60. if choose == 'n':
  61. return
  62. elif choose in dic:
  63. hostname = dic[choose]
  64. command = 'rm -f '+CONF_PATH+hostname+'_conf'
  65. os.system(command)
  66. print ("删除成功!")
  67. break
  68. else:
  69. print ("您的输入有误!")
  70.  
  71. def auto_activeHost():
  72. text = """
  73. 警告!程序准备开启多线程模式激活主机,请确保:
  74. 1,远程服务器处于开启状态
  75. 2,DNS或本地hosts映射能够解析远程服务器主机名
  76. """
  77. while True:
  78. print (text)
  79. choose = raw_input("是否确定开始激活远程主机(y/n)?:")
  80. if choose == 'n':
  81. return
  82. elif choose == 'y':
  83. break
  84. else:
  85. print ("你的输入有误!")
  86. print ("程序开始自动激活远程主机,请稍后...")
  87. List = Traverse_folder()
  88. if len(List) == 0:
  89. print ("请先创建主机!")
  90. return
  91. for i in List:
  92. dic = hostmessage_Read(i)
  93. t = threading.Thread(target=auto_Active,args=(dic,)) # 创建多线程对象
  94. t.setDaemon(True) # 将对象设置为守护线程
  95. t.start() # 线程开启
  96. while threading.activeCount() != 1: # 当前活跃的线程数
  97. pass
  98. else:
  99. print ("所有主机激活完毕!")
  100. time.sleep(2)
  101.  
  102. def auto_Active(dic):
  103. ssh = paramiko.SSHClient() # 创建ssh对象
  104. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #允许连接不在know_hosts文件中的主机
  105. try:
  106. ssh.connect(hostname=dic['hostname'],port=int(dic['port']),username=dic['username'],password=dic['password'],timeout=10)
  107. except Exception,e:
  108. print ("主机名:{0}的主机激活失败!失败原因:{1}".format(dic['hostname'],e))
  109. dic['status'] = 2
  110. hostmessage_Write(dic)
  111. else:
  112. print ("主机名:{0}的主机激活成功!".format(dic['hostname']))
  113. dic['status'] = 1
  114. hostmessage_Write(dic)
  115. finally:
  116. ssh.close()
  117.  
  118. def remote_Host():
  119. List = Traverse_folder(key='status',value=1)
  120. if len(List) == 0:
  121. print ("请先激活主机!")
  122. return
  123. while True:
  124. dic = {}
  125. print ("已激活主机如下:")
  126. num = 0
  127. for i in List:
  128. print ("{0},主机名:{1}".format(str(num+1),i))
  129. dic[str(num+1)] = i
  130. num += 1
  131. choose = raw_input("请输入你想操控的主机的索引(可多选,n=返回上级):")
  132. if choose == 'n':
  133. return
  134. choose = list(set(choose)) #去重复
  135. if set(choose) & set(dic.keys()) == set(choose):
  136. LIST = []
  137. for i in choose:
  138. LIST.append(dic[i])
  139. remote_Host_control(LIST)
  140. else:
  141. print ("您的输入有误!")
  142.  
  143. def remote_Host_control(List):
  144. help = """
  145. help帮助提示:
  146. 1.程序的Folder目录是本地文件目录
  147. 2,输入put向远程主机上传文件
  148. 3,输入get向远程主机下载文件
  149. 4,输入其他直接向远程主机发布命令
  150. """
  151. while True:
  152. print ("正在操控{0}台主机,如下:".format(len(List)))
  153. for i in List:
  154. print ("主机名:{0}".format(i))
  155. command = raw_input("请输入你想执行的命令(输入n=返回上级,输入help获取帮助):>>")
  156. if command == 'n':
  157. return
  158. elif command == 'help':
  159. print help
  160. elif command == 'get':
  161. print ("程序准备下载文件...")
  162. remote_path = raw_input("请输入想要下载的远程服务器文件绝对路径(例如:/etc/hosts):")
  163. LIST = remote_path.split('/')
  164. filename = LIST[len(LIST)-1]
  165. for i in List:
  166. local_path = GET_PATH + i + '/'+filename
  167. t = threading.Thread(target=get_Method,args=(i,[remote_path,local_path]))
  168. t.setDaemon(True)
  169. t.start()
  170. while threading.activeCount() != 1:
  171. pass
  172. else:
  173. print ("命令执行完毕!")
  174. elif command == 'put':
  175. print ("程序准备上传文件...")
  176. while True:
  177. filename = raw_input("请输入想上传的文件的文件名:")
  178. if os.path.exists(PUT_PATH+filename) == False:
  179. print ("文件没有找到,请重新输入!")
  180. continue
  181. local_path= PUT_PATH+filename
  182. remote_path = raw_input("你想将文件保存到远程服务器的哪里?(例如:/etc/):")
  183. remote_path = remote_path + '/' + filename
  184. for i in List:
  185. t = threading.Thread(target=put_Method, args=(i, [local_path,remote_path]))
  186. t.setDaemon(True)
  187. t.start()
  188. while threading.activeCount() != 1:
  189. pass
  190. else:
  191. print ("命令执行完毕!")
  192. break
  193. else:
  194. for i in List:
  195. t = threading.Thread(target=execute_Command,args=(i,command))
  196. t.setDaemon(True)
  197. t.start()
  198. while threading.activeCount() != 1:
  199. pass
  200. else:
  201. print ("命令执行完毕!")
  202.  
  203. def put_Method(hostname,Path):
  204. dic = hostmessage_Read(hostname)
  205. transport = paramiko.Transport((hostname, int(dic['port'])))
  206. try:
  207. transport.connect(username=dic['username'], password=dic['password'])
  208. sftp = paramiko.SFTPClient.from_transport(transport)
  209. sftp.put(Path[0], Path[1])
  210. except Exception, e:
  211. print ("主机名:{0},上传失败!错误原因:{1}".format(hostname, e))
  212. else:
  213. pass
  214. finally:
  215. transport.close()
  216.  
  217. def get_Method(hostname,Path):
  218. dic = hostmessage_Read(hostname)
  219. transport = paramiko.Transport((hostname,int(dic['port'])))
  220. try:
  221. transport.connect(username=dic['username'],password=dic['password'])
  222. sftp = paramiko.SFTPClient.from_transport(transport)
  223. sftp.get(Path[0],Path[1])
  224. except Exception,e:
  225. print ("主机名:{0},下载失败!错误原因:{1}".format(hostname,e))
  226. else:
  227. pass
  228. finally:
  229. transport.close()
  230.  
  231. def execute_Command(hostname,command):
  232. dic = hostmessage_Read(hostname)
  233. ssh = paramiko.SSHClient()
  234. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  235. try:
  236. ssh.connect(hostname=hostname,port=int(dic['port']),username=dic['username'],password=dic['password'])
  237. command_list = command.strip().split(';')
  238. except Exception,e:
  239. semaphore.acquire() # 线程锁开启
  240. print ("主机:{0}连接出现异常:{1}".format(hostname,e))
  241. semaphore.release() # 线程锁释放
  242. return
  243. for com in command_list:
  244. stdin, stdout, stderr = ssh.exec_command(com)
  245. error = stderr.read()
  246. output = stdout.read()
  247. semaphore.acquire() # 线程锁开启
  248. if len(error) != 0:
  249. print ("主机:{0} 执行{1}命令时出错:{2}".format(hostname,com, error))
  250. if len(output) != 0:
  251. print ("主机:{0},执行{1}命令的结果如下:".format(hostname,com))
  252. print (output)
  253. semaphore.release() # 线程锁释放
  254.  
  255. def Traverse_folder(key = None,value = None):
  256. '''
  257. 根据条件遍历某文件夹里的全部文件内容,
  258. 找出符合条件的文件返回包含主机名的列表
  259. 如果无条件,则返回包含所有主机名的列表
  260. :return:LIST
  261. '''
  262. LIST = []
  263. List = os.listdir(CONF_PATH)
  264. for i in List:
  265. if i == '__init__.py' or i == '__init__.pyc':
  266. continue
  267. else:
  268. with open(CONF_PATH+i,'r') as f:
  269. dic = pickle.load(f)
  270. if key != None:
  271. if dic[key] == value:
  272. LIST.append(dic['hostname'])
  273. else:
  274. LIST.append(dic['hostname'])
  275. return LIST
  276.  
  277. def hostmessage_Write(dic):
  278. with open(CONF_PATH+dic['hostname']+'_conf','w') as f:
  279. pickle.dump(dic,f)
  280. return True
  281.  
  282. def hostmessage_Read(hostname):
  283. if os.path.exists(CONF_PATH+hostname+'_conf'):
  284. with open(CONF_PATH+hostname+'_conf','r') as f:
  285. dic = pickle.load(f)
  286. return dic
  287.  
  288. def Main():
  289. text = """
  290. 欢迎来到Fabric主机管理界面
  291. 1,创建主机
  292. 2,删除主机
  293. 3,自动激活所有主机
  294. 4,开始远程操控
  295. 5,退出程序
  296. """
  297. while True:
  298. print text
  299. choose = raw_input("请输入你的选择:")
  300. dic = {'1':new_Host,'2':delete_Host,'3':auto_activeHost,'4':remote_Host,'5':Exit}
  301. if choose in dic:
  302. dic[choose]()
  303. else:
  304. print ("你的输入有误!")
  305.  
  306. def Exit():
  307. print ("程序退出!")
  308. exit()
  309.  
  310. if __name__ == "__main__":
  311. Main()

python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)的更多相关文章

  1. python作业类Fabric主机管理程序开发(第九周)

    作业需求: 1. 运行程序列出主机组或者主机列表 2. 选择指定主机或主机组 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) 4. 充分使用多线程或多进程 5. 不同主机的用户名密码 ...

  2. python 学习分享-实战篇类 Fabric 主机管理程序开发

    # 类 Fabric 主机管理程序开发: # 1. 运行程序列出主机组或者主机列表 # 2. 选择指定主机或主机组 # 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) # 4. 充分 ...

  3. 类 Fabric 主机管理程序开发

    类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载4. 充分使用多线程或多进程5. 不同主 ...

  4. Python09作业思路及源码:高级FTP服务器开发(仅供参考)

    高级FTP服务器开发 一,作业要求 高级FTP服务器开发 用户加密认证(完成) 多用户同时登陆(完成) 每个用户有不同家目录且只能访问自己的家目录(完成) 对用户进行磁盘配额,不同用户配额可不同(完成 ...

  5. 从零开始学Python04作业源码:模拟ATM电子银行(仅供参考)

    bin目录:程序启动入口 ATM_start.py: #!/usr/bin/python # -*- coding: utf-8 -*- # 模拟ATM电子银行+登录账户权限控制+管理员管理模块 # ...

  6. python第五十二天---第九周作业 类 Fabric 主机管理程序

    类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)4. 充分使用多线程或多进程5. 不同 ...

  7. MYSQL 排行类的相关SQL写法,仅供参考

    SELECT * FROM () )) b

  8. paramiko类Fabric主机管理

    环境:Linux python3.5 要求:类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/ ...

  9. JMeter5.4.1源码IDEA构建&二次开发(实战)

    JMeter5.4.1源码IDEA构建&二次开发(实战) 目录 JMeter5.4.1源码IDEA构建&二次开发(实战) 1.下载源码 2.导入IDEA 2.1 先设置Gradle目录 ...

随机推荐

  1. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  2. [APUE]UNIX进程的环境(下)

    一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函 ...

  3. 如何一步一步用DDD设计一个电商网站(三)—— 初涉核心域

    一.前言 结合我们本次系列的第一篇博文中提到的上下文映射图(传送门:如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念),得知我们这个电商网站的核心域就是销售子域.因为电子商务是以信息网络 ...

  4. JS核心系列:浅谈原型对象和原型链

    在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象(Object)和函数对象(Function). 一般而言,通过new Function产生的对象是函数对象,其他对 ...

  5. TODO:搭建Laravel VueJS SemanticUI

    TODO:搭建Laravel VueJS SemanticUI Laravel是一套简洁.优雅的PHP开发框架(PHP Web Framework).可以让你从面条一样杂乱的代码中解脱出来:它可以帮你 ...

  6. solr_架构案例【京东站内搜索】(附程序源代码)

    注意事项:首先要保证部署solr服务的Tomcat容器和检索solr服务中数据的Tomcat容器,它们的端口号不能发生冲突,否则web程序是不可能运行起来的. 一:solr服务的端口号.我这里的sol ...

  7. ASP.NET Core中如影随形的”依赖注入”[上]: 从两个不同的ServiceProvider说起

    我们一致在说 ASP.NET Core广泛地使用到了依赖注入,通过前面两个系列的介绍,相信读者朋友已经体会到了这一点.由于前面两章已经涵盖了依赖注入在管道构建过程中以及管道在处理请求过程的应用,但是内 ...

  8. C#多线程之线程同步篇1

    在多线程(线程同步)中,我们将学习多线程中操作共享资源的技术,学习到的知识点如下所示: 执行基本的原子操作 使用Mutex构造 使用SemaphoreSlim构造 使用AutoResetEvent构造 ...

  9. .NET面试题集锦①(Part一)

    一.前言部分 文中的问题及答案多收集整理自网络,不保证100%准确,还望斟酌采纳. 1.面向对象的思想主要包括什么? 答:任何事物都可以理解为对象,其主要特征: 继承.封装.多态.特点:代码好维护,安 ...

  10. Unable to create the selected property page. An error occurred while automatically activating bundle net.sourceforge.pmd

    解决方案: 在命令行到eclipse目录下使用 eclipse.exe -clean