• 采集模块继续完善


    采集模块继续完善

    通过上一篇的采集模块,大差不差的快要完成了。

    根据高内聚低耦合的开发原则,启动文件应该是就写一个run方法就好才对,于是优化了一下。

    start.py

    from src.script import run
    if __name__ == '__main__':
        run()
    

    script.py

    from lib.config.settings import settings
    from src.client import Agent,SSHSalt
    
    def run():
    	#判断配置文件设置的是哪种采集方式,一共三种,第一种就是agent模式,第二种和第三种因为都需要hostname而且步骤相似,于是整合成了一个方法。
        if settings.MODE == 'agent':
            Agent().collect()
        else:
            SSHSalt().collect()
    

    client.py

    from src.plugins import Plugins_Dict
    from lib.config.settings import settings
    
    import requests
    
    class Agent():
    
        def collect(self):
            #### 采集资产信息
            #这就是上一篇博客的内容了,执行每一个插件,也就是每一个设备的process方法。
            res = Plugins_Dict().execute()
    
            for k, v in res.items():
                print(k, v)
    
            #### 将采集到的信息数据发送给API端,下面两种方式发送都可以
            # requests.post(settings.API_URL, data=json.dumps(res))
            requests.post(settings.API_URL, json=res)
    
    class SSHSalt():
        #这个方法是用来向api发送请求,获取主机名列表的,下面会有api端的代码
        def getHostname(self):
            hostnames = requests.get(settings.API_URL)
    
            ### hostnames 就是获取的主机名列表
            # return ['c1.com', 'c2.com']
            return hostnames ### ['c1.com', 'c2.com']
    
        def task(self, hostname):
            res = Plugins_Dict(hostname=hostname).execute()
    		#每次的执行结果都发送给api
            requests.post(settings.API, json=res)
    
        def collect(self):
            #获取了主机名列表,也就是域名
            hostnames = self.getHostname()
    		#因为需要连接服务器,会非常耗时,所以用多线程,用线程池来实现。
            from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
            p = ThreadPoolExecutor(10)
    
            for hostname in hostnames:
    
                p.submit(self.task, hostname)
    
    

    api端,暂时就这样,还没写。

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    def asset(request):
    
        if request.method == 'POST':
            print(request.body)
    
            return HttpResponse('okokok')
        else:
    
            #### 从数据库中获取服务器的主机名
    
            #### 最终将数据库中存的主机名以列表的格式返回
            return HttpResponse(['c1.com', 'c2.com'])
    

    2.数据表设计

    2.1 服务端app设计

    • myapi : 负责接收客户端数据, 然后分析客户端数据
    • backend: 后台管理的app
    • respositoy : 专门负责 管理 数据模型的

    2.2. 数据表设计

    遵守的原则:

    1. 客户端采集的字段,和表的字段要一致,方便后续数据直接存储数据库
    2. 客户端的字段名,在数据表中也是要有的

    表与表的关系:

    产品表和服务器表的关系:

    如果你认为是一对多:

    一条产品线(王者荣耀) 跑在 100 台服务器上 , 而每一台服务器上 只跑一个业务 王

    者荣耀

    如果你认为是多对多:

    一条产品线(王者荣耀) 跑在 100 台服务器上 , 而每一台服务器上 不只跑一个业务

    王者荣耀

    具体要看公司的情况而定

    数据表模型设计的原则:

    1. 表和表之间的关系
    2. 表的字段 因为 客户端传过来的字段是啥 我们就要设计这些字段
    from django.db import models
    
    class UserProfile(models.Model):
        """
        用户信息
        """
        name = models.CharField(u'姓名', max_length=32)
        email = models.EmailField(u'邮箱')
        phone = models.CharField(u'座机', max_length=32)
        mobile = models.CharField(u'手机', max_length=32)
        password = models.CharField(u'密码', max_length=64)
    
        class Meta:
            verbose_name_plural = "用户表"
    
        def __str__(self):
            return self.name
    
    class UserGroup(models.Model):
        """
        用户组
        """
        name = models.CharField(max_length=32, unique=True)
        users = models.ManyToManyField('UserProfile')
    
        class Meta:
            verbose_name_plural = "用户组表"
    
        def __str__(self):
            return self.name
    
    class BusinessUnit(models.Model):
        """
        业务线
        """
        name = models.CharField('业务线', max_length=64, unique=True)
        contact = models.ForeignKey('UserGroup', verbose_name='业务联系人', related_name='c', on_delete=models.CASCADE)
        manager = models.ForeignKey('UserGroup', verbose_name='系统管理员', related_name='m', on_delete=models.CASCADE)
    
        class Meta:
            verbose_name_plural = "业务线表"
    
        def __str__(self):
            return self.name
    
    class IDC(models.Model):
        """
        机房信息
        """
        name = models.CharField('机房', max_length=32)
        floor = models.IntegerField('楼层', default=1)
    
        class Meta:
            verbose_name_plural = "机房表"
    
        def __str__(self):
            return self.name
    
    class Tag(models.Model):
        """
        资产标签
        """
        name = models.CharField('标签', max_length=32, unique=True)
    
        class Meta:
            verbose_name_plural = "标签表"
    
        def __str__(self):
            return self.name
    
    
    class Server(models.Model):
        """
        服务器信息
        """
        device_type_choices = (
            (1, '服务器'),
            (2, '交换机'),
            (3, '防火墙'),
        )
        device_status_choices = (
            (1, '上架'),
            (2, '在线'),
            (3, '离线'),
            (4, '下架'),
        )
    
        device_type_id = models.IntegerField('服务器类型',choices=device_type_choices, default=1)
        device_status_id = models.IntegerField('服务器状态',choices=device_status_choices, default=1)
    
        cabinet_num = models.CharField('机柜号', max_length=30, null=True, blank=True)
        cabinet_order = models.CharField('机柜中序号', max_length=30, null=True, blank=True)
    
        idc = models.ForeignKey('IDC', verbose_name='IDC机房', null=True, blank=True, on_delete=models.CASCADE)
        business_unit = models.ForeignKey('BusinessUnit', verbose_name='属于的业务线', null=True, blank=True, on_delete=models.CASCADE)
    
        tag = models.ManyToManyField('Tag')
    
        hostname = models.CharField('主机名',max_length=128, unique=True)
        sn = models.CharField('SN号', max_length=64, db_index=True)
        manufacturer = models.CharField(verbose_name='制造商', max_length=64, null=True, blank=True)
        model = models.CharField('型号', max_length=64, null=True, blank=True)
    
        manage_ip = models.GenericIPAddressField('管理IP', null=True, blank=True)
    
        os_platform = models.CharField('系统', max_length=16, null=True, blank=True)
        os_version = models.CharField('系统版本', max_length=16, null=True, blank=True)
    
        cpu_count = models.IntegerField('CPU个数', null=True, blank=True)
        cpu_physical_count = models.IntegerField('CPU物理个数', null=True, blank=True)
        cpu_model = models.CharField('CPU型号', max_length=128, null=True, blank=True)
    
        create_at = models.DateTimeField(auto_now_add=True, blank=True)
    
        class Meta:
            verbose_name_plural = "服务器表"
    
        def __str__(self):
            return self.hostname
    
    
    class Disk(models.Model):
        """
        硬盘信息
        """
        slot = models.CharField('插槽位', max_length=8)
        model = models.CharField('磁盘型号', max_length=32)
        capacity = models.CharField('磁盘容量GB', max_length=32)
        pd_type = models.CharField('磁盘类型', max_length=32)
        server_obj = models.ForeignKey('Server',related_name='disk', on_delete=models.CASCADE)
    
        class Meta:
            verbose_name_plural = "硬盘表"
    
        def __str__(self):
            return self.slot
    
    
    class NIC(models.Model):
        """
        网卡信息
        """
        name = models.CharField('网卡名称', max_length=128)
        hwaddr = models.CharField('网卡mac地址', max_length=64)
        netmask = models.CharField(max_length=64)
        ipaddrs = models.CharField('ip地址', max_length=256)
        up = models.BooleanField(default=False)
        server_obj = models.ForeignKey('Server',related_name='nic', on_delete=models.CASCADE)
    
    
        class Meta:
            verbose_name_plural = "网卡表"
    
        def __str__(self):
            return self.name
    
    
    class Memory(models.Model):
        """
        内存信息
        """
        slot = models.CharField('插槽位', max_length=32)
        manufacturer = models.CharField('制造商', max_length=32, null=True, blank=True)
        model = models.CharField('型号', max_length=64)
        capacity = models.FloatField('容量', null=True, blank=True)
        sn = models.CharField('内存SN号', max_length=64, null=True, blank=True)
        speed = models.CharField('速度', max_length=16, null=True, blank=True)
    
        server_obj = models.ForeignKey('Server',related_name='memory', on_delete=models.CASCADE)
    
    
        class Meta:
            verbose_name_plural = "内存表"
    
        def __str__(self):
            return self.slot
    
    

    img

    注:表关系图

    api分析数据入库

    主要以硬盘数据入库为例

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    import json
    from respositoy import models
    
    def asset(request):
    
        if request.method == 'POST':
            res = json.loads(request.body)
            print(res)
    
            #### 1.获取post过来的主机名,判断主机是否合法
            status = res['basic']['status']
            if status != 10000:
                return HttpResponse('采集出错')
    
            hostname = res['basic']['data']['hostname']
    
            server_obj = models.Server.objects.filter(hostname=hostname).first()
    
            if not server_obj:
                return HttpResponse('资产未录入!')
    
            ##### 2.判断一下硬盘数据采集是否成功
            code = res['disk']['status']
            if code != 10000:
                models.ErrorLog.objects.create(asset_obj=server_obj, content=res['disk']['data'], title='采集硬盘数据出错')
    
    
            ##### 3.保存磁盘的数据入库
    
            new_disk_data = res['disk']['data']
    
            ### 新的slot集合
            new_slot = list(new_disk_data.keys())
    
            ### 老的slot集合
            old_disk_data = models.Disk.objects.filter(server_obj=server_obj).all()
            old_slot = []
            for obj in old_disk_data:
                old_slot.append(obj.slot)
    
            add_slot = set(new_slot).difference(set(old_slot))  #### [0,1,2,3,4,5]
    
            if add_slot:
                for slot in add_slot:
                    #### {'slot': '0', 'pd_type': 'SAS', 'capacity': '279.396', 'model': 'SEAGATE ST300MM0006     LS08S0K2B5NV'},
                    disk_info = res['disk']['data'][slot]
                    disk_info['server_obj'] = server_obj
    
                    models.Disk.objects.create(**disk_info)
    
    
    
    
            return HttpResponse('okokok')
        else:
    
            #### 从数据库中获取服务器的主机名
    
            #### 最终将数据库中存的主机名以列表的格式返回
            return HttpResponse(['c1.com', 'c2.com'])
    
    
    
  • 相关阅读:
    数组初始化 和 vector初始化
    剑指offer42 左旋转字符串
    k sum(lintcode)
    背包问题2 (lintcode)
    92.背包问题(lintcode)
    72. Edit Distance
    79 最长公共子串 (lintcode)
    77 最长公共子序列 (lintcode)
    132. Palindrome Partitioning II
    Mysql经常使用函数汇总
  • 原文地址:https://www.cnblogs.com/chanyuli/p/12312579.html
Copyright © 2020-2023  润新知