运维平台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    上面流程的三四步骤,如下的获取资产信息步骤

原文地址:https://www.cnblogs.com/jokerbj/p/8547292.html