CMDB是運維自動化項目,它能夠減小人工干預,減小人工成本。python
裝機、實時監控、自動化部署,創建在它們的基礎上是資產信息變動記錄(資產管控自動進行彙報)linux
在對獲取資產信息時,簡述有四種方案。正則表達式
方案A(Agent方法,基於Shell命令實現)shell
Agent方式,能夠將服務器上面的Agent程序做定時任務,定時將資產信息提交到指定API錄入數據庫數據庫
優勢:速度快 缺點:須要爲每臺服務器部署一個Agent程序windows
方案B(SSH形式,基於Paramiko模塊)服務器
中控機在獲取未採集資產信息的服務器(服務器主機名,密碼),依賴於Paramiko(py模塊)經過SSH方式去獲取運維
優勢:無Agent 缺點:速度慢ssh
若是在服務器較少的狀況下,可應用此方法數據庫設計
import paramiko # 建立SSH對象 ssh = paramiko.SSHClient() # 容許鏈接不在know_hosts文件中的主機 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 鏈接服務器 ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', password='123') # 執行命令 stdin, stdout, stderr = ssh.exec_command('df') # 獲取命令結果 result = stdout.read() # 關閉鏈接 ssh.close()
方案C(RPC形式,基於saltstack第三方工具)
此方案本質上和第二種方案大體是差很少的流程,中控機在獲取到未採集資產信息的服務器(主機名),再而將命令放入一個隊列中,服務器來獲取。服務器將結果放入另外一個隊列中,中控機獲取將服務信息發送到API進而錄入數據庫。
import salt.client local = salt.client.LocalClient() local.cmd('*', 'cmd.run', ['whoami'])
優勢:快,開發成本低 缺點:依賴於第三方工具
方案D(基於pubpet,瞭解)
省略號...
小結:
關於程序的可插拔機制。
開發一套程序時,要使其有充分的擴展性。接下來能夠寫一些僞代碼...
假設項目名爲AutoClient, 目錄結構以下:
AutoClient/ |-- bin/ | |-- auto_client.py |-- config/ | |-- settings.py |-- lib/
| |--
|-- log/ | |-- error.log | |-- run.log |-- src/ | |-- plugins/
| |-- __init__.py
| |-- base.py
| |-- cpu.py
| |-- disk.py
| |-- ...
| |-- package.py
| |-- scripts.py |-- README
例如,採集資產信息有上述描述的三種形式(agent,ssh,salt,),而將要作的一件事就是要讓程序兼容這三種形式
在配置文件中寫一點東西、配置文件就先寫這些(settings.py)
# 採集資產的方式,選項有:agent(默認), salt, ssh MODE = 'agent' # 採集硬件數據的插件 PLUGINS_DICT = { 'cpu': 'src.plugins.cpu.CpuPlugin', 'disk': 'src.plugins.disk.DiskPlugin', 'main_board': 'src.plugins.main_board.MainBoardPlugin', 'memory': 'src.plugins.memory.MemoryPlugin', 'nic': 'src.plugins.nic.NicPlugin', }
繼而寫一些公用的(base.py)
# 導入settings文件 from AutoCMDB.conf import settings class BasePlugin(object): def __init__(self): """ 驗證配置文件 """ mode_list = ['agent', 'ssh', 'salt'] if settings.MODE in mode_list: self.mode = settings.MODE else: raise Exception('配置文件發生錯誤') def ssh(self, cmd): pass def agent(self, cmd): pass def salt(self, cmd): pass def shell_cmd(self, cmd): """ 執行判斷模式 :param cmd: :return: """ if self.mode == 'agent': result = self.agent(cmd) elif self.mode == 'ssh': result = self.ssh(cmd) else: result = self.salt(cmd) return result def execute(self): """ 執行判斷平臺 :return: 目標 拿到資產採集信息 """ result = self.shell_cmd('查看平臺命令') if result == 'win': return self.window() elif result == 'linux': return self.linux() else: raise Exception('只支持windows') def window(self): raise Exception('...') def linux(self): raise Exception('...') class DiskPlugin(BasePlugin): def window(self): # 正則表達式匹配想要的信息 return '硬盤' def linux(self): # 正則表達式匹配想要的信息 return '硬盤' obj = DiskPlugin() result = obj.execute()
上述代碼看似不少,可是這樣寫有什麼好處或者說有什麼用意
這樣寫程序的可插拔性就很強了,例如採集硬盤信息只需在DiskPlugin的window或者linux寫代碼,此時不用再去判斷什麼模式,只須要將命令傳輸便可
其次,作內存、CPU、網卡信息按照硬盤那樣去寫。然後將各個單獨存入相應的文件,這更使程序簡潔明瞭。
接下來呢,想要同時獲取CPU、內存、網卡的資產信息
那麼配置文件的插件PLUGINS_DICT能夠派上用場了。依託於它,可根據反射去作(package.py)
# 導入settings from AutoCMDB.conf import settings # 動態導入模塊 import importlib response = {} for k, v in settings.PLUGINS_DICT.items(): moudle_path, cls_name = v.rsplit('.', 1) if hasattr(importlib.import_module(moudle_path), cls_name): func = getattr(importlib.import_module(moudle_path), cls_name) response[k] = func().execute() # 這樣response便封裝了全部資產信息