zoukankan      html  css  js  c++  java
  • 运维平台cmdb开发-day1

    序读项目由来

    终极目标,运维平台。自动化。装机,监控,安装软件,部署
    基础服务,资产管理,之前是excel,现在是客户端自动获取,变更记录

    后台管理 api 采集资产

    四种模式
    agent 定时,每天执行一次,采集的资产回报给api,api负责入库
    ssh,需要中控机,不用部署agent,去api拿没有采集的主机,远程通过paramiko执行命令拿到数据回报给api
    salt,利用salt内部原理rbc,列队形式执行命令
    pupet,利用报表,每半个小时向master回报,我们利用报表执行自己的ruby脚本,资产拿到回报给api

    一 四种模式

    api 其他系统调用数据,不能让人直接用数据库。还可以提交数据,做统一化的管理。

    agent客户端有自定义的脚本,通过任务计划每天采集信息给api

    ssh 通过api 链接 数据库,查看谁没有给我信息,那我拿到主机名,我链接上去,执行命令,取返回值在给api

     slat rpc模式。 内部提供队列,zero mq

     30分钟自动链接,提供信息给中间,中间代码会整理这个信息

    二 各个模式代码

    import subprocess
    import requests
    
    ### pip3 install request
    
    ###################   采集数据  ##################
    
    
    result = subprocess.getoutput('ifconfig')
    print(result) # 正则处理获取的数据
    
    ##################    整理资产信息  ###################
    date_dict = {
        'nic':{},
        'disk':{},
        'mem':{}
    }
    
    ###################  发送数据  ##################
    requests.post('http://www.127.0.0.1:8000/assets.html',data=date_dict)
    Agent客户端模式
    # 基于 paramiko 模块
    # pip3 install paramiko
    
    import requests
    import paramiko
    
    
    ###################   获取未采集主机名  ##################
    
    # result = requests.get('http://www.127.0.0.1:8000/assets.html')
    con = ['c1.com','c2.com']  # 未收集到的主机名称
    
    
    ###################   通过paramiko链接远程服务器,执行命令  ##################
    # 创建SSH对象
    ssh = paramiko.SSHClient()
    
    # 允许链接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    # 链接服务器
    ssh.connect(hostname='c1.com',port=22,username='joker',password='123')
    
    # 执行命令
    stdin,stdout,stderr = ssh.exec_command('ifconfig')
    
    # 获取结果
    result = stdout.read()
    
    # 关闭链接
    ssh.close()
    print(result)
    
    ##################    整理资产信息  ###################
    date_dict = {result}
    
    ###################  发送数据  ##################
    requests.post('http://www.127.0.0.1:8000/assets.html',data=date_dict)
    paramiko的SSH模式
    # 安装saltstack    http://www.cnblogs.com/wupeiqi/articles/6415436.html
    # linux 上  rpm --import https://repo.saltstack.com/yum
    # Master : yum install salt-master     服务器端
    # Slave : yum install salt-minion      客户端
    
    
    
    # Master准备
    #  a . 配置文件,监听本机ip
    #     vim /etc/salt/master
    #     interface 本机ip地址
    
    #  b. 启动master
    #     /etc/init.d/salt-master start
    
    
    # Slave准备
    #  a . 配置文件,链接哪个master
    #      vim /etc/salt/minion
    #      master : 远程master地址
            
    #  b . 启动slave
    #      /etc/init.d/salt-minion start
    
    # 1. 配置 好了 之后创建关系
    # Master :
    # 查看
    # Master: salt-key -L          第一次执行命令的时候
    #     Accepted Keys:
    #     Denied Keys:             拒绝
    #     Unaccepted Keys:         未接受
    #         c1.com
    #         c2.com
    #         c3.com
    #     Rejected Keys:           拒绝
    
    # 2. 接受
    # Master: salt-key -a c1.com   -a 后面可以正则匹配
    
    # 在查看
    # Master: salt-key -L         
    #     Accepted Keys:
    #         c1.com
    #     Denied Keys:            
    #     Unaccepted Keys:         
    #         c2.com
    #         c3.com
    #     Rejected Keys:          
    
    # 3. 执行命令 
    # 通过py 文件执行命令
    # from salt import client
    # local = salt.client.LocalClient()
    # resutl = local.cmd('bogon','cmd.run',['ifconfig'])
    # resutl.keys()
    # ['bogon']
    # resutl.values()
    # ifconfig 的结果
    
    # 通过 传输命令执行
    # master:
    #     salt 'c1.com' cmd.run 'ifconfig'
    saltstack简单用法
    ###################   获取未采集主机名  ##################
    
    # result = requests.get('http://www.127.0.0.1:8000/assets.html')
    con = ['c1.com','c2.com']  # 未收集到的主机名称
    
    
    ###################   远程服务器执行命令 ##################
    # 2种方式
    import subprocess
    result = subprocess.getoutput("salt 'c1.com' cmd.run 'ifconfig'")
    
    import salt.client
    local = salt.client.LocalClient()
    resutl = local.cmd('c1.com','cmd.run',['ifconfig'])
    
    
    ##################    整理资产信息  ###################
    date_dict = {result}
    
    ###################  发送数据  ##################
    requests.post('http://www.127.0.0.1:8000/assets.html',data=date_dict)
    saltstack模式

    三 面向对象的继承

     

    四 代码

    流程

    # agent 形式
    # 1. 采集资产
    # 2. 将资产数据发送到api(post 表示要创建资产)
    
    # ssh形式
    # 1. 获取今日未采集主机列表
    # 2. 采集资产
    # 3. 将资产数据发送到api(post 表示要创建资产)
    
    
    # salt形式
    # 1. 获取今日未采集主机列表
    # 2. 采集资产
    # 3. 将资产数据发送到api(post 表示要创建资产)
    
    # agent 自己取内容,拿标识往后台发  需要维护一个主机名文件 才知道给谁发
    # 其他模式不需要,因为他先要获取主机名
    三种模式获取资产比较
    # 文件结构
    # bin 可执行文件 src 业务逻辑,采集资产信息 lib 公共功能 conf 配置文件 bin 可执行文件

     1. 资产信息的插件的封装

    # 采集资产: 三种不同的形式,而形式都在test里面
    
    from day73.conf import settings
    
    class BasePlugin(object):
    
        def __init__(self):
            mode_lsit = ['SSH','Salt','Agent']   # 配置文件里面的模式在这个列表里,执行命令
            if settings.MODE in mode_lsit:
                self.mode = settings.MODE
            else:
                raise Exception('配置文件错误')
    
        def ssh(self,cmd): # paramiko
            pass
    
        def agent(self,cmd):
            pass
    
        def salt(self,cmd):
            pass
    
        def shell_cmd(self,cmd):       # 获取 SETTINGS 里面的 模式
            if self.mode == 'SSH':
                ret = self.ssh(cmd)
            elif self.mode == 'Salt':
                ret =self.salt(cmd)
            else:
                ret = self.agent(cmd)
            return ret
    
        def execute(self):  # self 是 DiskPlugin 的对象 obj
    
            # 执行判断平台的命令
    
            # agent 模式,代码放在远程的服务器上
            # import subprocess
            # subprocess.getoutput('')
    
            # ssh 模式,paramiko模块远程链接上执行命令
    
            # saltstack 模式,调用salt接口执行命令
    
            ret = self.shell_cmd('查看平台命令')              # 不需要做判断 模式了,在内部判断了哪种模式
            if ret == 'win':
                return self.windows()
            elif ret == 'linux':
                return self.linux()
            else:
                raise Exception('只支持windows和Linux')
    
        def linux(self):
            raise Exception('....')
    
        def windows(self):
            raise Exception('....')
    
    
    class DiskPlugin(BasePlugin): # 硬盘
    
        def linux(self):
            output = self.shell_cmd('fdisk -l')
            # 正则表达式,取该取的内容返回
            return output
    
        def windows(self):
            output = self.shell_cmd('xxx')
            return output
    
    
    class MemPlugin(BasePlugin):  # 内存
    
        def linux(self):
            output = self.shell_cmd('free')
            return output
    
        def windows(self):
            output = self.shell_cmd('xxx')
            return output
    
    
    obj = BasePlugin()
    obj.execute()  # 就会执行命令,会自动分辨是哪个平台
    采集资产
    用到的知识点:
    面向对象的继承
     2. 数据打包
    将,内存,硬盘,网卡等信息打包在一起
    # 将数据打包返回
    
    # from .plugins.disk import DiskPlugin    导入 采集对象类
    # from .plugins.mem import MemPlugin
    # from .plugins.nic import NicPlugin
    
    from day73.conf import settings
    def pack():
        # 如果需要其他信息,就需要更改源码,这是我们不想看到的
        # obj1 = DiskPlugin()
        # disk_info = obj1.execute()
        #
        # obj2 = MemPlugin()
        # mem_info = obj2.execute()
        #
        # obj3 = NicPlugin()
        # nic_info = obj3.execute()
        #
        # response = {
        #     'nic':nic_info,
        #     'mem':mem_info,
        #     'disk':disk_info
        # }
    
        # 通过配置文件解决
    
        response = {}
        '''
        settings.PLUGINS   
        PLUGINS = {
        'disk':'src.plugins.disk.DiskPlugin',
        'men':'src.plugins.mem.MemPlugin',
        'nic':'src.plugins.nic.NickPlugin',
        }
        '''
    
        '''
        # from 导入模块
        from day73.src.plugins import disk
        content = disk.DiskPlugin().execute()  # 实例化 并且 执行 方法,返回内容
        
        # 字符串的导入模块
        import importlib
        M = importlib.import_module('PY文件路径')  # py 文件
        M = importlib.import_module('src.plugins.disk')  # py 文件
        cls = getattr(M, 'DiskPlugin')   # 反射
        content = cls.DiskPlugin().execute()  # 实例化 并且 执行 方法,返回内容
        '''
    
        for k,v in settings.PLUGINS.items():
            import importlib
            m_path,classname = v.rsplit('.',maxsplit=1) # 从右边第一个点进行分割
            M = importlib.import_module(m_path)  # py 文件
            cls = getattr(M, classname)                   # 是否有这个类
            # 'disk':'src.plugins.disk.DiskPlugin',
            # v 是字符串,所以要用反射
            response[k] = cls().execute()     # v().execute() 执行命令后的结果,参考.execute流程
    
        return response
    数据打包pack
    用到的知识点:
    # 字符串的导入模块
    import importlib
    M = importlib.import_module('PY文件路径')  # py 文件
    M = importlib.import_module('src.plugins.disk')  # py 文件
    cls = getattr(M, 'DiskPlugin')   # 反射
    content = cls.DiskPlugin().execute()  # 实例化 并且 执行 方法,返回内容
    字符串导入模块

      3. bin目录启动文件导入

    # package.PY文件在SRC目录下导入
    # from day73.src import package
    # data_dict = package.pack()
    
    # 将package.PY文件的代码放入到SRC里面的__init__文件中,然后导入包
    # 导入包,文件夹,默认就会加载文件夹下的__INIT__文件
    from day73.src import plugins
    data_dict = plugins.pack()   # 相当于将PACK放到了plugins里面了,就可以调用了
    导入文件,模块,导入包,目录

      4. 代码流程

     代码流程进阶 AutoClient    上面流程的三四步骤,如下的获取资产信息步骤

  • 相关阅读:
    javascript定义变量和优先级的问题
    css expression explaination
    apply()与call()详解
    jquery $(document).ready() 与window.onload的区别
    ES5严格模式
    css margin collapse
    作业 20181016-10 每周例行报告
    作业 20181009-9 每周例行报告
    作业 20180925-1 每周例行报告
    20180925-7 规格说明书-吉林市2日游
  • 原文地址:https://www.cnblogs.com/jokerbj/p/8547292.html
Copyright © 2011-2022 走看看