zoukankan      html  css  js  c++  java
  • 【IMU_Ops】------IV------ IMU自动化运维平台之CMDB(添加新资产)

    说明
    本文中所有内容仅作为学习使用,请勿用于任何商业用途。
    本文为原创,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明。

      上一章节,我们仅仅是做到在admin管理后台看见我们定义的所有models信息。本章节开始主要是实现CMDB中资产新增、新资产上线、资产更新、资产展示等功能。

     #A 新增资产

      首先需要更新视图文件view.py,先不要着急去撸代码,要搞清楚新增资产的大体逻辑再去撸代码(避免返工)下图为新增资产的逻辑图示及概述:

    •   其中assets-data应该是通过POST发送至服务端的资产原始数据;
    •   资产数据通过json转换为json数据类型;
    •   进行接收到的数据进行合理检查(安全性、合理性、完整性等);
    •   判断数据是否为空,若为空则返回错误信息并退出视图;
    •   判断数据是否为字典类型(这里为了方便操作,定义资产数据为字典类型),若非字典则返回错误信息并退出视图;
    •   判断数据是否带有SN,若非则返回错误信息并退出视图(SN是标示一个合法资产的唯一字段,不能缺少不能为空);

      下面我们根据以上逻辑,编写新增资产的视图代码:

     1 from django.shortcuts import HttpResponse
     2 from django.views.decorators.csrf import csrf_exempt
     3 import json
     4 from assets import models
     5 from assets import assets_handler
     6 
     7 
     8 # Create your views here.
     9 @csrf_exempt  #这里为了方便暂且跳过Django的csrf安全机制(后期再完善安全相关配置)
    10 def report(request):
    11     if request.method == "POST":
    12         assets_data = request.POST.get('assets_data')
    13         print(assets_data)
    14         data = json.loads(assets_data)
    15         # 判断data是否为空
    16         if not data:
    17             return HttpResponse("提交的数据为空!")
    18         if not issubclass(dict, type(data)):
    19             return HttpResponse("提交的数据必须是字典格式!")
    20         # 判断提交的数据是否有唯一键:sn
    21         sn = data.get('sn', None)
    22         if sn:
    23             # 判断是否为线上资产中存在的资产
    24             assets_obj = models.Assets.objects.filter(sn=sn)
    25             if assets_obj:
    26                 # 更新线上资产信息
    27                 update_assets = assets_handler.UpdateAsset(request, assets_obj[0], data)
    28                 return HttpResponse("资产已更新!")
    29             else:
    30                 # 进入待审批区域
    31                 obj = assets_handler.NewAssets(request, data)
    32                 response = obj.add_to_new_assets_zone()
    33                 return HttpResponse(response)
    34         else:
    35             return HttpResponse("提交的数据中未包含SN,请校验数据!")
    36     return HttpResponse("怎么就200了!")
    view.py

     #B 资产数据处理

      接下来,针对assets_data进行数据处理,在view文件中我们仅仅是针对数据进行了SN的判断和数据是否为空的判断。资产更新及提交资产到待审批区域还未解决,但这里我们还有几点需要明确的:

      通过SN在已上线的资产进行查找,若存在则进入已上线资产的更新流程;

      如果没有,说明这是个新资产,需要添加到新资产区;

      创建一个assets_handler.py文件,其中新建四个类分别实现四个功能:

      NewAssets(将资源新增到待审批区域)

      ApproveAssets(审批待上线的资源)

      UpdateAssets(更新已上线资产信息)

      Log(记录资产操作日志)

      整个数据处理的大体流程为:创建一个asset_handler.NewAsset()对象,然后调用它的obj.add_to_new_assets_zone()方法,将资产数据保存至models中的NewAssetsApprovalZone中(需要在models文件新增待审批区所需要的字段,models中代码会一并整理到第二章节中),根据实际情况,接收返回相应的结果;审批待上线资产则比较粗暴,一键审批并将待上线数据直接转正即可(从待审批区域移至资产表中);更新资产则是通过view中针对SN的判断来执行相应的数据更新即可。

      新增资产分两种情况:

    1.   彻底的新资产,任何区域都不存在该资产,直接添加至待审批区域即可;
    2.   已上线资产中没有该资产,但是待审批区中存在该资产(审批人还未审批的资产),此时再次接收到相同SN的资产时,只需要更新待审批区域该资产的数据即可;

      下面是assets_handler中各个功能模块的代码:

     

    NewAssets
      1 class ApproveAssets:
      2     # 审批待上线资产
      3     def __init__(self, request, assets_id):
      4         self.request = request
      5         self.new_assets = models.NewAssetApprovalZone.objects.get(id=assets_id)
      6         self.data = json.loads(self.new_assets.data)
      7 
      8     def assets_online(self):
      9         # 预留接口
     10         func = getattr(self, "_%s_online" % self.new_assets.assets_type)
     11         ret = func()
     12         return ret
     13 
     14     def _server_online(self):
     15         assets = self._create_assets()
     16         try:
     17             self._create_manufacturer(assets)  # 创建厂商
     18             self._create_server(assets)  # 创建服务器
     19             self._create_cpu(assets)  # 创建CPU
     20             self._create_ram(assets)  # 创建内存
     21             self._create_disk(assets)  # 创建硬盘
     22             self._create_nic(assets)  # 创建网卡
     23             self._delete_original_asset()  # 从待审批资产区删除已审批上线的资产
     24         except Exception as e:
     25             assets.delete()
     26             log('approve_failed', msg=e, new_assets=self.new_assets, request=self.request)
     27             print(e)
     28             return False
     29         else:
     30             # 添加日志
     31             log("online", assets=assets, request=self.request)
     32             print("新服务器上线!")
     33             return True
     34 
     35     def _create_assets(self):
     36         # 创建资产并上线
     37         assets = models.Assets.objects.create(assets_type=self.new_assets.assets_type,
     38                                               assets_name="%s:%s" % (self.new_assets.assets_type, self.new_assets.sn),
     39                                               sn=self.new_assets.sn, assets_approved=self.request.user,)
     40         return assets
     41 
     42     def _create_manufacturer(self, asset):
     43         # 创建厂商
     44         m = self.new_assets.manufacturer
     45         if m:
     46             manufacturer_obj, _ = models.ManufacturerAssets.objects.get_or_create(name=m)
     47             asset.manufacturer = manufacturer_obj
     48             asset.save()
     49 
     50     def _create_server(self, asset):
     51         # 创建服务器
     52         models.ServerAssets.objects.create(assets=asset, model=self.new_assets.model, os_type=self.new_assets.os_type,
     53                                            os_distribution=self.new_assets.os_distribution,
     54                                            os_release=self.new_assets.os_release)
     55 
     56     def _create_cpu(self, asset):
     57         # 创建CPU
     58         cpu = models.CPUAssets.objects.create(assets=asset)
     59         cpu.cpu_model = self.new_assets.cpu_model
     60         cpu.cpu_count = self.new_assets.cpu_count
     61         cpu.cpu_core_count = self.new_assets.cpu_core_count
     62         cpu.save()
     63 
     64     def _create_ram(self, asset):
     65         # 创建内存
     66         ram_list = self.data.get('ram')
     67         if not ram_list:
     68             return
     69         for ram_dict in ram_list:
     70             if not ram_dict.get('slot'):
     71                 raise ValueError("内存插槽位置不存在!")
     72             ram = models.RAMAssets()
     73             ram.assets = asset
     74             ram.slot = ram_dict.get('slot')
     75             ram.sn = ram_dict.get('sn')
     76             ram.model = ram_dict.get('model')
     77             ram.manufacturer = ram_dict.get('manufacturer')
     78             ram.volume = ram_dict.get('volume', 0)
     79             ram.save()
     80 
     81     def _create_disk(self, asset):
     82         # 创建硬盘
     83         disk_list = self.data.get('physical_disk_driver')
     84         if not disk_list:  # 一条硬盘数据都没有
     85             return
     86         for disk_dict in disk_list:
     87             if not disk_dict.get('sn'):
     88                 raise ValueError("未知sn的硬盘!")  # 根据sn确定具体某块硬盘。
     89             disk = models.DiskAssets()
     90             disk.assets = asset
     91             disk.sn = disk_dict.get('sn')
     92             disk.model = disk_dict.get('model')
     93             disk.brand = disk_dict.get('brand'),
     94             disk.slot = disk_dict.get('slot')
     95             disk.volume = disk_dict.get('volume', 0)
     96             iface = disk_dict.get('interface_type')
     97             if iface in ['SATA', 'SAS', 'SCSI', 'SSD', 'unknown']:
     98                 disk.interface_type = iface
     99 
    100             disk.save()
    101 
    102     def _create_nic(self, asset):
    103         # 创建网卡
    104         nic_list = self.data.get("nic")
    105         if not nic_list:
    106             return
    107 
    108         for nic_dict in nic_list:
    109             if not nic_dict.get('mac'):
    110                 raise ValueError("网卡缺少mac地址!")
    111             if not nic_dict.get('model'):
    112                 raise ValueError("网卡型号未知!")
    113 
    114             nic = models.NICAssets()
    115             nic.assets = asset
    116             nic.name = nic_dict.get('name')
    117             nic.model = nic_dict.get('model')
    118             nic.mac = nic_dict.get('mac')
    119             nic.ip_address = nic_dict.get('ip_address')
    120             if nic_dict.get('net_mask'):
    121                 if len(nic_dict.get('net_mask')) > 0:
    122                     nic.net_mask = nic_dict.get('net_mask')[0]
    123             nic.save()
    124 
    125     def _delete_original_asset(self):
    126         # 对审批通过的资产进行待审批区删除(其实不删除而是通过某个字段改变状态更合理,后期再优化吧)
    127         self.new_assets.delete()
    ApproveAssets
      1 class UpdateAsset:
      2     # 更新已上线资产信息
      3     def __init__(self, request, assets, report_data):
      4         self.request = request
      5         self.assets = assets
      6         self.report_data = report_data
      7         self.asset_update()
      8 
      9     def asset_update(self):
     10         # 预留接口
     11         func = getattr(self, "_%s_update" % self.report_data['assets_type'])
     12         ret = func()
     13         return ret
     14 
     15     def _server_update(self):
     16         try:
     17             self._update_manufacturer()  # 更新厂商
     18             self._update_server()  # 更新服务器
     19             self._update_cpu()  # 更新CPU
     20             self._update_ram()  # 更新内存
     21             self._update_disk()  # 更新硬盘
     22             self._update_nic()  # 更新网卡
     23             self.assets.save()
     24         except Exception as e:
     25             log('update_failed', msg=e, assets=self.assets, request=self.request)
     26             print(e)
     27             return False
     28         else:
     29             # 添加日志
     30             log("update_success", assets=self.assets)
     31             print("资产数据被更新!")
     32             return True
     33 
     34     def _update_manufacturer(self):
     35         # 更新厂商
     36 
     37         m = self.report_data.get('manufacturer')
     38         if m:
     39             manufacturer_obj, _ = models.ManufacturerAssets.objects.get_or_create(name=m)
     40             self.assets.manufacturer = manufacturer_obj
     41         else:
     42             self.assets.manufacturer = None
     43         self.assets.manufacturer.save()
     44 
     45     def _update_server(self):
     46         # 更新服务器
     47         self.assets.serverassets.model = self.report_data.get('model')
     48         self.assets.serverassets.os_type = self.report_data.get('os_type')
     49         self.assets.serverassets.os_distribution = self.report_data.get('os_distribution')
     50         self.assets.serverassets.os_release = self.report_data.get('os_release')
     51         self.assets.serverassets.save()
     52 
     53     def _update_cpu(self):
     54         # 更新CPU信息
     55         self.assets.cpu_assets .cpu_model = self.report_data.get('cpu_model')
     56         self.assets.cpu_assets.cpu_count = self.report_data.get('cpu_count')
     57         self.assets.cpu_assets.cpu_core_count = self.report_data.get('cpu_core_count')
     58         self.assets.cpu_assets.save()
     59 
     60     def _update_ram(self):
     61         """
     62         更新内存信息。
     63         使用集合数据类型中差的概念,处理不同的情况。
     64         如果新数据有,但原数据没有,则新增;
     65         如果新数据没有,但原数据有,则删除原来多余的部分;
     66         如果新的和原数据都有,则更新。
     67         在原则上,下面的代码应该写成一个复用的函数,
     68         但是由于内存、硬盘、网卡在某些方面的差别,导致很难提取出重用的代码。
     69         :return:
     70         """
     71         # 获取已有内存信息,并转成字典格式
     72         old_rams = models.RAMAssets.objects.filter(assets=self.assets)
     73         old_rams_dict = dict()
     74         if old_rams:
     75             for ram in old_rams:
     76                 old_rams_dict[ram.slot] = ram
     77         # 获取新数据中的内存信息,并转成字典格式
     78         new_rams_list = self.report_data['ram']
     79         new_rams_dict = dict()
     80         if new_rams_list:
     81             for item in new_rams_list:
     82                 new_rams_dict[item['slot']] = item
     83 
     84         # 利用set类型的差集功能,获得需要删除的内存数据对象
     85         need_deleted_keys = set(old_rams_dict.keys()) - set(new_rams_dict.keys())
     86         if need_deleted_keys:
     87             for key in need_deleted_keys:
     88                 old_rams_dict[key].delete()
     89 
     90         # 需要新增或更新的
     91         if new_rams_dict:
     92             for key in new_rams_dict:
     93                 defaults = {
     94                     'sn': new_rams_dict[key].get('sn'),
     95                     'model': new_rams_dict[key].get('model'),
     96                     'brand': new_rams_dict[key].get('brand'),
     97                     'volume': new_rams_dict[key].get('volume', 0),
     98                 }
     99                 models.RAMAssets.objects.update_or_create(assets=self.assets, slot=key, defaults=defaults)
    100 
    101     def _update_disk(self):
    102         """
    103         更新硬盘信息,类似更新内存。
    104         """
    105         old_disks = models.DiskAssets.objects.filter(assets=self.assets)
    106         old_disks_dict = dict()
    107         if old_disks:
    108             for disk in old_disks:
    109                 old_disks_dict[disk.sn] = disk
    110 
    111         new_disks_list = self.report_data['physical_disk_driver']
    112         new_disks_dict = dict()
    113         if new_disks_list:
    114             for item in new_disks_list:
    115                 new_disks_dict[item['sn']] = item
    116 
    117         # 需要删除的
    118         need_deleted_keys = set(old_disks_dict.keys()) - set(new_disks_dict.keys())
    119         if need_deleted_keys:
    120             for key in need_deleted_keys:
    121                 old_disks_dict[key].delete()
    122 
    123         # 需要新增或更新的
    124         if new_disks_dict:
    125             for key in new_disks_dict:
    126                 interface_type = new_disks_dict[key].get('interface_type', 'unknown')
    127                 if interface_type not in ['SATA', 'SAS', 'SCSI', 'SSD', 'unknown']:
    128                     interface_type = 'unknown'
    129                 defaults = {
    130                     'slot': new_disks_dict[key].get('slot'),
    131                     'model': new_disks_dict[key].get('model'),
    132                     'brand': new_disks_dict[key].get('brand'),
    133                     'volume': new_disks_dict[key].get('volume', 0),
    134                     'interface_type': interface_type,
    135                 }
    136                 models.DiskAssets.objects.update_or_create(assets=self.assets, sn=key, defaults=defaults)
    137 
    138     def _update_nic(self):
    139         """
    140         更新网卡信息,类似更新内存。
    141         """
    142         old_nics = models.NICAssets.objects.filter(assets=self.assets)
    143         old_nics_dict = dict()
    144         if old_nics:
    145             for nic in old_nics:
    146                 old_nics_dict[nic.model + nic.mac] = nic
    147 
    148         new_nics_list = self.report_data['nic']
    149         new_nics_dict = dict()
    150         if new_nics_list:
    151             for item in new_nics_list:
    152                 new_nics_dict[item['model'] + item['mac']] = item
    153 
    154         # 需要删除的
    155         need_deleted_keys = set(old_nics_dict.keys()) - set(new_nics_dict.keys())
    156         if need_deleted_keys:
    157             for key in need_deleted_keys:
    158                 old_nics_dict[key].delete()
    159 
    160         # 需要新增或更新的
    161         if new_nics_dict:
    162             for key in new_nics_dict:
    163                 if new_nics_dict[key].get('net_mask') and len(new_nics_dict[key].get('net_mask')) > 0:
    164                     net_mask = new_nics_dict[key].get('net_mask')[0]
    165                 else:
    166                     net_mask = ""
    167                 defaults = {
    168                     'name': new_nics_dict[key].get('name'),
    169                     'ip_address': new_nics_dict[key].get('ip_address'),
    170                     'net_mask': net_mask,
    171                 }
    172                 models.NICAssets.objects.update_or_create(assets=self.assets, model=new_nics_dict[key]['model'],
    173                                                           mac=new_nics_dict[key]['mac'], defaults=defaults)
    174 
    175         print('更新成功!')
    UpdateAssets
     1 def log(log_type, msg=None, assets=None, new_assets=None, request=None):
     2     # 记录日志
     3     event = models.EventLog()
     4     if log_type == "online":
     5         event.name = "%s <%s> :  上线" % (assets.assets_name, assets.sn)
     6         event.assets = assets
     7         event.detail = "资产成功上线!"
     8         event.user = request.user
     9     elif log_type == "approve_failed":
    10         event.name = "%s <%s> :  审批失败" % (new_assets.assets_type, new_assets.sn)
    11         event.new_assets = new_assets
    12         event.detail = "审批失败!
    %s" % msg
    13         event.user = request.user
    14     elif log_type == "update_success":
    15         event.name = "%s [%s] <%s> :  数据更新!" % (assets.assets_type, assets.assets_name, assets.sn)
    16         event.assets = assets
    17         event.detail = "更新成功!"
    18     elif log_type == "update_failed":
    19         event.name = "%s [%s] <%s> :  更新失败" % (assets.assets_type, assets.assets_name, assets.sn)
    20         event.assets = assets
    21         event.detail = "更新失败!
    %s" % msg
    22         # 更多日志类型.....
    23     event.save()
    Log

     #C 资产数据处理

      最后还有几个工作需要完成,我们有个view但是还缺少url的配置,还需要一些测试数据来检测我们的各个功能是否ok。

      首先我们完成rul的配置,为保证整个项目的代码可读性及高扩展性,我们更新IMU_DevOps目录下的urls文件:

    1 from django.contrib import admin
    2 from django.urls import path, include
    3 
    4 urlpatterns = [
    5     path('admin/', admin.site.urls),
    6     path('assets/', include('assets.urls'))
    7 ]
    urls.py

    嗯时间到,需要带娃去跨年,今年就写到这里吧。明年再更新!在这里祝大家新年快乐!2020各种顺!

      接下来在assets包中新增urls.py这个文件并编写代码,主要是指定之前我们编写的view视图中的report方法。

    1 from django.urls import path
    2 from assets import views
    3 
    4 
    5 app_name = 'assets'
    6 
    7 urlpatterns = [
    8     path('report/', views.report, name='report')
    9 ]
    assets-urls.py

      然后我们分别新建Conf,Log的python package,其中Conf中主要用来存放和该项目相关的配置文件,工程目录中的settings文件我们仅针对整个工程做基础的设置,而每个模块的配置我们都单独来写,这样不仅修改某个配置文件的时候不会影响到整个工程,同时整个工程的扩展性也会大大提升。在Log包目录下新建一个IMU_assets.log文件(暂时用来存放测试log,正式log还是通过assets_handler.py中的log方法将其存放在数据库中),接下来撸代码:

     1 import os
     2 
     3 # 远端接收数据的服务器
     4 Params = {
     5     "server": "127.0.0.1",
     6     "port": 8000,
     7     'url': '/assets/report/',
     8     'request_timeout': 30,
     9 }
    10 
    11 # 日志文件配置
    12 
    13 PATH = os.path.join(os.path.dirname(os.getcwd()), 'Log', 'IMU_assets.log')
    14 print(PATH)
    Conf-assets_setting.py

      最后我们需要测试以上功能是否达到我们的需求,由于是测试我这边就临时写一个test的文件,在其中定义两台服务器的信息并将它发送至我们设置的服务端。

      1 import json
      2 import time
      3 import urllib.request
      4 import urllib.parse
      5 import os
      6 import sys
      7 from Conf import assets_setting
      8 
      9 BASE_DIR = os.path.dirname(os.getcwd())
     10 # 设置工作目录,使得包和模块能够正常导入
     11 sys.path.append(BASE_DIR)
     12 
     13 def update_test(data):
     14     """
     15     创建测试用例
     16     """
     17     # 将数据打包到一个字典内,并转换为json格式
     18     data = {"assets_data": json.dumps(data)}
     19     # print(data) 测试是否收到data
     20     # 根据assets_setting.py中的配置,构造url
     21     url = "http://%s:%s%s" % (assets_setting.Params['server'], assets_setting.Params['port'],
     22                               assets_setting.Params['url'])
     23     print('正在将数据发送至: [%s]  ......' % url + '100%')
     24     data_encode = urllib.parse.urlencode(data).encode()
     25     response = urllib.request.urlopen(url=url, data=data_encode, timeout=assets_setting.Params['request_timeout'])
     26     print("33[31;1m发送完毕!33[0m ")
     27     message = response.read().decode()
     28     print("返回结果:%s" % message)
     29     try:
     30         # 使用Python内置的urllib.request库,发送post请求。
     31         # 需要先将数据进行封装,并转换成bytes类型
     32         data_encode = urllib.parse.urlencode(data).encode()
     33         response = urllib.request.urlopen(url=url, data=data_encode, timeout=assets_setting.Params['request_timeout'])
     34         print("33[31;1m发送完毕!33[0m ")
     35         message = response.read().decode()
     36         print("返回结果:%s" % message)
     37     except Exception as e:
     38         message = "发送失败"
     39         print("33[31;1m发送失败,%s33[0m" % e)
     40 
     41     # 记录日志
     42     with open(assets_setting.PATH, 'ab') as f:
     43         log = '发送时间: %s 	 服务器地址: %s 	 返回结果:%s 
    ' % (time.strftime('%Y-%m-%d %H-%M-%S'), url, message)
     44         f.write(log.encode())
     45         print('日志已记录完成!')
     46 
     47 
     48 if __name__ == '__main__':
     49     windows_data = {
     50         "os_type": "Windows",
     51         "os_release": "2019 64bit ",
     52         "os_distribution": "Microsoft",
     53         "assets_type": "server",
     54         "cpu_count": 16,
     55         "cpu_model": "Intel(R) Core(TM) i9-9750H CPU @ 4.30GHz",
     56         "cpu_core_count": 64,
     57         "ram": [
     58             {
     59                 "slot": "A0",
     60                 "volume": 64,
     61                 "model": "Physical Memory",
     62                 "brand": "kingstone ",
     63                 "sn": "323126"
     64             },
     65             {
     66                 "slot": "A1",
     67                 "volume": 64,
     68                 "model": "Physical Memory",
     69                 "brand": "kingstone ",
     70                 "sn": "312136"
     71             },
     72 
     73         ],
     74         "manufacturer": "Dell inc.",
     75         "model": "Y9320K 2019",
     76         "wake_up_type": 3,
     77         "sn": "31233-OEM-1312-132we6",
     78         "physical_disk_driver": [
     79             {
     80                 "interface_type": "unknown",
     81                 "slot": 0,
     82                 "sn": "3456733121124566544",
     83                 "model": "SAMSUNG SV122164G ATA Device",
     84                 "brand": "希捷",
     85                 "volume": 2048
     86             },
     87             {
     88                 "interface_type": "SATA",
     89                 "slot": 1,
     90                 "sn": "312334332122365423",
     91                 "model": "Seagate SV1324264G ATA Device",
     92                 "brand": "希捷",
     93                 "volume": 2048
     94             },
     95 
     96         ],
     97         "nic": [
     98             {
     99                 "mac": "14:CF:22:EF:36:23",
    100                 "model": "[00000066] Realtek RTL8192CU Wireless LAN 802.11n USB 2.0 Network Adapter",
    101                 "name": 14,
    102                 "ip_address": "10.8.8.17",
    103                 "net_mask": [
    104                     "255.255.255.0",
    105                     "64"
    106                 ]
    107             },
    108             {
    109                 "mac": "0A:01:33:33:66:17",
    110                 "model": "[00000336] VmWare WorkStation Host-Only Ethernet Adapter",
    111                 "name": 24,
    112                 "ip_address": "192.168.56.17",
    113                 "net_mask": [
    114                     "255.255.255.0",
    115                     "64"
    116                 ]
    117             },
    118             {
    119                 "mac": "14:CF:22:FF:66:17",
    120                 "model": "Intel Adapter",
    121                 "name": 13,
    122                 "ip_address": "192.1.1.17",
    123                 "net_mask": ""
    124             },
    125 
    126 
    127         ]
    128     }
    129 
    130     linux_data = {
    131         "assets_type": "server",
    132         "manufacturer": "IBM.",
    133         "sn": "F3LN112",
    134         "model": "K1 Power S930",
    135         "uuid": "3334523-1266-4d12-804e-c6c2wwe66",
    136         "wake_up_type": "Power Switch",
    137         "os_distribution": "Ubuntu",
    138         "os_release": "Ubuntu 16.04.4 LTS",
    139         "os_type": "Linux",
    140         "cpu_count": "16",
    141         "cpu_core_count": "64",
    142         "cpu_model": "POWER 9E",
    143         "ram": [
    144             {
    145                 "slot": "RAM slot #0",
    146                 "volume": 256,
    147                 "model": "Physical Memory",
    148                 "brand": "IBM",
    149                 "sn": "616612"
    150             }
    151         ],
    152         "size": 63.53899332970703,
    153         "nic": [],
    154         "physical_disk_driver": [
    155             {
    156                 "model": "ST2245LM035-1RK016",
    157                 "volume": "2048",
    158                     "sn": "WL23W26",
    159                 "brand": "SanSung",
    160                 "interface_type": "SATA"
    161             }
    162         ]
    163     }
    164 
    165     update_test(linux_data)
    166     update_test(windows_data)
    assets_test.py

     #D 验证功能模块

      现在我们来测试以上功能是否能达到我们预期效果,主要步骤分以下几方面:

      1、由于更改过models.py文件,第一步先运行Python  manage.py makemigrations以及python manage.py migrate

    2、运行assets_test.py

      从上图我们可以看出测试数据成功识别到setting中的服务端地址,并将数据成功发送至服务端,同时还记录的测试日志。

    3、在admin后台查看待审批区域是否有我们刚提交的资产:

    4、通过复选框选中两台待上线资产并进行审批通过,观察是否能顺利审核通过:

      接下来点击执行按钮

      在资产总表中查看是否能看见刚审核通过的资产:

    5、修改assets_test.py中内容,我们将SN不做修改,其他信息做部分调整(windows服务器内存调整为128G/槽位;linux服务器包括SN都做部分修改),查看更新功能是否正常:

      首先查看IMU的工程debug信息:  

      接着查看windows服务器内存是否被更新,目前还没有详细资产展示,所以只能去内存资产管理中查看:

      由于linux我们修改了SN号,所以被认为是新资产,故直接进入待审批区域,这里我们直接审批就不截图了。最后看看总资产:2台linux服务器,1台windows服务器

    6、查看日志是否正常记录(测试日志在工程目录中,系统日志在数据库的Log表中)

      其中有几条日志显示审批失败,后来找见原因是我的测试数据中内存槽位号重复了导致的。资产的新增、审批、更新就到这吧,下一章节开始弄前端,将整个资产进行一个统一的展示。

  • 相关阅读:
    OpenGL简介及编程入门
    大数阶乘 我的ACM的第一步!
    解释Windows7“上帝模式”的原理
    斯特林[striling]公式(求阶乘(n!)的位数)
    VC中借助内嵌资源实现Flash动画播放
    VC MFC 精品文章收集!
    这应该是UFC有史以来最快的KO记录了
    深以为然
    PS3欧洲延期!全球同步发售幻想破灭
    Windows Vista RC1 NVIDIA drivers include OpenGL ICD
  • 原文地址:https://www.cnblogs.com/4geek/p/12125474.html
Copyright © 2011-2022 走看看