服务器一对多与多对多处理
Posted 单爆手
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务器一对多与多对多处理相关的知识,希望对你有一定的参考价值。
如上图中这是我运维平台服务器接口返回的单条数据,但是这个数据里少了网卡设备和多Ip字段,那我的网卡设备有几种展现方式,怎么展现?--这里我想要以如下的形式展现:
[ { "id": 1, "ip": "192.168.1.9", "hostname": "yz-ms-web-09", "cpu": "Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz 1", "mem": "2G", "disk": "100G", "os": "centos 7", "sn": "B49479B2-D774-4B09-B7B9-F29384350C01", "rmt_card_ip": "", "cabinet_position": null, "uuid": "B49479B2-D774-4B09-B7B9-F29384350C01", "last_check": "2020-06-30T01:39:29.826163Z", "remark": null, "manufacturer": 1, "model_name": 1, "idc": null, "cabinet": null, "device": [ { "name": "eth0" "mac": "", "ips": [ {"ip":"192.168.1.1", "netmask":"255.255.255.0"} {"ip":"192.168.1.2", "netmask":"255.255.255.0"} {} ], "name": "eth1" "mac": "", "ips": [ {"ip":"192.168.1.1", "netmask":"255.255.255.0"} {"ip":"192.168.1.2", "netmask":"255.255.255.0"} {} ] }, {} ], } ]
网卡跟服务器是一对多的关系(一对多和多对多的处理方式是一样的).
一.一对多数据处理:
1.apps/servers/serilaizers.py
from rest_framework import serializers from .models import Manufacturer, ProductModel from rest_framework import serializers from .models import Server,NetworkDevice,IP class ServerAutoReportSerializer(serializers.Serializer): """ 服务器同步序列化类 """ ip = serializers.IPAddressField(required=True) hostname = serializers.CharField(required=True, max_length=20) cpu = serializers.CharField(required=True, max_length=50) mem = serializers.CharField(required=True, max_length=20) disk = serializers.CharField(required=True, max_length=200) os = serializers.CharField(required=True, max_length=50) sn = serializers.CharField(required=True, max_length=50) manufacturer= serializers.CharField(required=True) model_name = serializers.CharField(required=True) uuid = serializers.CharField(required=True, max_length=50) network = serializers.JSONField(required=True) def validate_manufacturer(self, value): try: return Manufacturer.objects.get(vendor_name__exact=value) except Manufacturer.DoesNotExist: return self.create_manufacturer(value) def validate(self, attrs): manufacturer_obj = attrs["manufacturer"] try: attrs["model_name"] = manufacturer_obj.productmodel_set.get(model_name__exact=attrs["model_name"]) except ProductModel.DoesNotExist: attrs["model_name"] = self.create_product_model(manufacturer_obj, attrs["model_name"]) return attrs def create_server(self, validated_data): network = validated_data.pop("network") server_obj = Server.objects.create(**validated_data) self.check_server_network_device(server_obj, network) return server_obj def create(self, validated_data): uuid = validated_data["uuid"].lower() sn = validated_data["sn"].lower() try: if sn == uuid or sn == "" or sn.startswith("vmware"): server_obj = Server.objects.get(uuid__icontains=uuid) else: server_obj = Server.objects.get(sn__icontains=sn) except Server.DoesNotExist: return self.create_server(validated_data) else: return self.update_server(server_obj, validated_data) def update_server(self, instance, validated_data): instance.hostname = validated_data.get("hostname", instance.hostname) instance.cpu = validated_data.get("cpu", instance.cpu) instance.ip = validated_data.get("ip", instance.ip) instance.mem = validated_data.get("mem", instance.mem) instance.disk = validated_data.get("disk", instance.disk) instance.os = validated_data.get("os", instance.os) instance.save() self.check_server_network_device(instance, validated_data["network"]) return instance def check_server_network_device(self,server_obj, network): """ 检查批定服务器有没有这些网卡设备,并作关联 """ network_device_queryset = server_obj.networkdevice_set.all() current_network_device_queryset = [] for device in network: try: network_device_obj = network_device_queryset.get(name__exact=device["name"]) except NetworkDevice.DoesNotExist: network_device_obj = self.create_network_device(server_obj, device) self.check_ip(network_device_obj, device["ips"]) current_network_device_queryset.append(network_device_obj) for network_device_obj in list(set(network_device_queryset) - set(current_network_device_queryset)): network_device_obj.delete() def check_ip(self, network_device_obj, ifnets): ip_queryset = network_device_obj.ip_set.all() current_ip_queryset = [] for ifnet in ifnets: try: ip_obj = ip_queryset.get(ip_addr__exact=ifnet["ip_addr"]) except IP.DoesNotExist: ip_obj = self.create_ip(network_device_obj, ifnet) current_ip_queryset.append(ip_obj) for ip_obj in list(set(ip_queryset) - set(current_ip_queryset)): ip_obj.delete() def create_ip(self, network_device_obj, ifnet): ifnet["device"] = network_device_obj return IP.objects.create(**ifnet) def create_network_device(self,server_obj, device): device.pop("ips") device["host"] = server_obj network_device_obj = NetworkDevice.objects.create(**device) return network_device_obj def create_manufacturer(self, vendor_name): return Manufacturer.objects.create(vendor_name=vendor_name) def create_product_model(self,manufacturer_obj, model_name): return ProductModel.objects.create(model_name=model_name, vendor=manufacturer_obj) def to_representation(self, instance): ret = { "hostname": instance.hostname, "ip": instance.ip } return ret class ServerSerializer(serializers.ModelSerializer): """ 服务器序列化类 """ def get_network_device(self, serveer_obj): ret = [] network_device = serveer_obj.networkdevice_set.all() for device in network_device: data = { "name": device.name, "mac": device.mac_address, "ips": self.get_ip(device) } ret.append(data) return ret def get_ip(self, network_device_obj): ret = [] for ifnet in network_device_obj.ip_set.all(): data = { "ip": ifnet.ip_addr, "netmask": ifnet.netmask } ret.append(data) return ret def to_representation(self, instance): ret = super(ServerSerializer, self).to_representation(instance) ret["device"] = self.get_network_device(instance) return ret class Meta: model = Server fields = "__all__" class NetworkDeviceSerializer(serializers.ModelSerializer): """ 网卡序列化 """ class Meta: model = NetworkDevice fields = "__all__" class IPSerializer(serializers.ModelSerializer): """ IP序列化 """ class Meta: model = IP fields = "__all__"
最终展示的效果就如下图了
11
22
以上是关于服务器一对多与多对多处理的主要内容,如果未能解决你的问题,请参考以下文章