tornado+ansible+twisted+mongodb營運自動化系統開發(二)
源碼:
#!/usr/bin/env python#coding:utf-8import os.pathimport tornado.localeimport tornado.httpserverimport tornado.ioloopimport tornado.optionsimport tornado.webfrom tornado.options import define, optionsimport pymongodefine("port", default=8000, help="run on the given port", type=int)class Application(tornado.web.Application): def __init__(self): #初始化一些東西 handlers = [ #url匹配 (r"/", MainHandler), (r"/index.html", MainHandler), (r"/add.html", AddHandler), (r"/listhost.html",List_hostHandler), (r"/delete.html", delete_hostHandler), (r"/module_action.html", Module_actionHandler), ] settings = dict( #程式設定,字典形式 template_path=os.path.join(os.path.dirname(__file__), "templates"), #設定模板檔案路徑 static_path=os.path.join(os.path.dirname(__file__), "static"), #設定靜態檔案路徑,如css\jpg\gif等 # ui_modules={"Book": BookModule}, #設定ui模組,可以用字典添加多個 debug=True, ) conn = pymongo.Connection("localhost", 27017) #初始化資料庫連接 self.db = conn["waitfish"] #選擇mongodb集合 tornado.web.Application.__init__(self, handlers, **settings) #傳入設定配置class MainHandler(tornado.web.RequestHandler): #首頁函數方法 def get(self): #設定httpget方法函數 self.render( "index.html", )class AddHandler(tornado.web.RequestHandler): #添加主機頁面 def get(self): self.render( "add.html", )class List_hostHandler(tornado.web.RequestHandler): #主機列表頁面,get方式現實全部主機 def get(self, *args, **kwargs): coll = self.application.db.waitfish hosts = coll.find() self.render( "listhost.html", hosts = hosts ) def post(self): #post方法現實post的主機 coll = self.application.db.waitfish #初始化資料庫連接 hostname = self.get_argument('hostname') #從post中擷取主機名稱 ipadd = self.get_argument('ipadd') #擷取主機ip地址 username = self.get_argument('username') #擷取主機使用者名稱 password = self.get_argument('password') #擷取密碼 post_dic = {'hostname':hostname, 'ipadd':ipadd, 'username':username, 'password':password} #產生要存入資料庫的內容 hosts = coll.find({'hostname':hostname}) #根據主機名稱判斷是否已經存在該主機 if hosts: #如果不存在 import ansible.runner #對主機進行初始化,複製公開金鑰到受管主機,(添加ip地址和主機名稱對到原生hosts檔案和ansible的hosts檔案) runner_copy_autherized_keys = ansible.runner.Runner( module_name = 'copy', module_args = "src=~/.ssh/id_rsa.pub dest=~/.ssh/authorized_keys owner=%s group=%s mode=644 backup=yes" %(username, username), remote_user = username, remote_pass = password, sudo = 'yes', sudo_pass =password, pattern = hostname, ) b = runner_copy_autherized_keys.run() print b runner = ansible.runner.Runner( module_name = 'shell', module_args = "echo '%s' >>/etc/ansible/hosts"% ipadd, sudo = 'yes', sudo_pass = 'xxxxxxx', transport = 'local', pattern = '127.0.0.1', ) #非同步執行該操作,防止web頁面被卡住 runner.run_async(30) coll.save(post_dic) #儲存主機資訊到資料庫 self.render( "listhost.html", #調用主機列表模板顯示被添加的主機資訊 hosts = hosts, ) else: #如果存在,則更新主機資訊 coll.update(post_dic,post_dic) self.render( # "listhost.html", # hosts = hosts, )class delete_hostHandler(tornado.web.RequestHandler): #定義刪除主機的函數 def post(self, *args, **kwargs): hostnames = self.get_arguments('hostname') # 根據checkbox得到hostname的列表 coll = self.application.db.waitfish #獲得資料庫遊標 for host in hostnames: coll.remove({"hostname":host}) #根據主機名稱刪除 self.render( "delete_info.html", message = "%s is removed!"% hostnames, #給出訊息 )class Module_actionHandler(tornado.web.RequestHandler): #定義模組操作函數方法 def get(self, *args, **kwargs): coll = self.application.db.waitfish #初始化資料庫連接 hosts = coll.find({}, {'hostname':1,'ipadd':1,"_id":0}) #這裡hostname:1 表示返回hostname列,由於_id列每次都返回所以用0禁用掉,模板還可以一樣 modulenames = ['ping', 'setup', 'copy','shell'] #現實我們定義的操作 self.render( "module_action.html", hosts = hosts, modulenames = modulenames, ) def post(self, *args, **kwargs): ipadd = self.get_arguments('ipadd')[0] #擷取主機名稱 module = self.get_arguments('modulename')[0] #擷取模組名 arg = self.get_arguments('args')[0] #擷取參數 coll = self.application.db.waitfish #初始化資料庫 user = coll.find_one({'ipadd':'%s'%ipadd})['username'] hostname = coll.find_one({'ipadd':'%s'%ipadd})['hostname'] #從資料庫找到主機的使用者名稱資訊 import ansible.runner runner = ansible.runner.Runner( #根據ansible的api來運行指令碼 module_name = module, module_args = arg, remote_user = user, #設定操作遠程受管主機的使用者名稱 pattern = ipadd, #設定要操作主機名 ) result = runner.run() #得到返回結果,這裡是同步執行,下個版本改進非同步 def pars_result(result): # 定義一個判斷結果的函數 if len(result['dark'])>0: # dark返回不為空白則表示操作失敗了 return result['dark'],'失敗!' else: return result['contacted'],'成功!' result = pars_result(result) self.render( "message.html", hostname = hostname, message = result[0], jieguo = result[1] )if __name__ == "__main__": tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()