CMDB--autoclient

autoclient

1.項目目錄結構規劃

bin:項目啓動文件
conf:配置文件
lib:引入第三方庫,庫文件
src:業務邏輯

2.高級配置文件的實現

實現的核心代碼:
集成全局的配置
for k in dir(global_settings):
        if k.isupper():
                v = getattr(global_settings, k)
                setattr(self, k, v)
集成自定製的配置
for k in dir(config):
    if k.isupper():
        v = getattr(config, k)
        setattr(self, k, v)

3.項目實現方案以及解決方案:

3.1首先面向過程的問題:
寫起來簡單容易,可是問題在於:面向過程的編程思想,不利於未來的維護和拓展,而且業務邏輯代碼在start.py文件中,不符合高內聚低耦合原則
原則就是:各個模塊或者各個類以及函數之間都是獨立的html

3.2可插拔式採集解決上述問題,將每一個模塊定義一個文件python

硬件,主板,cpu....
代碼寫起來,start.py文件執行文件裏面,一個個導入插件,一個個實例化django

因爲查找需求,不要查的文件須要註釋掉,這裏參考的是django的中間件概念,從路徑下導入一個個類,實現可插拔式的採集(經過#註釋)編程

PLUGINS_DICT = {
    'basic' : 'src.plugins.basic.Basic',
    'cpu' : 'src.plugins.cpu.Cpu',
    'disk' : 'src.plugins.disk.Disk',
    'board' : 'src.plugins.board.Board',
    'memory' : 'src.plugins.memory.Memory',
}

將plugins變成一個包,定義一個類PluginsManager,設置一個方法,execute ---從配置文件中讀取要採集的插件信息, 而且執行。在start.py文件中不按照原先的導入路徑,導入這個管理採集插件的類,執行實例化,而且執行下面的execute的方法服務器

for k, v in self.plugins_dict.items():
            ret = {"status":None, 'data':None}
            '''
            k: basic
            v: src.plugins.basic.Basic
            '''

問題來了,將這個v怎麼解決 ,切分ssh

module_path, class_name = v.rsplit('.',1)  ### ['src.plugins.basic', 'Basic']

因爲切下來的是字符串,不能夠from module_path import class_name函數

如何將字符串形式的模塊導入進來-----importlib,其中裏面有個模塊import_module插件

response={}
for k,v in self.plugins_dict.items():
    module_path,class_name=v.rsplit('.',1)
    m=importlib.import_module(module_path)

    cls=getattr(m,class_name)
    res=cls().process()
    response[k]=res
return response

3.3 代碼採集冗餘:debug

解決方法1:繼承,寫一個函數--------缺點每次新加的插件就比較麻煩要繼承code

解決方案2:init.py文件中,寫入一個command方法。將函數做爲一個參數傳進去,也就是函數的參數地址

def command(self, cmd):

        if self.mode == 'agent':
            import subprocess
            res = subprocess.getoutput(cmd)
            return res

        elif self.mode == 'ssh':
            import paramiko
            ssh = paramiko.SSHClient()
            # 容許鏈接不在know_hosts文件中的主機
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            # 鏈接服務器
            ssh.connect(hostname='192.168.200.30', port=22, username='root', password='997997')
            # 執行命令
            stdin, stdout, stderr = ssh.exec_command(cmd)
            # 獲取命令結果
            result = stdout.read()
            # 關閉鏈接
            ssh.close()
            return result
        elif self.mode == 'salt':
            import salt.client
            local = salt.client.LocalClient()
            result = local.cmd('c2.salt.com', 'cmd.run', [cmd])
            return result
        else:
            raise Exception ('只支持agent/ssh/salt模式')

命令採集完了將數據進行分析,每一個插件寫一個parse分析函數

4.debug開發模式:

命令執行,將結果拿到放到文件夾files文件裏面,讀取到項目裏面,運行開發模式下代碼

5.採集的代碼,報錯的信息完整提交

import traceback
def run():
    try:
        int('asasda')
    except Exception as e:
        print(traceback.format_exc())
run()
##能夠拿到完整的報錯信息