开发笔记:Python脚本自动远程注册prometheus监控+注册jumpserver资产(tronado主机间通信)

上一期:http://t.csdn.cn/541DY

安装完node_exporter后,需要在prometheus的配置文件中添加该节点才能使之被纳入prometheus的监控范围中。想要自动化该过程,不免需要两台主机之间的通信,不过既然能被监控说明之间的网络应该是相通的。

为了使脚本尽可能的轻量并具有泛用性,不添加额外的库和包,脚本方面采用curl发送get和post的方式进行通信。prometheus服务器上部署一个服务接收参数并处理,这个服务不可避免要装一些组件的,不过装一次就够了。服务采用tronado框架。prometheus的配置文件采用conf.d的方法实现自动更新,具体可以参考这里:http://t.csdn.cn/RW1tw,实际上就是把prometheus.yml中的job换成conf.d中的json文件,例如:

 这样这个job的节点就是读取该json中的内容。

下面上代码:

自动化脚本script.py:

# -*- coding: utf-8 -*-
import os
#与prometheus服务器通信,注册prometheus监控
print((os.popen('curl 192.168.100.181:9123')).read())
print('请选择job:')
job=raw_input()
ip = ((os.popen("ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/'")).read())
print('输入hostname:(按enter使用默认值:jt-'+ip[:-1]+')')
hostname = raw_input()#这是python2的,3的话就input()就好
if hostname =='':
    hostname ='linux-'+ip[:-1]
order="curl 192.168.100.181:9123 -X POST -d '{ \"job\": \"" + job + '\",\"hostname\": \"' + hostname + '\", \"ip\": \"' + ip[:-1] + "\"}' --header 'Content-Type: application/json'"
print((os.popen(order).read()))

服务端脚本scriptService.py:

import tornado.ioloop
import tornado.web
import json
import os
def promeConf(hostname,ip,job):
    path="/opt/monitor/prometheus/prometheus-2.7.1.linux-amd64/conf.d/"#prometheus配置文件路径,根据实际情况修改
    filename=j.joblist[int(job)]+'.json'
    with open(path+filename, mode='r') as f:
        list=json.load(f)
        f.close()
    dict=\
  {
    "targets": [ip+":9100"],
    "labels":
    {
      "hostname": hostname
    }
  }
    with open(path+"hf10g_virtual.json", mode='w') as f:
        list.append(dict)
        f.write(json.dumps(list,indent=1))
class Job():
    joblist=[]#定义一个类供全局使用
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        datalist=''
        job = (os.popen('ls /opt/monitor/prometheus/prometheus-2.7.1.linux-amd64/conf.d/')).read()
        j.joblist = (job.split('\n'))
        while ('' in j.joblist):
            j.joblist.remove('')
        for i in range(len(j.joblist) - 1):
            if (j.joblist[i])[-5:] == '.json':
                j.joblist[i] = j.joblist[i][:-5]
            else:
                j.joblist.remove(j.joblist[i])
                i = i + 1
        for i in range(len(j.joblist) - 1):
            datalist = datalist + str(i) + ':' + j.joblist[i] + '\n'
        datalist='请选择job:\n'+datalist
        self.write(datalist)
        self.finish()
    def post(self):
        data = json.loads(self.request.body)
        
        hostname=data['hostname']
        ip=data['ip']
        job=data['job']
        promeConf(hostname,ip,job)

application = tornado.web.Application([
    (r"/", MainHandler),
])
if __name__ == "__main__":
    j=Job()#实例化
    application.listen(9123)#自设端口
    tornado.ioloop.IOLoop.instance().start()

大致流程:

 下面逐步解析这套程序:

1.script.py:get请求job列表

print((os.popen('curl 192.168.100.181:9123')).read())

在linux端用curl方法去get prometheus服务器对应服务接口,没什么好说的。

2.scriptService.py:接收get请求、获取job列表、处理数据、返回信息

ls一下文件夹,把str切成列表,把不是.json的、空的都去掉,逻辑上仔细看应该就能明白,但是一般来讲拿去就能用,毕竟形式都固定的。然后加个序号排一下版再发回去,同时列表存起来供下一步使用。

    def get(self):
        datalist=''
        job = (os.popen('ls /opt/monitor/prometheus/prometheus-2.7.1.linux-amd64/conf.d/')).read()
        j.joblist = (job.split('\n'))
        while ('' in j.joblist):
            j.joblist.remove('')
        for i in range(len(j.joblist) - 1):
            if (j.joblist[i])[-5:] == '.json':
                j.joblist[i] = j.joblist[i][:-5]
            else:
                j.joblist.remove(j.joblist[i])
                i = i + 1
        for i in range(len(j.joblist) - 1):
            datalist = datalist + str(i) + ':' + j.joblist[i] + '\n'
        datalist='请选择job:\n'+datalist
        self.write(datalist)
        self.finish()

3.script.py:键入job编号,获取本机ip,键入或生成hostname

想获取本机网络上的ip就是ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/'这条命令,根据实际情况使用。raw_input是python2的方法,3的话就input(),主机名输入为空的话就默认为linux-ip。查到的ip最后一位是‘\n’,所以截掉最后一位。

job=raw_input()
ip = ((os.popen("ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/'")).read())
print('输入hostname:(按enter使用默认值:kvm-'+ip[:-1]+')')
hostname = raw_input()
if hostname =='':
    hostname ='linux-'+ip[:-1]

这个是适用于单网卡的方法多网卡不一定适用,下面给出另一种方法:

ip = ((os.popen("ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d 'addr:'")).read())#ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk "{print $2}'|tr -d "addr:"
    ip = ip.split('\n')
    if len(ip)>1:
        ip=[s for s in ip if '192' in s]#如果多网卡中想要的ip有特征可以在这里筛选,否则就手动选择吧
        ip=ip[0]

而且这种方法ip后面不带‘\n’,不用切掉最后一位。总之核心都是围绕着shell命令,再根据情况做数据处理。

4.script.py:post发送参数json

还是curl,发送一个json,注明--header 'Content-Type: application/json'。python2中解析json好像内部的引号必须是双引号,可以用\"来区分。

order="curl 192.168.100.181:9123 -X POST -d '{ \"job\": \"" + job + '\",\"hostname\": \"' + hostname + '\", \"ip\": \"' + ip[:-1] + "\"}' --header 'Content-Type: application/json'"
print((os.popen(order).read()))

5.scriptService.py:接收post,解析json

也没啥好说的,拿来就用就行

    def post(self):
        data = json.loads(self.request.body)
        hostname=data['hostname']
        ip=data['ip']
        job=data['job']
        promeConf(hostname,ip,job)

6.scriptService.py:更新配置文件

首先确定自己prometheus的配置conf.d路径,然后按照job的序号在joblist中找到对应job.json,格式就是

[
  {
    "targets": ["10.30.17.13:9100"],
    "labels": {
      "hostname": "kvm1"
    }
  },
  {
    "targets": ["10.30.17.14:9100"],
    "labels": {
      "hostname": "kvm2"
    }
  },
{
    "targets": ["10.30.17.15:9100"],
    "labels": {
      "hostname": "linux01"
    }
  }
]

文件操作是先读,把json转成字典列表,然后append新的字典,再写入json文件。

def promeConf(hostname,ip,job):
    path="/opt/monitor/prometheus/prometheus-2.7.1.linux-amd64/conf.d/"
    filename=j.joblist[int(job)]+'.json'
    with open(path+filename, mode='r') as f:
        list=json.load(f)
        f.close()
    dict=\
  {
    "targets": [ip+":9100"],
    "labels":
    {
      "hostname": hostname
    }
  }#有些node设定的端口不是9100,根据实际情况去改
    with open(path+"hf10g_virtual.json", mode='w') as f:
        list.append(dict)
        f.write(json.dumps(list,indent=1))

注意防火墙开对应端口嗷~

7.注册跳板机资产

这个可以看http://t.csdn.cn/SYRZT,把模块整合进去,反正注册只需要ip和hostname,传参里都有了。admin_user是跳板机中root用户的id,nodes是节点的id,都可以是固定的。

def get_token(jms_url, username, password):
    url = jms_url + '/api/v1/authentication/auth/'
    query_args = {
        "username": username,
        "password": password
    }
    response = requests.post(url, data=query_args)
    return json.loads(response.text)['token']
def create_assest(jms_url, token,ip,hostname):
    url = jms_url + '/api/v1/assets/assets/'
    headers = {
        "Authorization": 'Bearer ' + token,
        'X-JMS-ORG': '',
        'accept': 'application/json',
        'Content-Type': 'application/json'
    }
    data={
  "ip": ip,
  "hostname": hostname,
  "platform": "Linux",
  "is_active": True,
  "admin_user": "53594e64-48c7-4679-bf7c-d54aba747416",
  "nodes": ["d422754d-36fb-4f6f-a0ba-8f41b60c38e2"]
    }
    data_json = json.dumps(data)
    response = requests.post(url,data_json, headers=headers)
    response.json()
    return(response.text)
class MainHandler(tornado.web.RequestHandler):
    def post(self):
        data = json.loads(self.request.body)
        hostname=data['hostname']
        ip=data['ip']
        jms_url = '跳板机地址'
        username = '~'
        password = '~'
        token = get_token(jms_url, username, password)
        #promeConf(hostname,ip)
        self.write(create_assest(jms_url,token,ip,hostname))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值