CMDB开发之服务器数据采集

服务器数据采集与接收

采集数据可以有n种方法。但是我们并不需要太高深的知识,python基础足矣。现在完成的是一个Python获取linux服务器资源的脚本。

#!/usr/bin/env python3
#coding:utf-8
import os
import uuid
import socket

#获取主机名
hostname = socket.gethostname()
#获取ip地址,不确定获取那个
ip = socket.gethostbyname(hostname)
#mac地址
mac = uuid.UUID(int = uuid.getnode()).hex[-12:].upper()
mac = ":".join([mac[i:i+2] for i in range(0,11,2)])
#cpu型号
with os.popen("cat /proc/cpuinfo") as f:
    for line in f.readlines():
        key,value = line.split(":")
        key = key.strip()
        value = value.strip()
        if key == "model name":
           cpuData = value
           break
#内存大小
with os.popen("cat /proc/meminfo") as f:
    for line in f.readlines():
        key,value = line.split(":")
        key = key.strip()
        value = value.strip()
        if key == "MemTotal":
           MemTotal = value
           break

print(MemTotal)

效果如下:

but,上面的方法没有将数据进行统筹,所以我们需要将数据进行一次整合

#!/usr/bin/env python3
#coding:utf-8
import os
import uuid
import socket
result = {}

#获取主机名
hostname = socket.gethostname()
result["hostname"] = hostname

#获取ip地址,不确定获取那个
ip = socket.gethostbyname(hostname)
result["ip"] = ip

#mac地址
mac = uuid.UUID(int = uuid.getnode()).hex[-12:].upper()
mac = ":".join([mac[i:i+2] for i in range(0,11,2)])
result["mac"] = mac

#cpu型号
with os.popen("cat /proc/cpuinfo") as f:
    for line in f.readlines():
        key,value = line.split(":")
        key = key.strip()
        value = value.strip()
        if key == "model name":
           cpuData = value
           break
result["cpu"] = cpuData
#内存大小
with os.popen("cat /proc/meminfo") as f:
    for line in f.readlines():
        key,value = line.split(":")
        key = key.strip()
        value = value.strip()
        if key == "MemTotal":
           MemTotal = value
           break
result["memtotal"] = MemTotal

print(result)

效果如下:

但是我们又会发现这样做还是不够好,我们应该将有参数的放到函数或类当中,那么我们试试用类和装饰器写一写,进行简单的结构编写。

#!/usr/bin/env python3
#coding:utf-8
import os
import uuid
import socket

class GetData(object):
    def __init__(self):
        self.result = {} #实例化最终的结果
def getData_byFile(self,command,keyword):
	  “”“
统一的获取文件当中参数的方法
”“”
        result = ""
        with os.popen(command) as f:
        for line in f.readlines():
                key,value = line.split(":")
                key = key.strip()
                value = value.strip()
                if key == keyword:
                    result = value
                    break
         return result 

    def get_cpu(self):
        command = "cat /proc/cpuinfo"
        keyword = "model name"
        cpuData = self.getData_byFile(command,keyword)
        return cpuData
    def get_mem(self):
        command = "cat /proc/meminfo"
        keyword = "MemTotal"
        meminfo = self.getData_byFile(command,keyword)
        return meminfo
    def get_hostname(self):
        hostname = socket.gethostname()
        return hostname
    def get_ip(self):
        ip = socket.gethostbyname(hostname)
        return ip
    def get_mac(self):
        mac = uuid.UUID(int = uuid.getnode()).hex[-12:].upper()
        mac = ":".join([mac[i:i+2] for i in range(0,11,2)])
        result["mac"] = mac
        return mac

在上面的基础上我们再进行优化一次

#!/usr/bin/env python3
#coding:utf-8
import os
import uuid
import socket

class GetData(object):
    def __init__(self):
        self.result = {}
    def getData_byFile(self,command,keyword):
        result = ""
        with os.popen(command) as f:
            for line in f.readlines():
                key,value = line.split(":")
                key = key.strip()
                value = value.strip()
                if key == keyword:
                    result = value
                    break
        return result

    def get_cpu(self):
        command = "cat /proc/cpuinfo"
        keyword = "model name"
        cpuData = self.getData_byFile(command,keyword)
        return cpuData
    def get_mem(self):
        command = "cat /proc/meminfo"
        keyword = "MemTotal"
        meminfo = self.getData_byFile(command,keyword)

    def get_cpu(self):
        command = "cat /proc/cpuinfo"
        keyword = "model name"
        cpuData = self.getData_byFile(command,keyword)
        return cpuData
    def get_mem(self):
        command = "cat /proc/meminfo"
        keyword = "MemTotal"
        meminfo = self.getData_byFile(command,keyword)
        return meminfo
    def get_hostname(self):
        self.hostname = socket.gethostname()
        return self.hostname
    def get_ip(self):
        ip = socket.gethostbyname(self.hostname)
        return ip
    def get_mac(self):
        mac = uuid.UUID(int = uuid.getnode()).hex[-12:].upper()
        mac = ":".join([mac[i:i+2] for i in range(0,11,2)])
        return mac
    def getAll(self):
        self.result = {
           "mac": self.get_mac(),
           "hostname": self.get_hostname(),
           "ip": self.get_ip(),
           "cpuData": self.get_cpu(),
           "memtotal": self.get_mem()
        }

if __name__ == "__main__":
    data = GetData()
    data.getAll()
print(data.result)

but,在生成键值对这里我们不必单独进行生成,我们可以写一个装饰器,将其放入我们的字典中。

#!/usr/bin/env python3
#coding:utf-8
import os
import uuid
import socket

class GetData(object):
    def __init__(self):
        self.result = {}

    def getResult(fun):
        def inner(self):
            key,value = fun(self)
            self.result[key] = value #这里需要键值对
        return inner

    def getData_byFile(self,command,keyword):
        result = ""
        with os.popen(command) as f:
            for line in f.readlines():
                key,value = line.split(":")
                key = key.strip()
                value = value.strip()
                if key == keyword:
                    result = value
                    break
        return result

    @getResult
    def get_cpu(self):
        command = "cat /proc/cpuinfo"
        keyword = "model name"
        cpuData = self.getData_byFile(command,keyword)
        return "cpu",cpuData
    @getResult
    def get_mem(self):
        command = "cat /proc/meminfo"
        keyword = "MemTotal"
        meminfo = self.getData_byFile(command,keyword)
        return "meminfo",meminfo
    @getResult
    def get_hostname(self):
        self.hostname = socket.gethostname()
        return "hostname",self.hostname
    @getResult
    def get_ip(self):
        ip = socket.gethostbyname(self.hostname)
        return "ip",ip
    @getResult
    def get_mac(self):
        mac = uuid.UUID(int = uuid.getnode()).hex[-12:].upper()
        mac = ":".join([mac[i:i+2] for i in range(0,11,2)])
        return "mac",mac
    def getAll(self):
        self.result = {
           "mac": self.get_mac(),
           "hostname": self.get_hostname(),
           "ip": self.get_ip(),
           "cpuData": self.get_cpu(),
           "memtotal": self.get_mem()
        }

if __name__ == "__main__":
    data = GetData()
    data.get_cpu()
    data.get_mem()
    data.get_hostname()
    print(data.result)

到这里一个比较完整的脚本就完成了,当然也还是有可以优化的地方,值得注意的是我们在查询ip的时候是调用了我们的主机名来进行查询的。所以说一定要有先后顺序进行查询,如果先查询ip就会报错。

查看装饰的步骤

  1. get_houstname作为参数,传入getResult
  2. key,value = fun(self)实例化了get_houstname          key = hostname value = self.hostname
  3. 不论装饰器装饰了啥,返回的都是inner函数
  4.  self.method == method(self)

服务器数据采集的发送

我们开始设置我们的接口

\ALLENCMDB\Server\views.py

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from django.views.generic import View


class Api(View):
    def post(self,request):
        if request.POST:
            postData = request.POST
            return HttpResponse(postData)

    def get(self,request):
        if request.GET:
            getData = request.GET["key"]
            return HttpResponse(getData)

设置好url,通过浏览器访问没有问题

那么我们通过脚本来测试一下,首先保证你的Linux服务器能够与你的服务器能够互相ping通

WebServer:192.168.1.32

LinuxServer:192.168.1.53

然后在linuxserver上编写脚本,注意,如果Django服务器想被其他人访问自己,那么需要监听所有ip

然后用脚本请求,我们进行请求的代码

#!/usr/bin/env python3
#coding:utf-8

import requests

url = "http://192.168.1.32:8000/Api/"
data = {
   "type": "user_login",
    "data": {
       "username": "root",
       "password": "123456"
    },
    "token": ""
}

response = requests.post(url,data = data)
with open("1.html","w") as f:
    f.write(response.content)
print(response)

在接口请求的过程当中,如果发现请求的数据发送不成功,请将嵌套部分进行json封装
请求的代码

#!/usr/bin/env python3
#coding:utf-8

import json
import requests

url = "http://192.168.1.32:8000/Api/"
#对发送数据嵌套部分进行json封装
login_data = json.dumps({
        "username": "root",
        "password": "123456"
})

data = {
   "type": "user_login",
   "data": login_data,
    "token": ""
}


response = requests.post(url,data = data)
result = response.json()
print(result)

\ALLENCMDB\Server\views.py

import json
from django.views.generic import View
from django.http import JsonResponse,HttpResponse

class Api(View):
    def __init__(self,**kwargs):
        View.__init__(self,**kwargs)
        self.result = {
            "status": "",
            "data": {}
        }

    def post(self,request):
        """
        处理post请求
        """
        if request.POST:
            postData = request.POST
            post_type = postData.get("type") #获取类型
            if post_type == "user_login":
                login_data = json.loads(postData.get("data")) #获取登录数据,这里获取的是提交的json字符串
                username = login_data.get("username") #获取用户名
                self.result["status"] = "success"
                self.result["data"]["token"] = "211314"
            else:
                self.result["status"] = "error"
                self.result["data"]["error"] = "no method named %s"%postData
            return JsonResponse(self.result)


    def get(self, request):
        """
        处理get请求
        """
        if request.GET:
            getData = request.GET.get("key")
            return HttpResponse(getData)

我们利用上述脚本请求的时候会报错, 这里我们一定要注意类视图的一些特性。

然后将我们的视图代码修改

from django.views.generic import View
from django.http import JsonResponse,HttpResponse

class Api(View):
    	"""
       """
    def __init__(self,**kwargs):
        View.__init__(self,**kwargs)
        self.result = {
            "status": "",
            "data": {}
        }

    def post(self,request):
        """
        处理post请求
        """
        if request.POST:
            postData = request.POST.get("type")
            if postData == "user_login":
                self.result["status"] = "success"
                self.result["data"]["token"] = "211314"
            else:
                self.result["status"] = "error"
                self.result["data"]["error"] = "no method named %s"%postData
            return JsonResponse(self.result)


    def get(self, request):
        """
        处理get请求
        """
        if request.GET:
            getData = request.GET.get("key")
            return HttpResponse(getData)

完善我们的token机制

上面我们已经疏通了我们接口的基本样式,那么我们现在来完成完整的接口请求流程。

1. 确定我们的登录用户

进行登录逻辑的编写,首先完善登录的基本逻辑

import json

from django.views.generic import View
from django.http import JsonResponse,HttpResponse

from Service.models import LoginUser,Service,APIToken


class API(View):
    def __init__(self,**kwargs):
        View.__init__(self,**kwargs)
        self.result = {
            "status": "",
            "data": {}
        }

    def post(self,request):
        """
        处理post请求
        """
        if request.POST:
            postData = request.POST
            post_type = postData.get("type") #获取类型
            login_data = json.loads(postData.get("data"))  # 获取登录数据,这里获取的是提交的json字符串
            if post_type == "user_login":
                username = login_data.get("username") #获取接口提交的用户名
                password = login_data.get("password") #获取接口提交的密码
                try:
                    loginUser = LoginUser.objects.get(username = username)
                except:
                    self.result["status"] = "error"
                    self.result["data"]["error"] = "no user named %s"%username
                else:
                    db_password = loginUser.password
                    if password == db_password:
                        self.result["status"] = "success"
                        self.result["data"]["token"] = "201314"
                    else:
                        self.result["status"] = "success"
                        self.result["data"]["token"] = "%s's password is wrong"%username
            else:
                self.result["status"] = "error"
                self.result["data"]["error"] = "no method named %s"%postData
            return JsonResponse(self.result)


    def get(self, request):
        """
        处理get请求
        """
        if request.GET:
            getData = request.GET.get("key")
            return HttpResponse(getData)

在我们真正的代码实现过程当中,我们登录成功需要干两件事情

  1. 生成token

我们采用 用户名+当前时间戳进行hash MD5加密的方法生成token

  1. 保存token到数据库,然后下发token
class Api(View):
    def __init__(self,**kwargs):
        pass
    def post(self,request):
        pass

    def get(self,request):
        pass

    def makeToken(self, username):
        """
         我们采用 用户名+当前时间戳进行hash MD5加密的方法生成token:
        """
        time_stamp = str(time.time())  # 获取了当前时间的时间戳,并转化为字符串
        value = username + time_stamp  # 进行用户名和字符串类型的时间戳的拼接
        # md5加密,并返回
        md5 = hashlib.md5()
        md5.update(value.encode())
        token = md5.hexdigest()
        return token

我们来看一下token的使用,我们借助服务器信息注册来使用一下token

Token使用,我们实际上使用的是一种校验的方法

class Api(View):
    def __init__(self,**kwargs):
        pass
    def post(self,request):
        pass

    def get(self,request):
        pass

    def makeToken(self, username):
        pass
    def tokenValid(self,token):
        """
        校验token
        """
        try:
            db_token = APIToken.objects.get(value = token)
        except:
            return "token error"
        else:
            # 从数据库取出的时间转换为时间戳
            db_time_tuple = db_token.time.timetuple() #转换时间的格式为元组格式
            db_time_stamp = time.mktime(db_time_tuple) #讲元组格式的时间转换为时间戳
            # 当前的时间转换为时间戳
            now_time_tuple = datetime.datetime.now().timetuple()  # 转换时间的格式为元组格式
            now_time_stamp = time.mktime(now_time_tuple)  # 讲元组格式的时间转换为时间戳

            if 0 < now_time_stamp - db_time_stamp < 3600: #秒
                return "ok"
            else:
                db_token.delete()
                return "time out"

我们来编写服务器注册的案例

import time
import json
import hashlib
import datetime

from django.views.generic import View
from django.http import JsonResponse,HttpResponse

from Service.models import LoginUser,Service,APIToken


class API(View):
    def __init__(self,**kwargs):
        View.__init__(self,**kwargs)
        self.result = {
            "status": "",
            "data": {}
        }

    def post(self,request):
        """
        处理post请求
        """
        if request.POST:
            post_type = request.POST.get("type") #获取类型
            postData = json.loads(request.POST.get("data"))  # 获取登录数据,这里获取的是提交的json字符串
            if post_type == "user_login":
                username = postData.get("username") #获取接口提交的用户名
                password = postData.get("password") #获取接口提交的密码
                try:
                    loginUser = LoginUser.objects.get(username = username)
                except:
                    self.result["status"] = "error"
                    self.result["data"]["error"] = "no user named %s"%username
                else:
                    db_password = loginUser.password
                    if password == db_password:
                        token = self.makeToken(username) #调用方法生成token
                        #将token存入数据库
                        db_token = APIToken() #实例化api token数据模型,传入值
                        db_token.value = token
                        db_token.time = datetime.datetime.now()
                        db_token.user_id = loginUser.id #这里调用上面登录时候的用户id进行token对应
                        db_token.save()

                        self.result["status"] = "success"
                        self.result["data"]["token"] = token
                    else:
                        self.result["status"] = "success"
                        self.result["data"]["token"] = "%s's password is wrong"%username
            elif post_type == "addServer":
                if postData:
                    postToken = request.POST.get("token")
                    if postToken and self.tokenValid(postToken) == "ok":
                        #获取数据
                        ip = postData.get("ip")
                        mac = postData.get("mac")
                        cpu = postData.get("cpu")
                        memory = postData.get("memory")
                        hostname = postData.get("hostname")
                        #保存数据
                        server = Service()
                        server.ip = ip
                        server.mac = mac
                        server.cpu = cpu
                        server.memory = memory
                        server.hostname = hostname
                        server.isalive = "false"
                        server.save()
                        self.result["status"] = "success"
                        self.result["data"]["result"] = "save success"
                    else:
                        self.result["status"] = "error"
                        self.result["data"]["error"] = "token error"
                else:
                    self.result["status"] = "error"
                    self.result["data"]["error"] = "data error"

            else:
                self.result["status"] = "error"
                self.result["data"]["error"] = "no method named %s"%postData
            return JsonResponse(self.result)


    def get(self, request):
        """
        处理get请求
        """
        if request.GET:
            getData = request.GET.get("key")
            return HttpResponse(getData)

    def makeToken(self,username):
        """
         我们采用 用户名+当前时间戳进行hash MD5加密的方法生成token:
        """
        time_stamp = str(time.time()) #获取了当前时间的时间戳,并转化为字符串
        value = username + time_stamp #进行用户名和字符串类型的时间戳的拼接
        #md5加密,并返回
        md5 = hashlib.md5()
        md5.update(value.encode())
        token = md5.hexdigest()
        return token
    def tokenValid(self,token):
        """
        校验token
        """
        try:
            db_token = APIToken.objects.get(value = token)
        except:
            return "token error"
        else:
            # 从数据库取出的时间转换为时间戳
            db_time_tuple = db_token.time.timetuple() #转换时间的格式为元组格式
            db_time_stamp = time.mktime(db_time_tuple) #讲元组格式的时间转换为时间戳
            # 当前的时间转换为时间戳
            now_time_tuple = datetime.datetime.now().timetuple()  # 转换时间的格式为元组格式
            now_time_stamp = time.mktime(now_time_tuple)  # 讲元组格式的时间转换为时间戳

            if 0 < now_time_stamp - db_time_stamp < 3600: #秒
                return "ok"
            else:
                db_token.delete()
                return "time out"

请求的脚本:

#!/usr/bin/env python3
#coding:utf-8
import json
import requests

url = "http://192.168.1.32:8000/Api/"
#对发送数据嵌套部分进行json封装
server_data = json.dumps({
        "ip": "192.169.1.53",
        "mac": "00:01:6C:06:A6:29",
        "cpu": "Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz",
        "memory": "180000KB",
        "hostname": "saltmaster",
})

data = {
   "type": "addServer",
   "data":  server_data,
   "token": "a97ff61fddb10e52064563952e511bd7"#这里的token是根据前面的脚本请求得到的token
}

response = requests.post(url,data = data)
result = response.json()
print(result)

实际工作当中,我们请求的代码会写出如下

#!/usr/bin/env python3
#coding:utf-8

import json
import requests

class RequestApi:
    def __init__(self,username,password,url):
        self.url = url #传入地址
        self.request_data = json.dumps({
            "username": username,
            "password": password
        }) #定义了登录的数据
        self.requestData = {
            "type": "user_login",
            "data": self.request_data,
            "token": ""
        } #定义发送的数据
        self.token = self.request("post").get("data").get("token")

    def request(self,method):
        """
        method是我们用get还是post请求
        """
        #发起请求
        response = requests.request(method,url = self.url,data = self.requestData)
        result = response.json()
        return result
    def addServer(self):
        server_data = json.dumps({
        "ip": "192.169.1.5.",
        "mac": "00:01:6C:06:A6:29",
        "cpu": "Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz",
        "memory": "180000KB",
        "hostname": "saltmaster",
        })
        self.reqeustData["data"] = server_data
        self.requestData["type"] = "addServer"
        self.requestData["token"] = self.token
        self.request("post")



if __name__ == "__main__":
    url = "http://192.168.1.32:8000/Api/"
    username = "allen"
    password = "123"
    req = RequestApi(username,password,url)
    print(req.token)

效果如下:

当然我们也可以进行批量插入服务器信息,方便后面的Vue分页使用数据:

#!/usr/bin/env python3
#coding:utf-8

import json
import requests

url = "http://192.168.1.32:8000/Api/"
for i in range(1,101):
    server_data = json.dumps({
        "ip":"192.168.1.%s"%i,
        "mac":"00:0C:29:8B:9A:85",
        "cpu":"Intel(R) Core(TM) i7-7500 CPU @ 3.40GHz",
        "memory":"521314KB",
        "disk":"8888MB"
     })
    data = {
        "type":"addServer",
        "data":server_data,
        "token":"95d1244538e89f5bf91a4e6dd9b6918d"
    }
    response = requests.post(url,data = data)
    result = response.json()
    print(result)

效果如下:

上面的信息中在存入数据库时打错了字段名称,所以disk字段没有信息,修改后正常存入信息 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值